Advertisement

Not quite Pac-Man AI

Started by July 28, 2003 05:32 AM
14 comments, last by Beren77 21 years, 6 months ago
Hey, thanks for the nice reply Beren...

You orginally asked for help, and now in the same posting your assisting me

Anyway, I dont have a "graphics system"

Originally I made a stupid thing in turing by drawing a square, then drawing a bunch of rectangles or squares over it... Then i had a blue circle (mouse) go after a yellow arc... I only ever got to the point where the "mouse" wouldnt go out side of the main square, but other than that it owuld just move randomly arund and thru walls until like 400 moves later it "might" run into the cheese...

I kinda came up with a good way to do this one day while I was sitting at work (im a telemarketer) anyway, I am outta programming for over a year now... and now Im am gonna learn c++ right now again, but I think the code you posted is still a little over my head(but I will give it a clear lookover) will it run by itself???

Anyway, just some of my abstract rambling(oh yeah, I meant like this:

*******************
* * * * * *CC*
* * * * * *
* * * *
* **** * * 1****
* **** 1*2 *
* **** * 1* 223 *
*SS111111112111*2 *
*******************

See, my main theory is that let the cpu randomly decide a way to go, and eac htime it gets more than one chance, let it decide again, however, you gotta check the "value" of each square, the above map shows a "mouse" trying to get to the CC without knowing where it is... It randomly starts out going east... keeps going past the first intersection, then makes a wrong turn, but when it goes to go back, the previous value is 1.. however, in that event, it just goes to the place it has been the least, so it escapes, and keeps going east(cause to go west would be going over all those ones, which are higher than the "0" or whatever value for the unchecked spaces... it then meets a wall, has to go up, then gets a chance to go up or right, it chooses right, then goes up, then goes down, and it keeps going one direction or the other til eventually the spaces it has passed grows larger(or as large as) the values of the spaces it must go back over, so then it just keeps going...

That is a whole lot of writing for nothing, and maybe my idea is stupid, but I just thought when I was younger that something not knowing where to go, can just choose randomly, and yet, if it can keep conscious of where its been before slightly, then eventually, it owuld cover a whole map until it got to its destination, while not the fastest way, its not as stupid looking as always turning left/right, and the cpu doesnt really "cheat" it just can sense how many times its been in that spot before, and then always goes to the place its been the least( or randomly if one or more of the same value are open)

Well, thats just my crazy rambling thoughts... Iwould love to see this idea implemented someday, but well have to see...
Mess With the Best, go down like the rest, but please visit:http://members.tripod.com/nu_bgameprogramming/
Hi Brackus,

don't want the spoil the fun for you, but I was just a little frustrated about some other code of mine (don't ask...), so I settled down to write a (graphically _very_ simple) console program to visualize your mouse/cheese problem.
I tried to implement your idea, so I have an AIMap representing the number of times the mouse has passed over a field. The mouse then moves by checking where the neighboring field with the lowest number is. There are cases where the mouse could choose between two or more fields, because they have the same value. You could apply a random choice here. For the sake of simplicity, I omitted it and simply went for a strict ordering. So the mouse tries to go up, down, left, right (in that order).
(in other words, if all four neighboring fields have the same value, the mouse will always go up).

One problem is still unsolved, though: If the mouse hits a dead-end, it takes a step back and could then be in a position where the route back to the dead-end could have the same value as the way further out. So the dead-end could be entered twice (so occuring in the sample program below).

Feel free to ask any questions about the code, play with it, change it, do whatever you like with it --- and have fun.

Hope this code is easier to understand.
Beren

#include <stdio.h>#include <conio.h>#define MAZE_SIZE_X 10#define MAZE_SIZE_Y 10// Stores the maze informationchar Maze[MAZE_SIZE_X * MAZE_SIZE_Y] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1,                                         1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1,1, 0, 0, 1, 0, 1, 0, 0, 1, 1,1, 0, 1, 0, 0, 0, 1, 0, 0, 1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1};char AIMap[MAZE_SIZE_X * MAZE_SIZE_Y];// This functions outputs the Maze and the AIMap on the console.void drawMazeAndMap() {	for (int y = 0; y < MAZE_SIZE_Y; y++) {				for (int x = 0; x < MAZE_SIZE_X; x++) {		  switch (Maze[y * MAZE_SIZE_X + x]) {								case 0: printf(" "); break; // Free space				case 1: printf("*"); break; // Wall				case 2: printf("M"); break; // Mouse				case 3: printf("C"); break; // Cheese			}		}		printf("    ");		// Now draw one line of the AI Map:		for (int x2 = 0; x2 < MAZE_SIZE_X; x2++) {		  printf("%d", AIMap[y * MAZE_SIZE_X + x2]);		}		printf("\n");	}	printf("\n\n");}// Simply initializes the AIMap with 0 values.void clearAIMap() {	for (int i = 0; i < (MAZE_SIZE_Y * MAZE_SIZE_X); i++) {	  AIMap[i] = 0;	}}// The main "mouse-loop".// Hit any key to let the mouse move one more step and observe// how the maze and the AIMap change.// Hit ESC to abort or wait until the mouse found the cheese.void mainLoop() {	bool end = false;	char key;		// (Starting) positions of cheese and mouse:	// (Upper left corner is (0,0), lower right corner is	// (MAZE_SIZE_X - 1, MAZE_SIZE_Y - 1)	int cheese_x = 1, cheese_y = 1;	int mouse_x  = 1, mouse_y  = 8;	// Place the cheese (3 == cheese)	Maze[cheese_y * MAZE_SIZE_X + cheese_x] = 3;	// Place the mouse (2 == mouse)	Maze[mouse_y  * MAZE_SIZE_X + mouse_x]  = 2;	// The mouse has been on its initial field once, so set the	// AIMap value of its current position to 1	AIMap[mouse_y * MAZE_SIZE_X + mouse_x]++;	// Show the maze	drawMazeAndMap();	while (!end) {		key = getch();		if (key == 27) {			end = true;		}		// Move the mouse:		// First, determine which fields the mouse can walk to (empty fields):		int left = -1, right = -1, up = -1, down = -1;		if (Maze[(mouse_y - 1) * MAZE_SIZE_X + mouse_x] != 1) {			up = AIMap[(mouse_y - 1) * MAZE_SIZE_X + mouse_x];		}		if (Maze[(mouse_y + 1) * MAZE_SIZE_X + mouse_x] != 1) {			down = AIMap[(mouse_y + 1) * MAZE_SIZE_X + mouse_x];		}		if (Maze[mouse_y * MAZE_SIZE_X + mouse_x - 1] != 1) {			left = AIMap[mouse_y * MAZE_SIZE_X + mouse_x - 1];		}		if (Maze[mouse_y * MAZE_SIZE_X + mouse_x + 1] != 1) {			right = AIMap[mouse_y * MAZE_SIZE_X + mouse_x + 1];		}				// Now select the best field (the one with the smallest number > -1):		// If there are two fields with the same value, the mouse will prefer		// the field checked first (i.e. it will go up, down, left, right).		// So, the mouse will only go right, if there are no other chances at		// all. One problem here is, that thus, one dead-end is always hit		// twice.		int min = 99999, dir = -1;		if (up < min && up != -1) {			min = up;			dir = 0;		}		if (down < min && down != -1) {			min = down;			dir = 1;		}		if (left < min && left != -1) {			min = left;			dir = 2;		}		if (right < min && right != -1) {			min = right;			dir = 3;		}		// Remove the mouse from its old position		Maze[mouse_y * MAZE_SIZE_X + mouse_x] = 0;				// Calculate the new mouse coordinates:		switch (dir) {			case 0: mouse_y--; break;			case 1: mouse_y++; break;			case 2: mouse_x--; break;			case 3: mouse_x++; break;		}		// Now check if the target field contains the cheese...		if (Maze[mouse_y * MAZE_SIZE_X + mouse_x] == 3) {			printf("And the mouse is happily munching its cheese *hjam*...\n");			// Comment the next line out, if you want to know, if all fields			// of the maze are reached... (and they are :-))			end = true;		}		// Move the mouse:		Maze[mouse_y * MAZE_SIZE_X + mouse_x] = 2;		// And increase the "waycounter" of the mouse:		AIMap[mouse_y * MAZE_SIZE_X + mouse_x]++;		// Show the progress...		drawMazeAndMap();	}}void main() {  clearAIMap();		drawMazeAndMap();	mainLoop();}


[edited by - Beren77 on July 31, 2003 5:34:27 PM]
Advertisement
Yeah, its way easier in person, but basically, that is what i tried to show in my last posting!!!

Once the mouse hits a dead end, then backs up, likely, the way forward/backward (or right/left) has the same value (most likely a 1) that I guess is where the randomness would be stupid, so maybe if a thing was implemented so that in the event that situation occured, that it would go to the space it hadnt been to in the longest amount of time... Anyway, like I said, even if randomly it went down the dead end again, it would still add the numbers up, until eventuallythe "mouse" would have to get back down the dead end, and with the numbers to go back way higher than the numbers out, it would work...

This sound kinda like gibberish even to me, but its cool you find this a bit interesting...

Dustin
Mess With the Best, go down like the rest, but please visit:http://members.tripod.com/nu_bgameprogramming/
Hi,

one solution to that problem would be to assign a "how-long-has-it-been-since-the-mouse-was-here" value to each field. Actually, all you have to do is to increase the value of the AIMap field that the mouse moves to by any value > 1 (say 50 for example). Then, all AI fields that the mouse is currently not on and have a value > 0 are reduced by 1 et voilà: instead of having two fields with the same value, one leading into a dead-end, you would have two fields with different values, the lower one leading away from the dead end.

Beren
I''m not exactly sure (never checked myself) but one time the AI in Pac Man was described to me like this:

The ghosts follow a "set" routine for a few seconds then...

1. The Red ghost always picks the shortest path to you.
2. 2 Ghosts pick the best path to get to the spot left/right of you.
3. A fourth ghost tries to get to a spot below you.

Every now and then, the ghosts are forced to flip back on themselves.

Again, this is what I was told one time, but never looked at the source to confirm.
I tought it was

1st Ghost chase you.
2nd Protect the middle of the field
3rd and 4th trying to sandwich you.
I teleported home one night; With Ron and Sid and Meg; Ron stole Meggie's heart away; And I got Sydney's leg. <> I'm blogging, emo style

This topic is closed to new replies.

Advertisement