Assignment 2: Multi-Agent Pac-Man
Minimax, AlphaBeta,
Evaluation.
Introduction
In this assignment, you will design agents for an almost classic version of Pac-Man, which includes a ghost. Along the way, you will implement both minimax and alpha-beta search and try your hand at evaluation function design.
The code base has not changed much from the previous assignment, but please start with a fresh installation, rather than intermingling files from assignment 1. You can, however, use your search.py
and searchAgents.py
in any way you want.
The code for this assignment contains the following files (including this description) and is available as a zip archive.
Key files to read
multiAgents.py |
Where all of your multi-agent search agents will reside. |
pacman.py |
The main file that runs Pac-Man games. This file also describes a Pac-Man GameState type, which you will use extensively in this assignment |
game.py |
The logic behind how the Pac-Man world works. This file describes several supporting types like AgentState, Agent, Direction, and Grid. |
util.py |
Useful data structures for implementing search algorithms. |
Files you can ignore
graphicsDisplay.py |
Graphics for Pac-Man |
graphicsUtils.py |
Support for Pac-Man graphics |
textDisplay.py |
ASCII graphics for Pac-Man |
ghostAgents.py |
Agents to control ghosts |
keyboardAgents.py |
Keyboard interfaces to control Pac-Man |
layout.py |
Code for reading layout files and storing their contents |
What to submit: You will fill in portions of multiAgents.py
during the assignment. You should submit this file with your code and comments. Please do not change or submit the other files in this distribution. Instructions to submit your code on OWL will follow shortly.
Evaluation: Your code will be autograded for technical correctness. Please do not change the names of any provided functions or classes within the code, or you will wreak havoc on the autograder. However, the correctness of your implementation — not the autograder’s judgements — will be the final judge of your score. If necessary, we will review and grade assignments individually to ensure that you receive due credit for your work.
Academic Dishonesty: We will be checking your code against other submissions in the class for logical redundancy. If you copy someone else’s code and submit it with minor changes, we will know. These cheat detectors are quite hard to fool, so please don’t try. We trust you all to submit your own work only; please don’t let us down. If you do, we will pursue the strongest consequences available to us.
Getting Help: You are not alone! If you find yourself stuck on something, contact the course TAs for help. Office hours are there for your support; please use them. If you can’t make our office hours, let us know and we will schedule more. We want these assignments to be rewarding and instructional, not frustrating and demoralizing. But, we don’t know when or how to help unless you ask.
Multi-Agent Pac-Man
Run the provided ReflexAgent
in multiAgents.py
:
python pacman.py -p ReflexAgent -k 1
Note that it often loses and when it wins it doesn’t always get a good score (greater than 0) even on simple layouts:
python pacman.py -p ReflexAgent -l testClassic -k 1
Inspect its code (in multiAgents.py
) and make sure you understand what it’s doing.
Question 1 (20%) Improve the ReflexAgent
in multiAgents.py
to play respectably. The provided reflex agent code provides some helpful examples of methods that query the GameState
for information. A capable reflex agent will have to consider both food locations and ghost locations to perform well. Your agent should easily and reliably clear the testClassic
layout:
python pacman.py -p ReflexAgent -l testClassic -k 1
Try out your reflex agent on the default mediumClassic
layout with one ghost (and animation off to speed up the display):
python pacman.py --frameTime 0 -p ReflexAgent -k 1
How does your agent fare?
Note: As features, try the reciprocal of important values (such as distance to food) rather than just the values themselves.
Note: The evaluation function you’re writing is evaluating state-action pairs; in later parts of the assignment, you’ll be evaluating states.
Options: Default ghosts are random; you can also play for fun with a slightly smarter directional ghost using -g DirectionalGhost
. If the randomness is preventing you from telling whether your agent is improving, you can use -f
to run with a fixed random seed (same random choices every game). You can also play multiple games in a row with -n
. Turn off graphics with -q
to run lots of games quickly.
The autograder will check that your agent can rapidly clear the openClassic
layout ten times without dying more than twice or thrashing around infinitely (i.e. repeatedly moving back and forth between two positions, making no progress).
python pacman.py -p ReflexAgent -l openClassic -k 1 -n 10 -q
Don’t spend too much time on this question, though, as the meat of the assignment lies ahead.
Question 2 (40%) Now you will write an adversarial search agent in the provided MinimaxAgent
class stub in multiAgents.py
. Your minimax agent should work with one ghost.
Your code should also expand the game tree to an arbitrary depth. Score the leaves of your minimax tree with the supplied self.evaluationFunction
, which defaults to scoreEvaluationFunction
.MinimaxAgent
extends MultiAgentAgent
, which gives access to self.depth
and self.evaluationFunction
. Make sure your minimax code makes reference to these two variables where appropriate as these variables are populated in response to command line options.
Important: A single search ply is considered to be one Pac-Man move and the ghost’s response, so depth 2 search will involve Pac-Man and the ghost moving two times.
Hints and Observations
-
- The evaluation function in this part is already written (
self.evaluationFunction
). You shouldn’t change this function, but recognize that now we’re evaluating *states* rather than actions, as we were for the reflex agent. Look-ahead agents evaluate future states whereas reflex agents evaluate actions from the current state.
- The evaluation function in this part is already written (
python pacman.py -p MinimaxAgent -l smallClassic -k 1 -a depth=4
- To increase the search depth achievable by your agent, remove the
Directions.STOP
action from Pac-Man’s list of possible actions. Depth 2, 3, and 4 should be pretty quick, but depth 5 and higher will be slow. Don’t worry, the next question will speed up the search somewhat. - Pac-Man is always agent 0, and the agents move in order of increasing agent index.
- All states in minimax should be
GameStates
, either passed in togetAction
or generated viaGameState.generateSuccessor
.
Question 3 (40%) Make a new agent that uses alpha-beta pruning to more efficiently explore the minimax tree, in AlphaBetaAgent
.
You should see a speed-up (perhaps depth 5 alpha-beta will run as fast as depth 4 minimax). Ideally, depth 5 on smallClassic
should run in just a few seconds per move or faster.
python pacman.py -p AlphaBetaAgent -k 1 -a depth=6 -l smallClassic
The AlphaBetaAgent
minimax values should be identical to the MinimaxAgent
minimax values, although the actions it selects can vary because of different tie-breaking behavior.
Hints and Observations
- As for your reflex agent evaluation function, you may want to use the reciprocal of important values (such as distance to food) rather than the values themselves.
- One way you might want to write your evaluation function is to use a linear combination of features. That is, compute values for features about the state that you think are important, and then combine those features by multiplying them by different values and adding the results together. You might decide what to multiply each feature by based on how important you think it is.
Assignment 2 is done. Go Pac-Man!