← All work

IMPLEMENTATION NOTES / C++ / SFML

Pac-Man (SFML Remake)

A Pac-Man remake in C++ and SFML, built to learn the game loop, collision, ghost AI, and sprite drawing.

C++SFMLCMake

IMPLEMENTATION / EQUATIONS & SOURCE

Follow the inputs through the code.

Read each section as purpose → equation → actual source. Snippets are excerpts of the working implementation, not standalone programs. Follow the source link for surrounding context.

01 / Ghosts select a next step, not an entire path

After excluding walls and reverse movement, compare each candidate’s squared distance to the target. No square root is needed for ranking. This chooses a local direction at junctions rather than computing an A* route. The <= test lets later candidates win ties. Distance takes integer arguments, so fractional coordinates are truncated before comparison.

Equation
D²(q,t) = (qx−tx)² + (qy−ty)²
nextDirection = arg min D²(candidate,target)
PacMan/Ghosts.cpp : 49COMMIT c6a12fa
float Distance(int x, int y, int x1, int y1)
{
	return ((x - x1) * (x - x1)) + ((y - y1) * (y - y1));
}

// the original game didnt use a pathfinding algorithm
// simple distance comparisons are fine enough
Dir GetShortestDir(const std::vector<Dir>& squares, const Ghost& ghost, sf::Vector2f target)
{
	int min_dist = 20000000;
	Dir min_dir = NONE;
	if (squares.size() == 0)
		printf("EMPTY\n");

	for (auto dir : squares) {
		sf::Vector2f square = ghost.pos + dir_addition[dir];
		float dir_dist = Distance(target.x, target.y, square.x, square.y);
		if (dir_dist <= min_dist) {
			min_dir = dir;
			min_dist = dir_dist;
		}
	}

	return min_dir;
}
Read this source on GitHub ↗

02 / Different target rules create different behavior

Red targets the player; pink targets four tiles ahead; blue reflects red’s position about the point two tiles ahead of the player. Orange switches to (0,31) when squared player distance is below 64. They share direction selection but use separate target rules.

Equation
tred = player
tpink = player + 4·direction
a = player + 2·direction, tblue = 2a − red
torange = corner if D² < 64, otherwise player

These equations describe the public source, not every rule of the original arcade game or a claim of a newly invented algorithm.

PacMan/Ghosts.cpp : 74COMMIT c6a12fa
sf::Vector2f BlinkyUpdate(Ghost& ghost)
{
	return gState.player->pos;
}
sf::Vector2f PinkyUpdate(Ghost& ghost)
{
	return gState.player->pos + dir_addition[gState.player->cur_dir] * 4;
}
sf::Vector2f InkyUpdate(Ghost& ghost)
{
	sf::Vector2f target = gState.player->pos + dir_addition[gState.player->cur_dir] * 2;
	sf::Vector2f offset = gState.ghosts[RED]->pos - target;
	target = target + offset * -1;
	return target;
}
sf::Vector2f ClydeUpdate(Ghost& ghost)
{
	sf::Vector2f target = gState.player->pos;

	// if clyde is 8 tiles away, target player, else target corner
	if (Distance(ghost.pos.x, ghost.pos.y, gState.player->pos.x, gState.player->pos.y) < 64)
		target = { 0,31 };
	return target;
}
Read this source on GitHub ↗

SOURCE / SCOPE

Scope of the notes.

Each source excerpt comes from the linked fixed commit. Equations describe those operations. Apart from worked examples, no new performance or quality measurements are claimed. Refer to the repository for build steps and dependencies.

Open repository ↗