Hi, im currently doing a pacman game in c++ as a project.
im currently not using graphics but only using the console for simple representation.
right now, I'm having problems concerning detection of pellets. Im a bit confused why it detects it as walls even though i check if the current value of the tile is a non-wall object. hers the code.

#include <iostream>
#include <Windows.h>
using namespace std;

struct Player 
{
	int x, y;
	Player()
	{
		x = 4;
		y = 1;
	}
};



const char SYMBOL_EMPTY = ' ';
const char SYMBOL_PLAYER = '@';

const char SYMBOL_WALL = '#';
const char SYMBOL_PELLET ='.';
const int Xlim = 10;
const int Ylim = 29;
const int GameSpeed = 100;
const int LEFT = 1;
const int RIGHT = 2;
const int UP = 3;
const int DOWN = 4;
int direction = RIGHT;

char map[29][29] = 
{
	"############################",
	"#...........####...........#",
	"#.###.#####.####.#####.###.#",
	"#.###.#####.####.#####.###.#",
	"#                          #",
	"#                          #",
	"#                          #",
	"#                          #",
	"############################"
};

bool isValidPos(int x, int y) 
{ 
	return (x >= 0 && x < Xlim && y >= 0 && y < Ylim);
}


bool movePlayer(Player &player, int x, int y,int direction)
{

	char ch;
	if (!isValidPos(x, y)) 
	{ 
		return false;
	}
	
	switch (direction)
	{
	case RIGHT:
		ch=map[x+1][y];
		break;
	case LEFT:
		ch=map[x-1][y];
		break;
	case UP:
		ch=map[x][y-1];
		break;
	case DOWN:
		ch=map[x][y+1];
		break;
	}
	
	if(ch != SYMBOL_WALL) 
	{
		map[player.x][player.y] = SYMBOL_EMPTY;
		player.x = x; player.y = y;
		map[player.x][player.y] = SYMBOL_PLAYER;
		return true;	}
	
	else 
		return false;
	
	
}




void showMap() 
{
	for (int x = 0; x < Xlim; x++) 
	{
		cout << map[x] << endl;
	}
}

void showPlayer(Player &player)
{
	cout << "\nPlayerX: " << player.x << endl;
	cout << "PlayerY: " << player.y << endl;
}

void gameLoop() 
{
	Player player;
	
	movePlayer(player, 1, 2, direction);
	
	while (true) 
	{
		system("cls");
		showMap();
		showPlayer(player);
		if (GetAsyncKeyState(VK_UP)) 
		{
			direction = UP;
		} 
		else if (GetAsyncKeyState(VK_DOWN)) 
		{
			direction = DOWN;
		} 
		else if (GetAsyncKeyState(VK_LEFT)) 
		{
			direction = LEFT;
		} 
		else if (GetAsyncKeyState(VK_RIGHT)) 
		{
			direction = RIGHT;
		}
		switch (direction)
		{
		case UP:
			movePlayer(player, player.x-1, player.y, UP);
			break;
		case DOWN:
			movePlayer(player, player.x+1, player.y, DOWN);
			break;
		case LEFT:
			movePlayer(player, player.x, player.y-1, LEFT);
			break;
		case RIGHT:
			movePlayer(player, player.x, player.y+1, RIGHT);
			break;
		}
		
		Sleep(GameSpeed);
	}
}


int main() 
{
	gameLoop();
	return 0;
}

You're doubling the direction test. x or y is already adjusted in the call to movePlayer, and you further adjust it when setting ch in movePlayer. One possible fix is removing the switch in movePlayer and just setting ch to map[x][y] in all cases.

Edited 5 Years Ago by Narue: n/a

I FIXED IT!! though i have problems exiting the loop after eating all the pellets? any ideas how to implement it? i dont think checking the whole map if there are no more '.' characters would be efficient

#include<iostream>
#include<Windows.h>
#include <cstdlib>
#include <time.h>

using namespace std;

//Constants
const char WALL_SPACE='#';
const char EMPTY_SPACE=' ';
const char PELLET_SPACE='.';
const char PACMAN='@';
const int LEFT = 1;
const int RIGHT = 2;
const int UP = 3;
const int DOWN = 4;

//variables
//map is incomplete
char map[29][29] = 
{
	"############################",
	"#                         .#",
	"#                     .###.#",
	"#                 ####.###.#",
	"#               ...........#",
	"#######.#############.######",
	"#..#....................#..#",
	"#....##################....#",
	"############################"
};
int direction=LEFT;
int score = 0;
//structs
struct Player 
{
	int x, y;
	Player()
	{
		x = 2;
		y = 2;
	}
};
//Functions
void scorekeep(int score)
{
	cout<<"Score: "<<score;
}
bool isValidPos(int x, int y) 
{ 
	return (x >= 0 && x < 10 && y >= 0 && y < 30);
}
bool movePlayer(Player &player, int x, int y)
{
	if (!isValidPos(x, y)) 
	{ 
		return false;
	}
	
	char ch = map[x][y];
	
	if(ch== WALL_SPACE) 
	{
		return false;
	}
	
	if(ch==PELLET_SPACE)
		score+=10;
	if (isValidPos(player.x, player.y)) 
	{ 
		map[player.x][player.y] = EMPTY_SPACE;
	}
	player.x = x; player.y = y;
	map[player.x][player.y] = PACMAN;
	
	return true;
}

void showMap() 
{
	for (int x = 0; x < 9; x++) 
	{
		cout << map[x] << endl;
	}
}
bool checkWin(int score)
{
	if(score<500)
		return false;
	else
		return true;
}

void Game()
{
	Player player;
	movePlayer(player, 1, 2);
	
	while (true) 
	{
		system("cls");
		showMap();
		scorekeep(score);
		if(checkWin(score))
			{
				system("pause");
				return;
		}
		if (GetAsyncKeyState(VK_UP)) 
		{
			direction = UP;
		} 
		else if (GetAsyncKeyState(VK_DOWN)) 
		{
			direction = DOWN;
		} 
		else if (GetAsyncKeyState(VK_LEFT)) 
		{
			direction = LEFT;
		} 
		else if (GetAsyncKeyState(VK_RIGHT)) 
		{
			direction = RIGHT;
		}
		switch (direction)
		{
		case UP:
			movePlayer(player, player.x-1, player.y);
			Sleep(50);
			break;
		case DOWN:
			movePlayer(player, player.x+1, player.y);
			Sleep(50);
			break;
		case LEFT:
			movePlayer(player, player.x, player.y-1);
			Sleep(50);
			break;
		case RIGHT:
			movePlayer(player, player.x, player.y+1);
			Sleep(50);
			break;
		}
		
		}
		Sleep(15000);
	}

int main()
{
	Game();
	return 0;
}

Edited 5 Years Ago by kevinmax101: fixed return error

i dont think checking the whole map if there are no more '.' characters would be efficient

Doesn't seem that costly to me?

i dont think checking the whole map if there are no more '.' characters would be efficient

Well, if you call it in a loop for every draw that could slow drawing time and cause flickering (though you already have flickering ;)). I don't think it would be that big of a deal to maintain a count of remaining pellets regardless of how the maps are created. That would speed up your completion check.

Well, if you call it in a loop for every draw that could slow drawing time and cause flickering (though you already have flickering ). I don't think it would be that big of a deal to maintain a count of remaining pellets regardless of how the maps are created. That would speed up your completion check.

oh right, i forgot i can decrement the pellet count =_=. now i just have to initialize how many pellets are thre in a level. tnx btw

Umm i need help again :( im stuck because the ghosts are eating pacman's pellets, which is bad since my win condition is true when the number of pellets becomes 0. I managed to make pacman eat his pellets but i cant make the ghosts go through the pellets and still be displayed.

GHOST movement:

bool moveGhost(Ghost &ghost, int a, int b)
{
	if (!isValidPos(a, b)) 
	{ 
		return false;
	}
	
	char ch = map[a][b];
	
	if(ch==WALL_SPACE) 
	{
		changeDir(ghost);
		return false;
	}

	
	if(ch==PENALTY_BOX)
	{
		return true;
	}
	
	
	map[ghost.a][ghost.b] = EMPTY_SPACE;
	
	ghost.a = a; ghost.b = b;
	map[ghost.a][ghost.b] = GHOST;
	
	if(ch==PELLET_SPACE)
	{
		map[ghost.a][ghost.b]=PELLET_SPACE;

		ghost.a = a; ghost.b = b;
		map[ghost.a][ghost.b] = GHOST;

		
		return true;
	}
	
	return true;
}

I would not write objects to map. i would concider pellets only while moving PacMan.
I would draw in drawing loop first existing in those cordinates: Ghost. packMan, pellet otherwice thing in map.
It is not good to try to manage with only the map, you need layers.

Edited 5 Years Ago by pyTony: n/a

so i need to make 2 maps that have the same data and only pacman updates it? is that what u are tryin to say?

Not necessary map, but the coordinates of the creatures in my opinion should be saved outside the map. The drawing routine would first check if current place has creature/object and draw those. Not direct mapping of map in program and displayed map on screen. Map could be just boolean indicating empty or wall. My opinion only, your choice.

This article has been dead for over six months. Start a new discussion instead.