// Player.h
// Windows standard header file
#include <windows.h>
//time header file
#include <time.h>
// Player Class
class CPlayer
{
// Player Attributes
COORD m_Position;
short m_Lives;
int m_Score;
int m_Leaps;
public:
// Constructor / destructor
CPlayer();
~CPlayer();
// Move Player
void Move(COORD Direction);
void RandomLeap(COORD ArenaSize);
// Maintenance methods
void GetPosition(COORD * Position);
void SetLives(short Lives);
int GetLives(void);
void SetScore(short Score);
short GetScore(void);
void SetLeaps(int Leaps);
int GetLeaps(void);
};
// 02 Player.cpp
// CPlayer complement header file
#include "02 Player.h"
// does nothing
CPlayer::CPlayer(){}
// again does nothing
CPlayer::~CPlayer(){}
// Moves Player
void CPlayer::Move(COORD Direction)
{
m_Position.X += Direction.X;
m_Position.Y += Direction.Y;
}
// Makes Leap to random position
void CPlayer::RandomLeap(COORD ArenaSize)
{
srand(time(NULL));
m_Position.X = (rand() % (ArenaSize.X - 1)) + 1;
m_Position.Y = (rand() % (ArenaSize.Y - 1)) + 1;
}
// Gets player Position
void CPlayer::GetPosition(COORD * Position)
{
memcpy(Position, &m_Position, sizeof (COORD));
}
// Sets Player Lives
void CPlayer:
etLives(short Lives)
{
m_Lives = Lives;
}
// gets Player Lives
int CPlayer::GetLives(void)
{
return m_Lives;
}
// Sets Player score
void CPlayer:
etScore(short Score)
{
m_Score = Score;
}
// Get player score
short CPlayer::GetScore(void)
{
return m_Score;
}
// Sets player available leaps
void CPlayer:
etLeaps(int Leaps)
{
m_Leaps = Leaps;
}
// Gets player available leaps
int CPlayer::GetLeaps(void)
{
return m_Leaps;
}
// 02 Game.h
// Windows standard header file
#include <windows.h>
// Standard input/output header file
#include <stdio.h>
// Conlib header file
#include "ConLib.h"
#include "02 Player.h"
// Game status enumerator
enum GameStatus
{
GameMainMenu = 1,
GameRunning = 2,
GamePaused = 3,
GameWon = 4,
GameLostLife = 5,
GameLost = 6,
GameExit = 7,
GameSplashScreen = 8
};
// Game difficulty enumerator
enum GameDifficulty
{
GameEasy = 1,
GameMedium = 2,
GameDifficult = 3
};
// Game Base class
class CGame
{
private:
// input/output information
ConLib * m_Console;
int m_LastAction;
// Game information
int m_GameStatus;
COORD m_Arena;
CPlayer m_Player;
COORD * m_Monsters;
int m_MonstersNumber;
public:
// Constructors / destructor
CGame();
CGame(ConLib * Console);
~CGame();
// Shows the relative information depending on the status of the game
void ShowSplash(void);
void ShowMenu(void);
void ShowGame(void);
void ShowWon(void);
void ShowLostLife(void);
void ShowLost(void);
void ShowExit(void);
void Show(void);
// Process the turn depending on the game status
void Process (void);
void ProcessSplash(void);
void ProcessMenu(void);
void ProcessGame(void);
void ProcessWon(void);
void ProcessLostLife(void);
void ProcessLost(void);
void ProcessExit(void);
void ProcessTurn(void);
// Set Console information
void SetConsole(ConLib * Console);
// Game Methods
void StartNewGame(int Difficulty);
void EndGame(void);
void CheckCollisions();
int GetAction(void);
int GetStatus(void);
void MoveMonsters(void);
};
// 02 Game.cpp
// CGame complement header file
#include "02 Game.h"
// init members to initial status
CGame::CGame(ConLib * Console)
{
m_Console = Console;
m_Console = NULL;
m_GameStatus = GameSplashScreen;
m_LastAction = 0;
m_Monsters = NULL;
}
// Default destructor
CGame::~CGame()
{
m_Console = NULL;
m_GameStatus = GameSplashScreen;
m_LastAction = 0;
m_Monsters = NULL;
}
// Sets a pointer to the console
/*void CGame:
etConsole(ConLib * Console)
{
m_Console = Console;
}*/
// Returns the game status
int CGame::GetStatus(void)
{
return m_GameStatus;
}
// Shows the splash screen with playing instructions
void CGame:
howSplash(void)
{
m_Console->Clear();
m_Console->OutputString ("\\tWelcome to Monster 1.0 \\n\\n");
m_Console->OutputString ("Playing Monster is very easy. \\n\\n");
m_Console->OutputString ("The objective of the game is to destroy \\n");
m_Console->OutputString ("all the monsters. Two or more monster \\n");
m_Console->OutputString ("are destroyed when they move to the \\n");
m_Console->OutputString ("same cell in the field. You also lose a \\n");
m_Console->OutputString ("life if you move to a cell where a \\n");
m_Console->OutputString ("monster is. You move the player with the \\n");
m_Console->OutputString ("numerical keypad in the eight possible \\n");
m_Console->OutputString ("directions. You can also press Insert \\n");
m_Console->OutputString ("which will make you leap to a random \\n");
m_Console->OutputString ("place in the field.\\n\\n");
m_Console->SetTextColor (ConRed);
m_Console->OutputString ("Note: Make sure Numlock is turned off.\\n\\n");
m_Console->SetTextColor (ConRed | ConGreen | ConBlue);
m_Console->OutputString ("There are three difficulties available:\\n\\n");
m_Console->OutputString (" Easy : Monsters = 10 Arena = 25*15\\n");
m_Console->OutputString (" Lives = 4 Leaps = 3\\n");
m_Console->OutputString (" Medium : Monsters = 20 Arena = 35*18\\n");
m_Console->OutputString (" Lives = 3 Leaps = 2\\n");
m_Console->OutputString (" Hard : Monsters = 30 Arena = 50*23\\n");
m_Console->OutputString (" Lives = 2 Leaps = 1\\n");
}
// shows the main menu
void CGame:
howMenu(void)
{
COORD Position;
m_Console->SetBackgroundColor(0);
m_Console->SetTextColor(ConRed);
m_Console->Clear();
m_Console->SetBackgroundColor (ConRed | ConGreen | ConBlue);
m_Console->OutputString (" \\n");
m_Console->OutputString (" Monster - Version 1.0 \\n");
m_Console->OutputString (" ");
m_Console->SetBackgroundColor (0);
m_Console->SetTextColor (ConRed | ConGreen | ConBlue);
Position.X = 1;
Position.Y = 4;
m_Console->SetPosition(Position);
m_Console->OutputString ("What do you want to do? ");
Position.X = 3;
Position.Y = 6;
m_Console->SetPosition(Position);
m_Console->OutputString("1 - Start new game - Easy");
Position.Y = 7;
m_Console->SetPosition(Position);
m_Console->OutputString("2 - Start new game - Medium");
Position.Y = 8;
m_Console->SetPosition(Position);
m_Console->OutputString("3 - Start new game - Hard");
Position.Y = 10;
m_Console->SetPosition(Position);
m_Console->OutputString("Q - Exit game");
}
// Shows the actual game
void CGame:
howGame(void)
{
COORD Position;
int Monster;
// Draw player Position
m_Console->SetBackgroundColor(0);
m_Console->SetTextColor(ConGreen);
m_Player.GetPosition(&Position);
m_Console->SetPosition(Position);
m_Console->OutputString("P");
// Draw field
int FieldX, FieldY;
m_Console->SetBackgroundColor(ConRed | ConGreen | ConBlue);
m_Console->SetTextColor(ConRed | ConGreen | ConBlue);
for(FieldY = 0; FieldY <= m_Arena.Y; FieldY++)
{
if((FieldY == 0) || (FieldY == m_Arena.Y))
{
for(FieldX = 0; FieldX <= m_Arena.X; FieldX++)
{
Position.X = FieldX;
Position.Y = FieldY;
m_Console->SetPosition(Position);
m_Console->OutputString("#");
}
}
else
{
Position.X = 0;
Position.Y = FieldY;
m_Console->SetPosition(Position);
m_Console->OutputString("#");
Position.X = m_Arena.X;
Position.Y = FieldY;
m_Console->SetPosition(Position);
m_Console->OutputString("#");
}
}
// Draw Monsters
m_Console->SetBackgroundColor(0);
m_Console->SetTextColor(ConRed);
for(Monster = 0; Monster < m_MonstersNumber; Monster++)
{
if(m_Monsters [Monster].X != 0)
{
m_Console->SetPosition(m_Monsters [Monster]);
m_Console->OutputString("M");
}
}
// Show lives and score
char Buffer [100];
sprintf(Buffer, " Lives: %d \\t\\t Score: %d \\t Leaps: %d",
m_Player.GetLives() - 1, m_Player.GetScore(),
m_Player.GetLeaps());
Position.X = 5;
Position.Y = 24;
m_Console->SetPosition(Position);
m_Console->SetTextColor (ConRed | ConGreen);
m_Console->OutputString (Buffer);
}
// Show game won Box
void CGame:
howWon(void)
{
ShowGame();
COORD Position;
Position.X = 20;
Position.Y = 11;
m_Console->SetPosition(Position);
m_Console->SetBackgroundColor(ConGreen);
m_Console->SetTextColor(ConRed);
m_Console->OutputString ("######################################");
Position.Y = 12;
m_Console->SetPosition(Position);
m_Console->OutputString ("# Congratulations! #");
Position.Y = 13;
m_Console->SetPosition(Position);
m_Console->OutputString ("# You Have Killed all the monsters #");
Position.Y = 14;
m_Console->SetPosition(Position);
m_Console->OutputString ("######################################");
}
//Show life lost box
void CGame:
howLostLife(void)
{
ShowGame();
COORD Position;
Position.X = 20;
Position.Y = 11;
m_Console->SetPosition(Position);
m_Console->SetBackgroundColor(ConGreen);
m_Console->SetTextColor (ConRed);
m_Console->OutputString ("######################################");
Position.Y = 12;
m_Console->SetPosition (Position);
m_Console->OutputString ("# You have lost a life #");
Position.Y = 13;
m_Console->SetPosition (Position);
m_Console->OutputString ("######################################");
}
// Shows Game Lost Box
void CGame:
howLost(void)
{
ShowGame ();
COORD Position;
Position.X = 20;
Position.Y = 11;
m_Console->SetPosition (Position);
m_Console->SetBackgroundColor (ConGreen);
m_Console->SetTextColor (ConRed);
m_Console->OutputString ("######################################");
Position.Y = 12;
m_Console->SetPosition (Position);
m_Console->OutputString ("# Tough luck! #");
Position.Y = 13;
m_Console->SetPosition (Position);
m_Console->OutputString ("# You have lost all your lives #");
Position.Y = 14;
m_Console->SetPosition (Position);
m_Console->OutputString ("######################################");
}
//Shows exit text
void CGame:
howExit(void)
{
m_Console->SetBackgroundColor (0);
m_Console->SetTextColor (ConRed | ConGreen | ConBlue);
m_Console->Clear();
m_Console->OutputString ("\\n Monster 1.0 \\n\\n\\n");
m_Console->OutputString (" by: Morten Due Christiansen\\n\\n\\n\\n");
m_Console->OutputString ("Thanks for playing!\\n\\n\\n");
}
// Shows the correct screen depending on the status
void CGame:
how(void)
{
m_Console->SetBackgroundColor (0);
m_Console->SetTextColor (ConRed | ConGreen | ConBlue);
m_Console->Clear ();
switch (m_GameStatus)
{
case GameMainMenu:
ShowMenu();
break;
case GameRunning:
ShowGame ();
break;
case GameWon:
ShowWon ();
break;
case GameLostLife:
ShowLostLife ();
break;
case GameLost:
ShowLost ();
break;
case GameExit:
ShowExit ();
break;
case GameSplashScreen:
ShowSplash ();
break;
default:
break;
}
}
// starts new game
void CGame:
tartNewGame (int Difficulty)
{
int Monster;
COORD Position;
m_GameStatus = GameRunning;
// Set game difficulty
switch (Difficulty)
{
case GameEasy:
m_MonstersNumber = 10;
m_Player.SetLives (4);
m_Player.SetLeaps (3);
m_Arena.X = 25;
m_Arena.Y = 15;
break;
case GameMedium:
m_MonstersNumber = 25;
m_Player.SetLives (3);
m_Player.SetLeaps (2);
m_Arena.X = 35;
m_Arena.Y = 18;
break;
case GameDifficult:
m_MonstersNumber = 35;
m_Player.SetLives (2);
m_Player.SetLeaps (1);
m_Arena.X = 50;
m_Arena.Y = 23;
break;
}
// Create Player
m_Player.RandomLeap (m_Arena);
m_Player.GetPosition (&Position);
m_Player.SetScore (0);
// Create monster
m_Monsters = new COORD [m_MonstersNumber];
srand (time (NULL));
// Calculate random positions for monsters
for (Monster = 0; Monster < m_MonstersNumber; Monster++)
{
// Make Sure position is different than players position
do
{
m_Monsters [Monster].X = (rand () % (m_Arena.X - 1 )) + 1;
m_Monsters [Monster].Y = (rand () % (m_Arena.Y - 1 )) + 1;
}
while ( (m_Monsters [Monster].X == Position.X ) &&
(m_Monsters [Monster].Y == Position.Y ) );
}
}
// Get player action
int CGame:: GetAction (void)
{
// get input form user
m_LastAction = m_Console->GetKey ();
return m_LastAction;
}
// Move monsters according to player position
void CGame::MoveMonsters (void)
{
COORD Distance, Position;
int Monster;
m_Player.GetPosition (&Position);
for (Monster = 0; Monster < m_MonstersNumber; Monster++)
{
// Check if monster is dead
if (m_Monsters [Monster].X !=0)
{
Distance.X = Position.X - m_Monsters [Monster].X;
Distance.Y = Position.Y - m_Monsters [Monster].Y;
// Make sure movement is unitary
if (Distance.X > 0)
{
Distance.X = 1;
}
if (Distance.X < 0)
{
Distance.X = -1;
}
if (Distance.Y > 0)
{
Distance.Y = 1;
}
if (Distance.Y < 0)
{
Distance.Y = -1;
}
// Move Monsters
m_Monsters [Monster].X += Distance.X;
m_Monsters [Monster].Y += Distance.Y;
}
}
}
// Process splash screen
void CGame:
rocessSplash (void)
{
// If user pressed a key just move to main menu
if (m_LastAction)
{
m_GameStatus = GameMainMenu;
}
}
// Gets menu option and eiter quit or start new game
void CGame:
rocessMenu (void)
{
switch (m_LastAction)
{
//Quit game
case VK_ESCAPE:
case 'Q':
case 'q':
m_GameStatus = GameExit;
break;
// Start new game
case '1':
StartNewGame (GameEasy);
m_GameStatus = GameRunning;
break;
case '2':
StartNewGame (GameMedium);
m_GameStatus = GameRunning;
break;
case '3':
StartNewGame (GameDifficult);
m_GameStatus = GameRunning;
break;
default:
break;
}
}
// Moves Player and monsters
void CGame:
rocessGame (void)
{
COORD Movement;
int Monster, MonstersAlive;
Movement.X = 0;
Movement.Y = 0;
// Move player
switch (m_LastAction)
{
case VK_UP:
Movement.Y = -1;
break;
case VK_DOWN:
Movement.Y = 1;
break;
case VK_LEFT:
Movement.X = -1;
break;
case VK_RIGHT:
Movement.X = 1;
break;
case VK_HOME:
Movement.X = -1;
Movement.Y = -1;
break;
case VK_PRIOR:
Movement.X = 1;
Movement.Y = -1;
break;
case VK_END:
Movement.X = -1;
Movement.Y = 1;
break;
case VK_NEXT:
Movement.X = 1;
Movement.Y = 1;
break;
case VK_INSERT:
if (m_Player.GetLeaps () > 0)
{
m_Player.RandomLeap (m_Arena);
m_Player.SetLeaps (m_Player.GetLeaps () - 1);
}
break;
case VK_ESCAPE:
EndGame ();
m_GameStatus = GameMainMenu;
break;
}
/// There was movement
if ( (Movement.X !=0) || (Movement.Y !=0) )
{
COORD PlayerPosition;
m_Player.GetPosition (&PlayerPosition);
// If inside bounds move
if ( (Movement.X + PlayerPosition.X > 0) &&
(Movement.Y + PlayerPosition.Y > 0) &&
(Movement.X + PlayerPosition.X < m_Arena.X) &&
(Movement.Y + PlayerPosition.Y < m_Arena.Y) )
{
m_Player.Move (Movement);
}
// Do Monster AI and check for any collision
MoveMonsters ();
CheckCollisions();
// Check to see if any monster is alive
MonstersAlive = 0;
for (Monster = 0; Monster < m_MonstersNumber; Monster++)
{
// Check if monster is dead
if (m_Monsters [Monster].X !=0)
{
MonstersAlive = 1;
break;
}
}
if (MonstersAlive == 0)
{
m_GameStatus = GameWon;
}
}
}
// Check for collisions between monsters and player
void CGame::CheckCollisions()
{
COORD Position;
int MonsterA, MonsterB;
m_Player.GetPosition (&Position);
for (MonsterA = 0; MonsterA < m_MonstersNumber; MonsterA++)
{
// Check if Monster is dead
if (m_Monsters [MonsterA].X != 0)
{
//check for collision with player
if ( (m_Monsters [MonsterA].X == Position.X) &&
(m_Monsters [MonsterA].Y == Position.Y) )
{
m_Monsters [MonsterA].X = 0;
m_Monsters [MonsterA].Y = 0;
// Set to see if player has any remaining lives
if (m_Player.GetLives () - 1 <= 0)
{
m_GameStatus = GameLost;
}
else
{
m_GameStatus = GameLostLife;
}
return;
}
// Check for collisions with other monsters
for (MonsterB = MonsterA+1; MonsterB < m_MonstersNumber; MonsterB++)
{
// Check if monster is dead
if (m_Monsters [MonsterB].X != 0)
{
// Check for collision with monsters
if ( (m_Monsters [MonsterA].X == m_Monsters [MonsterB].X) &&
(m_Monsters [MonsterA].Y == m_Monsters [MonsterB].Y) )
{
m_Monsters [MonsterA].X = m_Monsters [MonsterB].X = 0;
m_Monsters [MonsterA].Y = m_Monsters [MonsterB].Y = 0;
m_Player.SetScore (m_Player.GetScore () + 15);
}
}
}
}
}
}
// End Game and return to main menu
void CGame:
rocessWon (void)
{
// If user pressed a key just move to main menu
if (m_LastAction)
{
m_GameStatus = GameMainMenu;
}
EndGame ();
}
// Finish the game
void CGame::EndGame (void)
{
if (m_Monsters != NULL)
{
delete [] m_Monsters;
}
m_Monsters = NULL;
}
// Removes a life from the player
void CGame:
rocessLostLife (void)
{
int IsValid = 0;
int Monster;
COORD Position;
// Remove a life from player if ran out of lives end game
m_Player.SetLives (m_Player.GetLives () - 1);
if (m_Player.GetLives () - 1 <= -1)
{
m_GameStatus = GameLost;
}
else
{
m_GameStatus = GameRunning;
IsValid = 0;
// Calculate random position for player
do
{
m_Player.RandomLeap (m_Arena);
m_Player.GetPosition (&Position);
// Make Sure position is different than other monster position
for (Monster = 0; Monster < m_MonstersNumber; Monster++)
{
// check if monster is dead
if (m_Monsters [Monster].X != 0)
{
if ( (m_Monsters [Monster].X != Position.X) &&
(m_Monsters [Monster].Y != Position.Y) )
{
IsValid = 1;
}
else
{
IsValid = 0;
}
}
}
}
while ( IsValid == 0 );
}
}
// end game and return to main menu
void CGame:
rocessLost (void)
{
// if user pressed a key, just move to main menu
if (m_LastAction)
{
m_GameStatus = GameMainMenu;
}
EndGame ();
Show ();
}
// General function that does all task for this turn
void CGame:
rocess (void)
{
/* Since the splash screen must be shown when we begin we must
force it to be shown because theres no action pending */
if (m_GameStatus == GameSplashScreen)
{
Show ();
}
// if user presses a key, act accordingly
if (GetAction())
{
switch (m_GameStatus)
{
case GameMainMenu:
ProcessMenu ();
break;
case GameRunning:
ProcessGame ();
break;
case GameWon:
ProcessWon ();
break;
case GameLostLife:
ProcessLostLife ();
break;
case GameLost:
ProcessLost ();
break;
case GameSplashScreen:
ProcessSplash ();
break;
default:
break;
}
Show ();
}
}
// 02 Main.cpp
// Conlib header file
#include "ConLib.h"
//CGame header file
#include "02 Game.h"
// Start
void main()
{
ConLib Console;
CGame Game(&Console);
// Set Window title
Console.SetTitle ("Monster");
// Start and run game
while (Game.GetStatus () != GameExit)
{
Game.Process();
}
}