HO CHI MINH UNIVERSITY OF SCIENCE
CSC14003 - ARTIFICIAL INTELLIGENCE
Project 01: Search
July 29, 2023
Author
Nguyen Vu Bach - 21127224
Nguyen Viet Kim - 21127333
Nguyen Do Nguyen Phuong - 21127399
Le Mai Minh Quan - 21127401
Le Minh - 21127645
1
Introduction to Artificial Intelligence
Contents
1 Project description 3
2 Environment 3
3 Assignment plan 3
4 Level of completion 4
5 Code specification 4
5.1 Used modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
5.2 Class GameState . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
5.3 Some declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
5.4 Heuristic function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
5.5 Dijkstra search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
5.6 Breadth first search function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5.7 Minimax function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
5.8 Move Pac-man function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
5.9 Read map function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.10 Draw objects function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.11 Pac-man breadth first search AI function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
5.12 Pac-man A* AI function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
5.13 Monster A* AI function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5.14 Create graph function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5.15 Main function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5.16 Other functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.16.1 Check for valid move function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.16.2 Check game over function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.16.3 Get game score function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
5.16.4 Manhattan distance function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6 References 13
CSC14003 | Project 01: Search 2
Introduction to Artificial Intelligence
1 Project description
You are given a file that describes Pac-man World. Suggest or implement learned algorithms to assist Pac-Man
in finding food without getting killed by monsters. In the game Pac-Man, both Pac-Man and the monsters
are constrained to moving in four directions: left, right, up, and down. They are not able to move through
walls. The game is divided into four distinct levels, and each level has its own set of rules.
• Level 1: Pac-Man is aware of the food’s position on the map, and there are no monsters present. There
is only one food item on the map.
• Level 2: Monsters are stationary and do not move around. If Pac-Man and a monster collide with each
other, the game ends. There is still one food item on the map, and Pac-Man knows its position.
• Level 3: Pac-Man’s visibility is limited to its nearest three steps. Foods outside this range are not visible
to Pac-Man. Pac-Man can only scan the adjacent tiles within the 8 tiles x 3 range. There are multiple
food items spread throughout the map. Monsters can move one step in any valid direction around
their initial location at the start of the game. Both Pac-Man and monsters move one step per turn.
• Level 4 (difficult) involves an enclosed map where monsters relentlessly pursue Pac-Man. Pac-Man
must gather as much food as possible while avoiding being overtaken by any monster. The monsters
have the ability to pass through each other. Both Pac-Man and the monsters move one step per turn,
and the map contains a multitude of food items.
The calculation of game points follows these rules:
• Each movement deducts 1 point from your score.
• Collecting each food item awards you 20 points.
2 Environment
Our project use Python as the programming language for processing test files, building and compiling
program of the project. Our project runs on Python 3.11 Environment, using Visual Studio Code as compiler.
3 Assignment plan
No. Assignment Student ID
1 BFS search algorithm 21127333
2 Minimax search algorithm 21127401
3 Dijkstra search algorithm 21127401
4 Move Pac-man and Pac-man BFS AI function 21127224
5 Pac-man A* AI function 21127399
6 Ghosts AI function 21127399
7 Read data from file and create map function 21127645
8 Create test maps 21127645
9 Main function 21127399
10 Report 21127333
CSC14003 | Project 01: Search 3
Introduction to Artificial Intelligence
4 Level of completion
No. Specifications Completion
1 Level 1 100%
2 Level 2 100%
3 Level 3 100%
4 Level 4 100%
5 Graphical demonstration 100%
6 Generate at least 5 maps with differences in the number and structure of walls, 70%
monsters, and food
7 Report the algorithm, and experiment with some reflections or comments 100%
5 Code specification
5.1 Used modules
These are modules that are used in our project.
• sys module: it provides access to some variables used or maintained by the interpreter and to functions
that interact strongly with the interpreter.
• heapq module: used to access to heap queue algorithm.
• pygame module: this module provides functions to demonstrate Pac-man as a game.
• time module: used to calculate run time of the algorithm.
• random module: used to create random choice for direction in the algorithm.
• collections module: this module is used to import deque module used as list-like container.
1 import sys
2 import heapq
3 import pygame
4 from pygame . locals import *
5 import time
6 from random import choice
7 from collections import deque
Listing 1: Used modules
5.2 Class GameState
GameState class contains information of the game, including size of the map, matrix of the map; Pacman,
monster and food information, game score, game state (game_over) and the level (1, 2, 3, 4).
1 class GameState :
2 def __init__ ( self , size , matrix , pacman , monsters , food , level ) :
3 self . size = size
4 self . matrix = matrix
5 self . pacman = pacman
6 self . monsters = monsters
7 self . food = food
8 self . score = 0
CSC14003 | Project 01: Search 4
Introduction to Artificial Intelligence
9 self . game_over = False
10 self . level = level
Listing 2: Class GameState
5.3 Some declarations
These are some global declarations for used in algorithm. There are colors, level and cache for A* heuristic
declarations.
1 # colors
2 BLACK = (0 , 0 , 0)
3 WHITE = (255 , 255 , 255)
4 YELLOW = (255 , 255 , 0)
5 RED = (255 , 0 , 0)
6 GREEN = (0 , 255 , 0)
7
8 # Level
9 LEVEL_1 = 1
10 LEVEL_2 = 2
11 LEVEL_3 = 3
12 LEVEL_4 = 4
13
14 # cache for A * seacrh heuristic
15 heuristic_cache = {}
Listing 3: Global declarations
5.4 Heuristic function
Heuristic function is used to estimate distance from the current node (point) to the goal point using Euclidean
algorithm and store results in the heuristic_cache dictionary.
1 def heuristic ( node , goal ) :
2 if node not in heuristic_cache :
3 heuristic_cache [ node ] = (( node [0] - goal [0]) ** 2 + ( node [1] - goal [1]) ** 2) **
0.5
4 return heuristic_cache [ node ]
Listing 4: heuristic function
5.5 Dijkstra search
Implementation of Dijkstra search for finding path for Pac-man.
1 def dijkstra_search ( graph , start , goal ) :
2 queue = []
3 heapq . heappush ( queue , (0 , start ) ) # (f , node )
4 came_from = {}
5 cost_so_far = {}
6 came_from [ start ] = None
7 cost_so_far [ start ] = 0
8
9 while queue :
10 _ , current = heapq . heappop ( queue )
11
CSC14003 | Project 01: Search 5
Introduction to Artificial Intelligence
12 if current == goal :
13 break
14
15 for next_node in graph [ current ]:
16 new_cost = cost_so_far [ current ] + 1 # Step = 1
17
18 if next_node not in cost_so_far or new_cost < cost_so_far [ next_node ]:
19 cost_so_far [ next_node ] = new_cost
20 priority = new_cost + heuristic ( next_node , goal )
21 heapq . heappush ( queue , ( priority , next_node ) )
22 came_from [ next_node ] = current
23
24 path = []
25 current = goal
26 while current != start :
27 path . append ( current )
28 current = came_from [ current ]
29 path . append ( start )
30 path . reverse ()
31
32 return path
Listing 5: Global declarations
5.6 Breadth first search function
BFS algorithm implementation used in Pac-man path finding.
1 def bfs_search ( matrix , start , goal ) :
2 if not is_valid_position ( matrix , start ) or not is_valid_position ( matrix , goal ) :
3 return []
4
5 queue = deque ()
6 queue . append ( start )
7 visited = set ()
8 visited . add ( start )
9 came_from = {}
10 came_from [ start ] = None
11
12 while queue :
13 current = queue . popleft ()
14
15 if current == goal :
16 break
17
18 x , y = current
19 adjacent_tiles = [( x - 1 , y ) , ( x + 1 , y ) , (x , y - 1) , (x , y + 1) ]
20 for next_node in adjacent_tiles :
21 if next_node not in visited and is_valid_position ( matrix , next_node ) :
22 queue . append ( next_node )
23 visited . add ( next_node )
24 came_from [ next_node ] = current
25
26 path = []
27 current = goal
28 while current != start :
CSC14003 | Project 01: Search 6
Introduction to Artificial Intelligence
29 path . append ( current )
30 current = came_from [ current ]
31 path . append ( start )
32 path . reverse ()
33
34 return path
Listing 6: BFS function
5.7 Minimax function
Implementation of the minimax algorithm for Pac-man path finding in the game.
1 def minimax ( game_state , depth , max_player ) :
2 if depth == 0 or is_terminal_state ( game_state ) :
3 return evaluate_game_state ( game_state )
4
5 if max_player :
6 max_eval = float ( ’ - inf ’)
7 valid_moves = get_valid_moves ( game_state )
8 for move in valid_moves :
9 new_state = GameState (
10 game_state . size ,
11 game_state . matrix ,
12 game_state . pacman ,
13 game_state . monsters [:] ,
14 game_state . food [:]
15 )
16 make_move ( new_state , move )
17 eval = minimax ( new_state , depth - 1 , False )
18 max_eval = max ( max_eval , eval )
19 return max_eval
20
21 else :
22 min_eval = float ( ’ inf ’)
23 valid_moves = get_valid_moves ( game_state )
24 for move in valid_moves :
25 new_state = GameState (
26 game_state . size ,
27 game_state . matrix ,
28 game_state . pacman ,
29 game_state . monsters [:] ,
30 game_state . food [:]
31 )
32 make_move ( new_state , move )
33 eval = minimax ( new_state , depth - 1 , True )
34 min_eval = min ( min_eval , eval )
35 return min_eval
Listing 7: Minimax function
5.8 Move Pac-man function
1 def make_move ( game_state , move ) :
2 x , y = game_state . pacman
3
CSC14003 | Project 01: Search 7
Introduction to Artificial Intelligence
4 if move == ’ up ’:
5 x -= 1
6 elif move == ’ down ’:
7 x += 1
8 elif move == ’ left ’:
9 y -= 1
10 elif move == ’ right ’:
11 y += 1
12
13 if is_va lid_position ( game_state . matrix , (x , y ) ) :
14 game_state . score -= 1
15 if (x , y ) in game_state . food :
16 game_state . food . remove (( x , y ) )
17 game_state . score += 20
18 if not game_state . food :
19 game_state . game_over = True
20
21 game_state . pacman = (x , y )
22
23 game_state . matrix [ game_state . pacman [0]][ game_state . pacman [1]] = ’5 ’
Listing 8: Move Pacman function
5.9 Read map function
1 def read_map ( file_name ) :
2 with open ( file_name , ’r ’) as file :
3 size = tuple ( map ( int , file . readline () . strip () . split () ) )
4 matrix = []
5 for _ in range ( size [0]) :
6 row = list ( file . readline () . strip () . split () ) # Read matrix values as
strings
7 matrix . append ( row )
8 pacman = tuple ( map ( int , file . readline () . strip () . split () ) )
9 monsters = []
10 food = []
11 for i in range ( size [0]) :
12 for j in range ( size [1]) :
13 if matrix [ i ][ j ] == ’3 ’:
14 monsters . append (( i , j ) )
15 elif matrix [ i ][ j ] == ’2 ’:
16 food . append (( i , j ) )
17 return size , matrix , pacman , monsters , food
Listing 9: Read map function
5.10 Draw objects function
draw_objects() function is used to draw objects (Pac-man, mosters,food and walls) to the game screen.
1 def draw_objects ( screen , game_state ) :
2 cell_size = 50
3 for i in range ( game_state . size [0]) :
4 for j in range ( game_state . size [1]) :
5 if (i , j ) == game_state . pacman :
CSC14003 | Project 01: Search 8
Introduction to Artificial Intelligence
6 pygame . draw . rect ( screen , YELLOW , pygame . Rect ( j * cell_size , i *
cell_size , cell_size , cell_size ) )
7 elif (i , j ) in game_state . monsters :
8 pygame . draw . rect ( screen , RED , pygame . Rect ( j * cell_size , i *
cell_size , cell_size , cell_size ) )
9 elif (i , j ) in game_state . food :
10 pygame . draw . circle ( screen , GREEN , ( j * cell_size + cell_size // 2 , i
* cell_size + cell_size // 2) , 10)
11
12 for i in range ( game_state . size [0]) :
13 for j in range ( game_state . size [1]) :
14 if game_state . matrix [ i ][ j ] == ’1 ’:
15 pygame . draw . rect ( screen , WHITE , pygame . Rect ( j * cell_size , i *
cell_size , cell_size , cell_size ) )
16
17 pygame . display . flip ()
Listing 10: Draw objects function
5.11 Pac-man breadth first search AI function
pacman_ai_bfs() function is the implementation of the BFS algorithm for Pac-man AI. This uses the BFS
function that has been declared in section 5.6.
1 def pacman_ai_bfs ( game_state ) :
2 start = game_state . pacman
3 goal = min ( game_state . food , key = lambda f : manhattan_distance ( start , f ) )
4
5 if not is_valid_position ( game_state . matrix , start ) or not is_valid_position (
game_state . matrix , goal ) :
6 return None
7
8 graph = create_graph ( game_state . matrix )
9
10 path = bfs_search ( game_state . matrix , start , goal )
11 if path and len ( path ) > 1:
12 next_position = path [1]
13 dx , dy = next_position [0] - start [0] , next_position [1] - start [1]
14 if dx == 1:
15 return ’ down ’
16 elif dx == -1:
17 return ’up ’
18 elif dy == 1:
19 return ’ right ’
20 elif dy == -1:
21 return ’ left ’
22 return None
5.12 Pac-man A* AI function
This function is the implementation of the A* algorithm for Pac-man in finding path to the food.
1 def pacman_ai_astar ( game_state ) :
2 start = game_state . pacman
3 goal = min ( game_state . food , key = lambda f : manhattan_distance ( start , f ) )
4
CSC14003 | Project 01: Search 9
Introduction to Artificial Intelligence
5 if not is_valid_position ( game_state . matrix , start ) or not is_valid_position (
game_state . matrix , goal ) :
6 return None
7
8 graph = create_graph ( game_state . matrix )
9
10 path = dijkstra_search ( graph , start , goal )
11 if path and len ( path ) > 1:
12 next_position = path [1]
13 dx , dy = next_position [0] - start [0] , next_position [1] - start [1]
14 if dx == 1:
15 return ’ down ’
16 elif dx == -1:
17 return ’ up ’
18 elif dy == 1:
19 return ’ right ’
20 elif dy == -1:
21 return ’ left ’
22 return None
Listing 11: Pac-man A* AI function
5.13 Monster A* AI function
Implementation of the A* algorithm for monsters’ AI of Pac-man game.
1 def monster_ai_astar ( game_state , monster_pos ) :
2 if game_state . level == LEVEL_2 :
3 return monster_pos
4
5 start = monster_pos
6 goal = game_state . pacman
7 graph = create_graph ( game_state . matrix )
8
9 if goal not in graph :
10 return monster_pos
11
12 path = dijkstra_search ( graph , start , goal )
13
14 if path and len ( path ) > 1:
15 next_pos = path [1]
16 if next_pos not in game_state . monsters :
17 return next_pos
18 return monster_pos
Listing 12: Monster A* AI function
5.14 Create graph function
This function create graph for use in the algorithm.
1 def create_graph ( matrix ) :
2 graph = {}
3 for i in range ( len ( matrix ) ) :
4 for j in range ( len ( matrix [ i ]) ) :
5 if matrix [ i ][ j ] != ’1 ’:
CSC14003 | Project 01: Search 10
Introduction to Artificial Intelligence
6 neighbors = []
7 if i > 0 and matrix [ i - 1][ j ] != ’1 ’:
8 neighbors . append (( i - 1 , j ) )
9 if i < len ( matrix ) - 1 and matrix [ i + 1][ j ] != ’1 ’:
10 neighbors . append (( i + 1 , j ) )
11 if j > 0 and matrix [ i ][ j - 1] != ’1 ’:
12 neighbors . append (( i , j - 1) )
13 if j < len ( matrix [ i ]) - 1 and matrix [ i ][ j + 1] != ’1 ’:
14 neighbors . append (( i , j + 1) )
15 graph [( i , j ) ] = neighbors
16 return graph
Listing 13: Create graph function
5.15 Main function
This is the implementation of the main function.
Player will be given choices of level to run the Pac-man AI. The program will read the file according to
player’s choice, get and store informtaion read from file to GameState object. The program will then initialize
the pygame with the given size read from file and display to the console. The program will start counting
time and until the algorithm has completed. After the game has completed, the program will print the result
including score and time to the screen and wait for user to quit the game.
1 def main () :
2 level = int ( input ( " Choose the level (1 , 2 , 3 , or 4) : " ) )
3 map_file = f " map { level }. txt "
4
5 size , matrix , pacman , monsters , food = read_map ( map_file )
6 game_state = GameState ( size , matrix , pacman , monsters , food , level )
7
8 pygame . init ()
9 screen_width , screen_height = size [1] * 50 , size [0] * 50
10 info_height = 100
11
12 p l a y i n g _ area_surface = pygame . Surface (( screen_width , screen_height ) )
13 info_surface = pygame . Surface (( screen_width , info_height ) )
14
15 screen = pygame . display . set_mode (( screen_width , screen_height + info_height ) )
16 pygame . display . set_caption ( " Pacman Game " )
17 start_time = time . time ()
18
19 clock = pygame . time . Clock ()
20 pa cm an _ai_function = pacman_ai_bfs
21 while not game_state . game_over :
22 for event in pygame . event . get () :
23 if event . type == QUIT :
24 pygame . quit ()
25 sys . exit ()
26
27 move = pacman_ai_function ( game_state )
28
29 if move in get_valid_moves ( game_state ) :
30 make_move ( game_state , move )
31
CSC14003 | Project 01: Search 11
Introduction to Artificial Intelligence
32 for i , monster in enumerate ( game_state . monsters ) :
33 move = monster_ai_astar ( game_state , monster )
34 if move and is_valid_position ( game_state . matrix , move ) and move not in
game_state . monsters :
35 game_state . monsters [ i ] = move
36
37 elapsed_time = time . time () - start_time
38
39 p l a y ing_area_surface . fill ( BLACK )
40 draw_objects ( playing_area_surface , game_state )
41
42 info_surface . fill ( BLACK )
43 draw_info ( info_surface , game_state , elapsed_time )
44
45 screen . blit ( playing_area_surface , (0 , 0) )
46 screen . blit ( info_surface , (0 , screen_height ) )
47
48 pygame . display . flip ()
49 clock . tick (10)
50
51
52 print ( " Game Over . Your Score : " , game_state . score , " Time taken : " , elapsed_time , "
seconds " )
53
54 while True :
55 for event in pygame . event . get () :
56 if event . type == QUIT :
57 pygame . quit ()
58 sys . exit ()
Listing 14: Main function
5.16 Other functions
5.16.1 Check for valid move function
This function check for valid move before Pac-man or ghosts can move.
1 def is_v alid_position ( matrix , position ) :
2 x , y = position
3 if 0 <= x < len ( matrix ) and 0 <= y < len ( matrix [0]) :
4 return matrix [ x ][ y ] != ’1 ’
5 return False
Listing 15: Check valid position function
5.16.2 Check game over function
This function return game state is game over if the game is terminated.
1 def is_t erminal_state ( game_state ) :
2 return game_state . game_over
Listing 16: Check game over function
CSC14003 | Project 01: Search 12
Introduction to Artificial Intelligence
5.16.3 Get game score function
Return the game score.
1 def ev a lu a t e_game_state ( game_state ) :
2 return game_state . score
Listing 17: Get score function
5.16.4 Manhattan distance function
manhattan_distance() return the distance between to points using the Manhattan distance algorithm to
calculate.
1 def m an ha tta n_distance ( pos1 , pos2 ) :
2 return abs ( pos1 [0] - pos2 [0]) + abs ( pos1 [1] - pos2 [1])
Listing 18: Manhattan distance function
6 References
• Pac-man github repository by Deus1223
• How to implement BFS algorithm for Pac-man
• A* algorithm
• Pyagme documentation
CSC14003 | Project 01: Search 13