7 Replies - 1950 Views - Last Post: 29 July 2013 - 05:57 AM Rate Topic: -----

#1 Toadill  Icon User is offline

  • D.I.C Regular

Reputation: 45
  • View blog
  • Posts: 392
  • Joined: 08-January 12

C++ Console Pacman game

Posted 28 July 2013 - 02:32 PM

I have started building this console clone for a college project but have found a few problems with the AI side of things. The first problem is that the AI does not always move like it should. I am wondering if there is a way to update keyinput without pausing the screen in the console.
For example the call to the function getKeyPress();
seems to hold up my game loop. Any ideas would be appreciated.

Also as of now the AI ghost simply tries to move toward pacman which is not completely ideal when the ghost runs into a wall. Instead I believe path nodes are the key to making the ghost move at least until it gets past a wall. Any ideas on this would be helpful as well.

I am just doing this now as a fun project :bigsmile:

The code below is a fully working version.
Anyone is welcome to use this code to better understand gaming logic.

//Coded by James Leshko

#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <ctime>

using namespace std;
// 35 = walls
//111 = small pills
// 79 = power pills
//074 = pacman right
//076 = pacman left
//118 = pacman up
//94 = pacman down
// 87 = ghost1
// 88 = ghost2
// 89 = ghost3

const int MAXROWS = 32;
const int MAXCOLUMNS = 28;

char keyboardValue = 127;
//Start position is [15][0]
int pacI = 15, pacJ = 0;
//Ghost1 Start postion is [16][14]
int ghostOneI = 16, ghostOneJ = 14;
int node1i = 16, node1j = 5;
int i = 0 , j = 0;
char key = 127;

char levelMatrix[MAXROWS][MAXCOLUMNS] = 
    {
	   { 35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35},
	   { 35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35,  79,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  79,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 000,  35,  35, 000,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 000,  35,  35, 000,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35,  35, 000, 000, 000, 000,  35,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   {074, 000, 000, 000, 000, 000, 111, 000, 000, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000, 000, 000, 111, 000, 000, 000, 000, 000, 000},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35,  35, 000, 000, 000, 000,  35,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35,  35,  35,  35,  35,  35,  35,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35,  79, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111,  79,  35},
	   { 35,  35,  35, 111,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35, 111,  35,  35,  35},
	   { 35,  35,  35, 111,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35, 111,  35,  35,  35},
	   { 35, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111,  35},
	   { 35, 111,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35},
	   { 35, 111,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35},
	   { 35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35},
	   { 35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35}
    };

char ghostCurrent = levelMatrix[ghostOneI][ghostOneJ];
char ghostTrail = ghostCurrent[&ghostOneI][&ghostOneJ];

void getKeyPress();
bool blockValid(int block);
void Ghost();
void GoToXY(int column, int line);
bool ghostMoveUp();
bool ghostMoveDown();
bool ghostMoveLeft();
bool ghostMoveRight();
int findNode();

int pillCount = 244;
int lives = 3;
clock_t startTime = 0, endTime= 0;
bool superPellet = false;
bool pill = false;



int main()
{
    HANDLE  hConsole;
    int k =14;

    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hConsole, k);

    cout << "       ###############			   "<< endl;         
    cout << "      ##################		   "<< endl;       
    cout << "    #######################		   "<< endl;         
    cout << "  ##############   ###########				   "<< endl;
    cout << "##############################				   "<< endl;
    cout << "#######################				   "<< endl;
    cout << "####################			   "<< endl;
    cout << "################			   "<< endl;
    cout << "#############			   "<< endl;
    cout << "###########				   "<< endl;   
    cout << "#########					   "<< endl;
    cout << "############			   "<< "PACMAN" << endl;         
    cout << "##################		   "<< endl;       
    cout << "#######################		   "<< endl;         
    cout << "###########################				   "<< endl;
    cout << "##############################				   "<< endl;
    cout << "    #######################				   "<< endl;
    cout << "      ####################			   "<< endl;
    cout << "        ################			   "<< endl;

    cout << endl;
    system("pause");
    char key = 0;
    system("mode 80, 50");
    int pills = 30;
    bool stopCounting  = false;
    //create the matrix 
    //28 columns
    //32 high

    do
    {
	   //Set Start position
	   GoToXY(0, 0);
	   Ghost();
	   //Column
	   for (i = 0; i <= 31; i++)
	   {
		  //Row
		  for (j = 0; j <= 27; j++)
		  {
			 //Walls
			 if (levelMatrix[i][j] == 35)
			 {
				k = 1;
				SetConsoleTextAttribute(hConsole, k);
			 }
			 //Pacman
			 else if (levelMatrix[i][j] == 074 || levelMatrix[i][j] == 076 || levelMatrix[i][j] == 118 ||levelMatrix[i][j] == 94)
			 {
				k = 14;
				SetConsoleTextAttribute(hConsole, k);
			 }
			 //Blank
			 else if (levelMatrix[i][j] == 000)
			 {
				k = 0;
				SetConsoleTextAttribute(hConsole, k);
			 }
			 //Ghost
			 else if (levelMatrix[i][j] == 87)
			 {
				if (superPellet)
				{
				    k = 7;
				    SetConsoleTextAttribute(hConsole, k);
				}
				else
				{
				    k = 4;
				    SetConsoleTextAttribute(hConsole, k);
				}
			 }
			 //pill
			 else if (levelMatrix[i][j] == 111)
			 {
				k = 15;
				SetConsoleTextAttribute(hConsole, k);
			 }
			 //Power pill
			 else if (levelMatrix[i][j] == 79)
			 {
				k = 14;
				SetConsoleTextAttribute(hConsole, k);
			 }

			 cout << levelMatrix[i][j];
			 if ( j == 27)
				cout << endl;

			 if ( j == 27 && i == 31)
				stopCounting = true;
		  }  
	   }
	   getKeyPress();
	   //Color
	   k = 15;
	   SetConsoleTextAttribute(hConsole, k);
	   
	   cout << "lives remaining " << lives << endl;
	   endTime = clock();
	   int elapsed = int((endTime - startTime) / CLOCKS_PER_SEC);
	   //cout  << elapsed;

	   if (elapsed > 5)
	   {
		  superPellet = false;
		  elapsed = 0;
	   }
    }
    while (lives >= 0 || pillCount != 0);
    
    	system("pause");
	return 0;
};

bool ghostMoveUp()
{
    char ghostNextUp = levelMatrix[ghostOneI - 1][ghostOneJ];
      //Check the next upward block to be sure it is not a wall
    if ( ghostNextUp != 35)
    {
	   //Check the last block to see if there was a pill
	   if ( ghostNextUp == 111 || ghostNextUp == 117 )
	   {
		  //put the pill back
		  levelMatrix[ghostOneI - 1][ghostOneJ] = 87;

		  levelMatrix[ghostOneI][ghostOneJ] = ghostTrail;
		  ghostOneI--;
	   }
	   else
	   {
		  pill = false;
		  levelMatrix[ghostOneI][ghostOneJ] = 000;
		  levelMatrix[ghostOneI - 1][ghostOneJ] = 87;
		  ghostOneI--;
	   }
	   return true;
    }
    else
    {
	   return false;
    }
}

bool ghostMoveDown()
{

    char ghostNextDown = levelMatrix[ghostOneI + 1][ghostOneJ];
    if ( ghostNextDown != 35)
    {
	   if ( ghostNextDown == 111 || ghostNextDown ==117)
	   {
		  levelMatrix[ghostOneI + 1][ghostOneJ] = 87;
		  levelMatrix[ghostOneI][ghostOneJ] = ghostNextDown;
		  ghostOneI++;
	   }
	   else
	   {
		  levelMatrix[ghostOneI][ghostOneJ] = 000;
		  levelMatrix[ghostOneI + 1][ghostOneJ] = 87;
		  ghostOneI++;
	   }
	   return true;
    }
    else
    {
	   return false;
    }
}

bool ghostMoveLeft()
{
    char ghostNextLeft = levelMatrix[ghostOneI][ghostOneJ - 1];
    if ( ghostNextLeft != 35)
	   {
		  if ( ghostNextLeft == 111 || ghostNextLeft ==117)
		  {
			 levelMatrix[ghostOneI][ghostOneJ - 1] = 87;
			 levelMatrix[ghostOneI][ghostOneJ] = ghostNextLeft;
			 ghostOneJ--;
		  }
		  else
		  {
			 levelMatrix[ghostOneI][ghostOneJ] = 000;
			 levelMatrix[ghostOneI][ghostOneJ - 1] = 87;
			 ghostOneJ--;
		  }
		   return true;
	   }
        else
	   {
		  return false;
	   }

}

bool ghostMoveRight()
{
    char ghostNextRight = levelMatrix[ghostOneI][ghostOneJ + 1];
    if ( ghostNextRight != 35)
    {
	  
	   if ( ghostNextRight == 111 || ghostNextRight ==117)
	   {
		  levelMatrix[ghostOneI][ghostOneJ + 1] = 87;
		  levelMatrix[ghostOneI][ghostOneJ] = ghostNextRight;
		  ghostOneJ++;
	   }
	   else
	   {
		  levelMatrix[ghostOneI][ghostOneJ] = 000;
		  levelMatrix[ghostOneI][ghostOneJ + 1] = 87;
		  ghostOneJ++;
	   }
	   return true;
    }
    else
    {
	   return false;
    }

}

void Ghost()
{
    if (superPellet)
    {
	   //Ghost is moving up 
	   if ( pacI > ghostOneI)
	   {
		  //if wall found
		  if (!ghostMoveUp())
		  { 
			 //find node path 
		  }
	   }
    
	   //Ghost is moving down
	   else if (pacI < ghostOneI)
	   {
		  if (!ghostMoveDown())
		  {

		  }
	   }

	   //Ghost is moving left
	    if (pacJ > ghostOneJ)
	   {
		  if (!ghostMoveLeft())
		  {

		  }
	   }

	   //Ghost is moving right
	   else if (pacJ < ghostOneJ)
	   {
		  if (!ghostMoveRight())
		  {

		  }
	   }
    }
    else
    {


	   //Ghost is moving up 
	   if ( pacI < ghostOneI)
	   {

		  //if wall found
		  if (!ghostMoveUp())
		  { 

		  }
	   }
    
	   //Ghost is moving down
	   else if (pacI > ghostOneI)
	   {
		  if (!ghostMoveDown())
		  {

		  }
	   }

	   //Ghost is moving left
	   if (pacJ < ghostOneJ)
	   {
		  if (!ghostMoveLeft())
		  {

		  }
	   }

	   //Ghost is moving right
	   else if (pacJ > ghostOneJ)
	   {
		  if (!ghostMoveRight())
		  {

		  }
	   }
    }

    //you caught the ghost
    if (pacJ == ghostOneJ && pacI == ghostOneI && superPellet)
    {
	   levelMatrix[ghostOneI][ghostOneJ] = 074;
	   ghostOneI = 16;
	   ghostOneJ = 14;
	   levelMatrix[16][14] = 87;
    }
    //Reset the postion of pacman you died
    else if (pacJ == ghostOneJ && pacI == ghostOneI)
    {
	   lives--;
	   levelMatrix[pacI][pacJ] = 000;
	   levelMatrix[ghostOneI][ghostOneJ] = 000;
	   pacI = 15;
	   pacJ = 0;
	   ghostOneI = 16;
	   ghostOneJ = 14;
	   levelMatrix[15][0] = 074;
	   levelMatrix[16][14] = 87;
    }
}

void getKeyPress()
{
	key = _getch();
    char pacTemp = '<';
	//get a special key
	if (key == 0 || key == -32)  
	{
		key = _getch();

		if (key == 72) //up
		{
		   if ( levelMatrix[pacI- 1][pacJ] != 35)
		   {
			 if (levelMatrix[pacI- 1][pacJ] == 79)
			 {
				startTime = clock();
				superPellet = true;
			 }
			 levelMatrix[pacI][pacJ] = 000;
			 levelMatrix[pacI - 1][pacJ] = 118;
			 pacI--;
		   }
		}
		else if (key == 75) //left
		{
		    if ( levelMatrix[pacI][pacJ- 1] != 35)
		    {
			 if (levelMatrix[pacI][pacJ - 1] == 79)
			 {
				startTime = clock();
				superPellet = true;
			 }
			 levelMatrix[pacI][pacJ] = 000;
			 levelMatrix[pacI][pacJ - 1] = 076;
			 pacJ--;
		    }
		}
		else if (key == 77) //right
		{
		    if ( levelMatrix[pacI][pacJ+ 1] != 35)
		    {
			 if (levelMatrix[pacI][pacJ + 1] == 79)
			 {
				startTime = clock();
				superPellet = true;
			 }
			 levelMatrix[pacI][pacJ] = 000;
			 levelMatrix[pacI][pacJ + 1] = 074;
			 pacJ++;
		    }
		}
		else if (key == 80) //down
		{
		   if ( levelMatrix[pacI + 1][pacJ] != 35)
		   {
			 if (levelMatrix[pacI + 1][pacJ] == 79)
			 {
				startTime = clock();
				superPellet = true;
			 }
			 levelMatrix[pacI][pacJ] = 000;
			 levelMatrix[pacI + 1][pacJ] = 94;
			 pacI++;
		   }
	   }
    }
}

void GoToXY(int column, int line)
{
    // Create a COORD structure and fill in its members.
    // This specifies the new position of the cursor that we will set.
    COORD coord;
    coord.X = column;
    coord.Y = line;

    // Obtain a handle to the console screen buffer.
    // (You're just using the standard console, so you can use STD_OUTPUT_HANDLE
    // in conjunction with the GetStdHandle() to retrieve the handle.)
    // Note that because it is a standard handle, we don't need to close it.
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    // Finally, call the SetConsoleCursorPosition function.
    if (!SetConsoleCursorPosition(hConsole, coord))
    {
        // Uh-oh! The function call failed, so you need to handle the error.
        // You can call GetLastError() to get a more specific error code.
        // ...
    }
}





Is This A Good Question/Topic? 0
  • +

Replies To: C++ Console Pacman game

#2 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3454
  • View blog
  • Posts: 10,659
  • Joined: 05-May 12

Re: C++ Console Pacman game

Posted 28 July 2013 - 03:30 PM

GetAsyncKeyState() will tell you exactly which key is being held down at that instant of time:
http://msdn.microsof...3(v=vs.85).aspx

I highly recommend getting rid of the magic numbers and replacing them with more descriptive names. What does 111 or 35 represent? What does 074 mean?
Was This Post Helpful? 1
  • +
  • -

#3 Toadill  Icon User is offline

  • D.I.C Regular

Reputation: 45
  • View blog
  • Posts: 392
  • Joined: 08-January 12

Re: C++ Console Pacman game

Posted 28 July 2013 - 03:56 PM

Okay here we go!!

Now I just need to add AI path finding rather then going straight for Pacman.


//Coded by James Leshko

#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <ctime>

using namespace std;
// 35 = walls

// 88 = ghost2
// 89 = ghost3

const int SMALLPILL = 111;
const int POWERPILL = 79;
const int PACMANRIGHT = 074;
const int PACMANLEFT = 076;
const int PACMANUP = 118;
const int PACMANDOWN = 94;
const int GHOST1 = 87;
const int BLANK = 000;
const int WALL = 35;
const int MAXROWS = 32;
const int MAXCOLUMNS = 28;

char keyboardValue = 127;
//Start position is [15][0]
int pacI = 15, pacJ = 0;
//Ghost1 Start postion is [16][14]
int ghostOneI = 16, ghostOneJ = 14;
int node1i = 16, node1j = 5;
int i = 0 , j = 0;
char key = 127;

char levelMatrix[MAXROWS][MAXCOLUMNS] = 
    {
	   { 35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35},
	   { 35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35,  79,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  79,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 000,  35,  35, 000,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 000,  35,  35, 000,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35,  35, 000, 000, 000, 000,  35,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   {074, 000, 000, 000, 000, 000, 111, 000, 000, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000, 000, 000, 111, 000, 000, 000, 000, 000, 000},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35, 000, 000, 000, 000, 000, 000,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35,  35, 000, 000, 000, 000,  35,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35,  35,  35,  35,  35,  35, 111,  35,  35, 000,  35,  35,  35,  35,  35,  35,  35,  35, 000,  35,  35, 111,  35,  35,  35,  35,  35,  35},
	   { 35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35, 111,  35,  35,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35, 111,  35,  35,  35,  35, 111,  35},
	   { 35,  79, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111,  79,  35},
	   { 35,  35,  35, 111,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35, 111,  35,  35,  35},
	   { 35,  35,  35, 111,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35, 111,  35,  35,  35},
	   { 35, 111, 111, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111,  35,  35, 111, 111, 111, 111, 111, 111,  35},
	   { 35, 111,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35},
	   { 35, 111,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35,  35, 111,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35, 111,  35},
	   { 35, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,  35},
	   { 35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35}
    };

char ghostCurrent = levelMatrix[ghostOneI][ghostOneJ];
char ghostTrail = ghostCurrent[&ghostOneI][&ghostOneJ];

void getKeyPress();
bool blockValid(int block);
void Ghost();
void GoToXY(int column, int line);
bool ghostMoveUp();
bool ghostMoveDown();
bool ghostMoveLeft();
bool ghostMoveRight();
int findNode();

int pillCount = 244;
int lives = 3;
clock_t startTime = 0, endTime= 0;
bool superPellet = false;
bool pill = false;



int main()
{
    HANDLE  hConsole;
    int k =14;

    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hConsole, k);

    cout << "       ###############			   "<< endl;         
    cout << "      ##################		   "<< endl;       
    cout << "    #######################		   "<< endl;         
    cout << "  ##############   ###########				   "<< endl;
    cout << "##############################				   "<< endl;
    cout << "#######################				   "<< endl;
    cout << "####################			   "<< endl;
    cout << "################			   "<< endl;
    cout << "#############			   "<< endl;
    cout << "###########				   "<< endl;   
    cout << "#########					   "<< endl;
    cout << "############			   "<< "PACMAN" << endl;         
    cout << "##################		   "<< endl;       
    cout << "#######################		   "<< endl;         
    cout << "###########################				   "<< endl;
    cout << "##############################				   "<< endl;
    cout << "    #######################				   "<< endl;
    cout << "      ####################			   "<< endl;
    cout << "        ################			   "<< endl;

    cout << endl;
    system("pause");
    char key = 0;
    system("mode 80, 50");
    int pills = 30;
    bool stopCounting  = false;
    //create the matrix 
    //28 columns
    //32 high

    do
    {
	   //Set Start position
	   GoToXY(0, 0);
	   Ghost();
	   getKeyPress();
	   //Column
	   for (i = 0; i <= 31; i++)
	   {
		  //Row
		  for (j = 0; j <= 27; j++)
		  {
			 //Walls
			 if (levelMatrix[i][j] == WALL)
			 {
				k = 1;
				SetConsoleTextAttribute(hConsole, k);
			 }
			 //Pacman
			 else if (levelMatrix[i][j] == PACMANRIGHT || levelMatrix[i][j] == PACMANLEFT || levelMatrix[i][j] == PACMANUP ||levelMatrix[i][j] == PACMANDOWN)
			 {
				k = 14;
				SetConsoleTextAttribute(hConsole, k);
			 }
			 //Blank
			 else if (levelMatrix[i][j] == BLANK)
			 {
				k = 0;
				SetConsoleTextAttribute(hConsole, k);
			 }
			 //Ghost
			 else if (levelMatrix[i][j] == GHOST1)
			 {
				if (superPellet)
				{
				    k = 7;
				    SetConsoleTextAttribute(hConsole, k);
				}
				else
				{
				    k = 4;
				    SetConsoleTextAttribute(hConsole, k);
				}
			 }
			 //pill
			 else if (levelMatrix[i][j] == SMALLPILL)
			 {
				k = 15;
				SetConsoleTextAttribute(hConsole, k);
			 }
			 //Power pill
			 else if (levelMatrix[i][j] == POWERPILL)
			 {
				k = 14;
				SetConsoleTextAttribute(hConsole, k);
			 }

			 cout << levelMatrix[i][j];
			 if ( j == 27)
				cout << endl;

			 if ( j == 27 && i == 31)
				stopCounting = true;
		  }  
	   }

	   //Color
	   k = 15;
	   SetConsoleTextAttribute(hConsole, k);
	   
	   cout << "lives remaining " << lives << endl;
	   endTime = clock();
	   int elapsed = int((endTime - startTime) / CLOCKS_PER_SEC);
	   //cout  << elapsed;

	   if (elapsed > 5)
	   {
		  superPellet = false;
		  elapsed = 0;
	   }
    }
    while (lives >= 0 || pillCount != 0);
    
    	system("pause");
	return 0;
};

bool ghostMoveUp()
{
    char ghostNextUp = levelMatrix[ghostOneI - 1][ghostOneJ];
      //Check the next upward block to be sure it is not a wall
    if ( ghostNextUp != WALL)
    {
	   //Check the last block to see if there was a pill
	   if ( ghostNextUp == SMALLPILL || ghostNextUp == 117 )
	   {
		  //put the pill back
		  levelMatrix[ghostOneI - 1][ghostOneJ] = GHOST1;

		  levelMatrix[ghostOneI][ghostOneJ] = ghostTrail;
		  ghostOneI--;
	   }
	   else
	   {
		  pill = false;
		  levelMatrix[ghostOneI][ghostOneJ] = BLANK;
		  levelMatrix[ghostOneI - 1][ghostOneJ] = GHOST1;
		  ghostOneI--;
	   }
	   return true;
    }
    else
    {
	   return false;
    }
}

bool ghostMoveDown()
{

    char ghostNextDown = levelMatrix[ghostOneI + 1][ghostOneJ];
    if ( ghostNextDown != WALL)
    {
	   if ( ghostNextDown == SMALLPILL || ghostNextDown ==117)
	   {
		  levelMatrix[ghostOneI + 1][ghostOneJ] = GHOST1;
		  levelMatrix[ghostOneI][ghostOneJ] = ghostNextDown;
		  ghostOneI++;
	   }
	   else
	   {
		  levelMatrix[ghostOneI][ghostOneJ] = BLANK;
		  levelMatrix[ghostOneI + 1][ghostOneJ] = GHOST1;
		  ghostOneI++;
	   }
	   return true;
    }
    else
    {
	   return false;
    }
}

bool ghostMoveLeft()
{
    char ghostNextLeft = levelMatrix[ghostOneI][ghostOneJ - 1];
    if ( ghostNextLeft != WALL)
	   {
		  if ( ghostNextLeft == SMALLPILL || ghostNextLeft ==117)
		  {
			 levelMatrix[ghostOneI][ghostOneJ - 1] = GHOST1;
			 levelMatrix[ghostOneI][ghostOneJ] = ghostNextLeft;
			 ghostOneJ--;
		  }
		  else
		  {
			 levelMatrix[ghostOneI][ghostOneJ] = BLANK;
			 levelMatrix[ghostOneI][ghostOneJ - 1] = GHOST1;
			 ghostOneJ--;
		  }
		   return true;
	   }
        else
	   {
		  return false;
	   }

}

bool ghostMoveRight()
{
    char ghostNextRight = levelMatrix[ghostOneI][ghostOneJ + 1];
    if ( ghostNextRight != WALL)
    {
	  
	   if ( ghostNextRight == SMALLPILL || ghostNextRight ==117)
	   {
		  levelMatrix[ghostOneI][ghostOneJ + 1] = GHOST1;
		  levelMatrix[ghostOneI][ghostOneJ] = ghostNextRight;
		  ghostOneJ++;
	   }
	   else
	   {
		  levelMatrix[ghostOneI][ghostOneJ] = BLANK;
		  levelMatrix[ghostOneI][ghostOneJ + 1] = GHOST1;
		  ghostOneJ++;
	   }
	   return true;
    }
    else
    {
	   return false;
    }

}

void Ghost()
{
    if (superPellet)
    {
	   //Ghost is moving up 
	   if ( pacI > ghostOneI)
	   {
		  //if wall found
		  if (!ghostMoveUp())
		  { 
			 //find node path 
		  }
	   }
    
	   //Ghost is moving down
	   else if (pacI < ghostOneI)
	   {
		  if (!ghostMoveDown())
		  {

		  }
	   }

	   //Ghost is moving left
	    if (pacJ > ghostOneJ)
	   {
		  if (!ghostMoveLeft())
		  {

		  }
	   }

	   //Ghost is moving right
	   else if (pacJ < ghostOneJ)
	   {
		  if (!ghostMoveRight())
		  {

		  }
	   }
    }
    else
    {


	   //Ghost is moving up 
	   if ( pacI < ghostOneI)
	   {

		  //if wall found
		  if (!ghostMoveUp())
		  { 

		  }
	   }
    
	   //Ghost is moving down
	   else if (pacI > ghostOneI)
	   {
		  if (!ghostMoveDown())
		  {

		  }
	   }

	   //Ghost is moving left
	   if (pacJ < ghostOneJ)
	   {
		  if (!ghostMoveLeft())
		  {

		  }
	   }

	   //Ghost is moving right
	   else if (pacJ > ghostOneJ)
	   {
		  if (!ghostMoveRight())
		  {

		  }
	   }
    }

    //you caught the ghost
    if (pacJ == ghostOneJ && pacI == ghostOneI && superPellet)
    {
	   levelMatrix[ghostOneI][ghostOneJ] = PACMANRIGHT;
	   ghostOneI = 16;
	   ghostOneJ = 14;
	   levelMatrix[16][14] = GHOST1;
    }
    //Reset the postion of pacman you died
    else if (pacJ == ghostOneJ && pacI == ghostOneI)
    {
	   lives--;
	   levelMatrix[pacI][pacJ] = BLANK;
	   levelMatrix[ghostOneI][ghostOneJ] = BLANK;
	   pacI = 15;
	   pacJ = 0;
	   ghostOneI = 16;
	   ghostOneJ = 14;
	   levelMatrix[15][0] = PACMANRIGHT;
	   levelMatrix[16][14] = GHOST1;
    }
}

void getKeyPress()
{
    if(GetAsyncKeyState(VK_UP))
    {
	   if ( levelMatrix[pacI- 1][pacJ] != WALL)
	   {
		  if (levelMatrix[pacI- 1][pacJ] == POWERPILL)
		  {
			 startTime = clock();
			 superPellet = true;
		  }
		  levelMatrix[pacI][pacJ] = BLANK;
		  levelMatrix[pacI - 1][pacJ] = PACMANUP;
		  pacI--;
	   }
    }
    else if (GetAsyncKeyState(VK_LEFT)) //left
    {
	   if ( levelMatrix[pacI][pacJ- 1] != WALL)
	   {
		  if (levelMatrix[pacI][pacJ - 1] == POWERPILL)
		  {
			 startTime = clock();
			 superPellet = true;
		  }
		  levelMatrix[pacI][pacJ] = BLANK;
		  levelMatrix[pacI][pacJ - 1] = PACMANLEFT;
		  pacJ--;
	   }
    }
    else if (GetAsyncKeyState(VK_RIGHT)) //right
    {
	   if ( levelMatrix[pacI][pacJ+ 1] != WALL)
	   {
		  if (levelMatrix[pacI][pacJ + 1] == POWERPILL)
		  {
			 startTime = clock();
			 superPellet = true;
		  }
		  levelMatrix[pacI][pacJ] = BLANK;
		  levelMatrix[pacI][pacJ + 1] = PACMANRIGHT;
		  pacJ++;
	   }
    }
    else if (GetAsyncKeyState(VK_DOWN)) //down
    {
	   if ( levelMatrix[pacI + 1][pacJ] != WALL)
	   {
		  if (levelMatrix[pacI + 1][pacJ] == POWERPILL)
		  {
			 startTime = clock();
			 superPellet = true;
		  }
		  levelMatrix[pacI][pacJ] = BLANK;
		  levelMatrix[pacI + 1][pacJ] = PACMANDOWN;
		  pacI++;
	   }
    }
}

void GoToXY(int column, int line)
{
    // Create a COORD structure and fill in its members.
    // This specifies the new position of the cursor that we will set.
    COORD coord;
    coord.X = column;
    coord.Y = line;

    // Obtain a handle to the console screen buffer.
    // (You're just using the standard console, so you can use STD_OUTPUT_HANDLE
    // in conjunction with the GetStdHandle() to retrieve the handle.)
    // Note that because it is a standard handle, we don't need to close it.
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    // Finally, call the SetConsoleCursorPosition function.
    if (!SetConsoleCursorPosition(hConsole, coord))
    {
        // Uh-oh! The function call failed, so you need to handle the error.
        // You can call GetLastError() to get a more specific error code.
        // ...
    }
}





I have also noticed now that I will have to control the loop so the ghost moves a little slower now. Otherwise the player stands no chance. I believe path finding will help a little bit but will still need to be governed.

This post has been edited by Toadill: 28 July 2013 - 04:11 PM

Was This Post Helpful? 0
  • +
  • -

#4 Kohana  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 56
  • Joined: 09-January 10

Re: C++ Console Pacman game

Posted 28 July 2013 - 04:34 PM

Sweet game dude!

You should create a thread class to run the movement code for the enemy so he moves independent of the player. You used threads before?
Was This Post Helpful? 0
  • +
  • -

#5 Toadill  Icon User is offline

  • D.I.C Regular

Reputation: 45
  • View blog
  • Posts: 392
  • Joined: 08-January 12

Re: C++ Console Pacman game

Posted 28 July 2013 - 04:45 PM

View PostKohana, on 28 July 2013 - 06:34 PM, said:

Sweet game dude!

You should create a thread class to run the movement code for the enemy so he moves independent of the player. You used threads before?



The code above does make the ghost independent :turned:
it's just that now he runs into walls trying to get to pacman. Now I have to build path finding nodes or other targets for the ghost to travel to that will help guide the ghost to Pacman. The logic I have figured is to set a timer, much like what happens when pacman eats a power pellet it will last for so long then go back to normal. Except in this case the timer would be set to find node paths instead of pacman. Once the timer is up it will continue looking for pacman. The timer would be trigger when the ghost hits a wall.

I also have to slow down the loop so that the ghost does not move so fast lol. Right now he moves at mock 1 on a straight stretch. :death:


Also another thing that is not exactly perfect is the way the ghost puts the pills back. I have been trying to devise a way to keep track of what was on the next block to put back when the ghost moves from the block. :oops:

This post has been edited by Toadill: 28 July 2013 - 05:08 PM

Was This Post Helpful? 0
  • +
  • -

#6 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3454
  • View blog
  • Posts: 10,659
  • Joined: 05-May 12

Re: C++ Console Pacman game

Posted 28 July 2013 - 08:12 PM

This maybe a silly question, but in an interview of the author of pacman, he mentioned that there was very little smarts built into the ghosts AI. He said that they simply headed towards pacman's current location based on X and Y relative values. There was no pathing logic. Also why even worry about threads? Back when the game was written, the target platforms didn't do threading. Why make things more complicated by using threads?
Was This Post Helpful? 0
  • +
  • -

#7 Toadill  Icon User is offline

  • D.I.C Regular

Reputation: 45
  • View blog
  • Posts: 392
  • Joined: 08-January 12

Re: C++ Console Pacman game

Posted 28 July 2013 - 08:25 PM

View PostSkydiver, on 28 July 2013 - 10:12 PM, said:

This maybe a silly question, but in an interview of the author of pacman, he mentioned that there was very little smarts built into the ghosts AI. He said that they simply headed towards pacman's current location based on X and Y relative values. There was no pathing logic. Also why even worry about threads? Back when the game was written, the target platforms didn't do threading. Why make things more complicated by using threads?


As you can see in this version of pacman the ghost moves until it reaches a wall, then it gets stuck and stops moving. Therefore it would need some kind of path finding nodes to direct it.

I just found a good resource for this that explains what I am talking about well.

Pacman Logic
Was This Post Helpful? 1
  • +
  • -

#8 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3454
  • View blog
  • Posts: 10,659
  • Joined: 05-May 12

Re: C++ Console Pacman game

Posted 29 July 2013 - 05:57 AM

Nice article! Anyway this is what was in the back of my mind when I made the post above above simplistic logic:

Quote

When a decision about which direction to turn is necessary, the choice is made based on which tile adjoining the intersection will put the ghost nearest to its target tile, measured in a straight line.

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1