├── README.md ├── finalcontest ├── autograder.py ├── capture.py ├── captureAgents.py ├── captureGraphicsDisplay.py ├── distanceCalculator.py ├── game.py ├── graphicsDisplay.py ├── graphicsUtils.py ├── keyboardAgents.py ├── mazeGenerator.py ├── myAgent.py ├── oneGhostTeam.py ├── pacman.py ├── staffBot.py ├── team.py ├── team_self.py ├── textDisplay.py └── util.py ├── hw ├── hw1.pdf ├── hw2.pdf ├── hw3.pdf ├── hw4.pdf └── hw5.pdf ├── minicontest1 ├── autograder.py ├── game.py ├── graphicsDisplay.py ├── graphicsUtils.py ├── layout.py ├── mazeGenerator.py ├── myAgents.py ├── pacman.py ├── search.py ├── searchProblems.py ├── textDisplay.py └── util.py ├── minicontest2 ├── baselineTeam.py ├── capture.py ├── captureAgents.py ├── captureGraphicsDisplay.py ├── distanceCalculator.py ├── features.py ├── game.py ├── graphicsDisplay.py ├── graphicsUtils.py ├── keyboardAgents.py ├── layout.py ├── mazeGenerator.py ├── myTeam.py ├── score ├── tags ├── textDisplay.py ├── unpack.py └── util.py ├── p0-tutorial ├── addition.py ├── autograder.py ├── buyLotsOfFruit.py ├── grading.py ├── projectParams.py ├── shop.py ├── shopAroundTown.py ├── shopSmart.py ├── testClasses.py ├── testParser.py ├── test_cases │ ├── CONFIG │ ├── q1 │ │ └── CONFIG │ ├── q2 │ │ └── CONFIG │ └── q3 │ │ └── CONFIG ├── textDisplay.py ├── town.py ├── tutorialTestClasses.py └── util.py ├── p1-search ├── VERSION ├── autograder.py ├── eightpuzzle.py ├── game.py ├── ghostAgents.py ├── grading.py ├── graphicsDisplay.py ├── graphicsUtils.py ├── keyboardAgents.py ├── layout.py ├── pacman.py ├── pacmanAgents.py ├── projectParams.py ├── search.py ├── searchAgents.py ├── searchTestClasses.py ├── submission_autograder.py ├── testClasses.py ├── testParser.py ├── test_cases │ ├── CONFIG │ ├── q1 │ │ └── CONFIG │ ├── q2 │ │ └── CONFIG │ ├── q3 │ │ └── CONFIG │ ├── q4 │ │ └── CONFIG │ ├── q5 │ │ └── CONFIG │ ├── q6 │ │ └── CONFIG │ ├── q7 │ │ └── CONFIG │ └── q8 │ │ └── CONFIG ├── textDisplay.py └── util.py ├── p2-multiagent ├── VERSION ├── autograder.py ├── game.py ├── ghostAgents.py ├── grading.py ├── graphicsDisplay.py ├── graphicsUtils.py ├── keyboardAgents.py ├── layout.py ├── layouts │ ├── capsuleClassic.lay │ ├── contestClassic.lay │ ├── mediumClassic.lay │ ├── minimaxClassic.lay │ ├── openClassic.lay │ ├── originalClassic.lay │ ├── powerClassic.lay │ ├── smallClassic.lay │ ├── testClassic.lay │ ├── trappedClassic.lay │ └── trickyClassic.lay ├── multiAgents.py ├── multiagentTestClasses.py ├── pacman.py ├── pacmanAgents.py ├── projectParams.py ├── submission_autograder.py ├── testClasses.py ├── testParser.py ├── test_cases │ ├── CONFIG │ ├── extra │ │ └── CONFIG │ ├── q1 │ │ └── CONFIG │ ├── q2 │ │ └── CONFIG │ ├── q3 │ │ └── CONFIG │ ├── q4 │ │ └── CONFIG │ └── q5 │ │ └── CONFIG ├── textDisplay.py └── util.py ├── p3-rl ├── VERSION ├── analysis.py ├── autograder.py ├── crawler.py ├── environment.py ├── featureExtractors.py ├── game.py ├── ghostAgents.py ├── grading.py ├── graphicsCrawlerDisplay.py ├── graphicsDisplay.py ├── graphicsGridworldDisplay.py ├── graphicsUtils.py ├── gridworld.py ├── keyboardAgents.py ├── layout.py ├── learningAgents.py ├── mdp.py ├── pacman.py ├── pacmanAgents.py ├── projectParams.py ├── qlearningAgents.py ├── reinforcementTestClasses.py ├── submission_autograder.py ├── testClasses.py ├── testParser.py ├── test_cases │ ├── CONFIG │ ├── q1 │ │ └── CONFIG │ ├── q10 │ │ └── CONFIG │ ├── q2 │ │ └── CONFIG │ ├── q3 │ │ └── CONFIG │ ├── q4 │ │ └── CONFIG │ ├── q5 │ │ └── CONFIG │ ├── q6 │ │ └── CONFIG │ ├── q7 │ │ └── CONFIG │ ├── q8 │ │ └── CONFIG │ └── q9 │ │ └── CONFIG ├── textDisplay.py ├── textGridworldDisplay.py ├── util.py └── valueIterationAgents.py ├── p4-tracking ├── VERSION ├── autograder.py ├── busters.py ├── bustersAgents.py ├── bustersGhostAgents.py ├── distanceCalculator.py ├── game.py ├── ghostAgents.py ├── grading.py ├── graphicsDisplay.py ├── graphicsUtils.py ├── inference.py ├── keyboardAgents.py ├── layout.py ├── pacman.py ├── projectParams.py ├── submission_autograder.py ├── testClasses.py ├── testParser.py ├── test_cases │ ├── CONFIG │ ├── q1 │ │ └── CONFIG │ ├── q10 │ │ └── CONFIG │ ├── q2 │ │ └── CONFIG │ ├── q3 │ │ └── CONFIG │ ├── q4 │ │ └── CONFIG │ ├── q5 │ │ └── CONFIG │ ├── q6 │ │ └── CONFIG │ ├── q7 │ │ └── CONFIG │ ├── q8 │ │ └── CONFIG │ └── q9 │ │ └── CONFIG ├── textDisplay.py ├── tracking_fa18TestClasses.py └── util.py └── p5-ml ├── autograder.py ├── backend.py ├── models.py ├── nn.py └── submission_autograder.py /README.md: -------------------------------------------------------------------------------- 1 | ### Introduction 2 | This is the repo for CS188 - Introduction to Artificial Intelligence, Spring 19 at UC Berkeley 3 | -------------------------------------------------------------------------------- /finalcontest/distanceCalculator.py: -------------------------------------------------------------------------------- 1 | # distanceCalculator.py 2 | # --------------------- 3 | # Licensing Information: Please do not distribute or publish solutions to this 4 | # project. You are free to use and extend these projects for educational 5 | # purposes. The Pacman AI projects were developed at UC Berkeley, primarily by 6 | # John DeNero (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 7 | # For more info, see http://inst.eecs.berkeley.edu/~cs188/sp09/pacman.html 8 | 9 | """ 10 | This file contains a Distancer object which computes and 11 | caches the shortest path between any two points in the maze. 12 | 13 | Example: 14 | distancer = Distancer(gameState.data.layout) 15 | distancer.getDistance( (1,1), (10,10) ) 16 | """ 17 | 18 | import sys, time, random 19 | 20 | class Distancer: 21 | def __init__(self, layout, default = 10000): 22 | """ 23 | Initialize with Distancer(layout). Changing default is unnecessary. 24 | """ 25 | self._distances = None 26 | self.default = default 27 | self.dc = DistanceCalculator(layout, self, default) 28 | 29 | def getMazeDistances(self): 30 | self.dc.run() 31 | 32 | def getDistance(self, pos1, pos2): 33 | """ 34 | The getDistance function is the only one you'll need after you create the object. 35 | """ 36 | if self._distances == None: 37 | return manhattanDistance(pos1, pos2) 38 | if isInt(pos1) and isInt(pos2): 39 | return self.getDistanceOnGrid(pos1, pos2) 40 | pos1Grids = getGrids2D(pos1) 41 | pos2Grids = getGrids2D(pos2) 42 | bestDistance = self.default 43 | for pos1Snap, snap1Distance in pos1Grids: 44 | for pos2Snap, snap2Distance in pos2Grids: 45 | gridDistance = self.getDistanceOnGrid(pos1Snap, pos2Snap) 46 | distance = gridDistance + snap1Distance + snap2Distance 47 | if bestDistance > distance: 48 | bestDistance = distance 49 | return bestDistance 50 | 51 | def getDistanceOnGrid(self, pos1, pos2): 52 | key = (pos1, pos2) 53 | if key in self._distances: 54 | return self._distances[key] 55 | else: 56 | raise Exception("Positions not in grid: " + str(key)) 57 | 58 | def isReadyForMazeDistance(self): 59 | return self._distances != None 60 | 61 | def manhattanDistance(x, y ): 62 | return abs( x[0] - y[0] ) + abs( x[1] - y[1] ) 63 | 64 | def isInt(pos): 65 | x, y = pos 66 | return x == int(x) and y == int(y) 67 | 68 | def getGrids2D(pos): 69 | grids = [] 70 | for x, xDistance in getGrids1D(pos[0]): 71 | for y, yDistance in getGrids1D(pos[1]): 72 | grids.append(((x, y), xDistance + yDistance)) 73 | return grids 74 | 75 | def getGrids1D(x): 76 | intX = int(x) 77 | if x == int(x): 78 | return [(x, 0)] 79 | return [(intX, x-intX), (intX+1, intX+1-x)] 80 | 81 | ########################################## 82 | # MACHINERY FOR COMPUTING MAZE DISTANCES # 83 | ########################################## 84 | 85 | distanceMap = {} 86 | 87 | class DistanceCalculator: 88 | def __init__(self, layout, distancer, default = 10000): 89 | self.layout = layout 90 | self.distancer = distancer 91 | self.default = default 92 | 93 | def run(self): 94 | global distanceMap 95 | 96 | if self.layout.walls not in distanceMap: 97 | distances = computeDistances(self.layout) 98 | distanceMap[self.layout.walls] = distances 99 | else: 100 | distances = distanceMap[self.layout.walls] 101 | 102 | self.distancer._distances = distances 103 | 104 | def computeDistances(layout): 105 | "Runs UCS to all other positions from each position" 106 | distances = {} 107 | allNodes = layout.walls.asList(False) 108 | for source in allNodes: 109 | dist = {} 110 | closed = {} 111 | for node in allNodes: 112 | dist[node] = sys.maxsize 113 | import util 114 | queue = util.PriorityQueue() 115 | queue.push(source, 0) 116 | dist[source] = 0 117 | while not queue.isEmpty(): 118 | node = queue.pop() 119 | if node in closed: 120 | continue 121 | closed[node] = True 122 | nodeDist = dist[node] 123 | adjacent = [] 124 | x, y = node 125 | if not layout.isWall((x,y+1)): 126 | adjacent.append((x,y+1)) 127 | if not layout.isWall((x,y-1)): 128 | adjacent.append((x,y-1) ) 129 | if not layout.isWall((x+1,y)): 130 | adjacent.append((x+1,y) ) 131 | if not layout.isWall((x-1,y)): 132 | adjacent.append((x-1,y)) 133 | for other in adjacent: 134 | if not other in dist: 135 | continue 136 | oldDist = dist[other] 137 | newDist = nodeDist+1 138 | if newDist < oldDist: 139 | dist[other] = newDist 140 | queue.push(other, newDist) 141 | for target in allNodes: 142 | distances[(target, source)] = dist[target] 143 | return distances 144 | 145 | 146 | def getDistanceOnGrid(distances, pos1, pos2): 147 | key = (pos1, pos2) 148 | if key in distances: 149 | return distances[key] 150 | return 100000 151 | 152 | -------------------------------------------------------------------------------- /finalcontest/keyboardAgents.py: -------------------------------------------------------------------------------- 1 | # keyboardAgents.py 2 | # ----------------- 3 | # Licensing Information: Please do not distribute or publish solutions to this 4 | # project. You are free to use and extend these projects for educational 5 | # purposes. The Pacman AI projects were developed at UC Berkeley, primarily by 6 | # John DeNero (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 7 | # For more info, see http://inst.eecs.berkeley.edu/~cs188/sp09/pacman.html 8 | 9 | from game import Agent 10 | from game import Directions 11 | import time 12 | import random 13 | 14 | class KeyboardAgent(Agent): 15 | """ 16 | An agent controlled by the keyboard. 17 | """ 18 | # NOTE: Arrow keys also work. 19 | WEST_KEY = 'a' 20 | EAST_KEY = 'd' 21 | NORTH_KEY = 'w' 22 | SOUTH_KEY = 's' 23 | STOP_KEY = 'q' 24 | 25 | def __init__( self, index = 0 ): 26 | 27 | self.lastMove = Directions.STOP 28 | self.index = index 29 | self.keys = [] 30 | 31 | def getAction( self, state): 32 | from graphicsUtils import keys_waiting 33 | from graphicsUtils import keys_pressed 34 | # keys = keys_waiting() + keys_pressed() 35 | # if keys != []: 36 | # self.keys = keys 37 | while self.keys == []: 38 | self.keys = keys_pressed() 39 | 40 | legal = state.getLegalActions(self.index) 41 | move = self.getMove(legal) 42 | self.keys = [] 43 | 44 | if move == Directions.STOP: 45 | # Try to move in the same direction as before 46 | if self.lastMove in legal: 47 | move = self.lastMove 48 | 49 | if (self.STOP_KEY in self.keys) and Directions.STOP in legal: move = Directions.STOP 50 | 51 | if move not in legal: 52 | move = random.choice(legal) 53 | 54 | self.lastMove = move 55 | time.sleep(0.2) 56 | return move 57 | 58 | def getMove(self, legal): 59 | move = Directions.STOP 60 | if (self.WEST_KEY in self.keys or 'Left' in self.keys) and Directions.WEST in legal: move = Directions.WEST 61 | if (self.EAST_KEY in self.keys or 'Right' in self.keys) and Directions.EAST in legal: move = Directions.EAST 62 | if (self.NORTH_KEY in self.keys or 'Up' in self.keys) and Directions.NORTH in legal: move = Directions.NORTH 63 | if (self.SOUTH_KEY in self.keys or 'Down' in self.keys) and Directions.SOUTH in legal: move = Directions.SOUTH 64 | return move 65 | 66 | def processBroadcast(self, gameState, broadcast): 67 | pass 68 | 69 | def getTeam(self, index): 70 | return [] 71 | 72 | class KeyboardAgent2(KeyboardAgent): 73 | """ 74 | A second agent controlled by the keyboard. 75 | """ 76 | # NOTE: Arrow keys also work. 77 | WEST_KEY = 'j' 78 | EAST_KEY = "l" 79 | NORTH_KEY = 'i' 80 | SOUTH_KEY = 'k' 81 | STOP_KEY = 'u' 82 | 83 | def getMove(self, legal): 84 | move = Directions.STOP 85 | if (self.WEST_KEY in self.keys) and Directions.WEST in legal: move = Directions.WEST 86 | if (self.EAST_KEY in self.keys) and Directions.EAST in legal: move = Directions.EAST 87 | if (self.NORTH_KEY in self.keys) and Directions.NORTH in legal: move = Directions.NORTH 88 | if (self.SOUTH_KEY in self.keys) and Directions.SOUTH in legal: move = Directions.SOUTH 89 | return move 90 | -------------------------------------------------------------------------------- /finalcontest/oneGhostTeam.py: -------------------------------------------------------------------------------- 1 | # baselineTeam.py 2 | # --------------- 3 | # Licensing Information: Please do not distribute or publish solutions to this 4 | # project. You are free to use and extend these projects for educational 5 | # purposes. The Pacman AI projects were developed at UC Berkeley, primarily by 6 | # John DeNero (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 7 | # For more info, see http://inst.eecs.berkeley.edu/~cs188/sp09/pacman.html 8 | 9 | from captureAgents import CaptureAgent 10 | import distanceCalculator 11 | import random, time, util, sys 12 | from game import Directions 13 | import game 14 | from util import nearestPoint 15 | 16 | ################# 17 | # Team creation # 18 | ################# 19 | 20 | RANDOM_ACTION_PROB = 0.4 21 | 22 | def createTeam(firstIndex, secondIndex, isPacman, 23 | first = 'GhostReflexAgent', second = None, numTraining=0): 24 | """ 25 | This function should return a list of two agents that will form the 26 | team, initialized using firstIndex and secondIndex as their agent 27 | index numbers. isPacman is True if the pacman team is being created, and 28 | will be False if the ghost team is being created. 29 | 30 | As a potentially helpful development aid, this function can take 31 | additional string-valued keyword arguments ("first" and "second" are 32 | such arguments in the case of this function), which will come from 33 | the --pacmanOpts and --ghostOpts command-line arguments to capture.py. 34 | For the nightly contest, however, your team will be created without 35 | any extra arguments, so you should make sure that the default 36 | behavior is what you want for the nightly contest. 37 | """ 38 | return [eval(first)(firstIndex)] 39 | 40 | ########## 41 | # Agents # 42 | ########## 43 | 44 | class GhostReflexAgent(CaptureAgent): 45 | """ 46 | A reflex agent that keeps its side Pacman-free. Again, 47 | this is to give you an idea of what a defensive agent 48 | could be like. It is not the best or only way to make 49 | such an agent. 50 | """ 51 | 52 | def registerInitialState(self, gameState): 53 | self.start = gameState.getAgentPosition(self.index) 54 | CaptureAgent.registerInitialState(self, gameState) 55 | 56 | def chooseAction(self, gameState): 57 | """ 58 | Picks among the actions with the highest Q(s,a). 59 | """ 60 | actions = gameState.getLegalActions(self.index) 61 | 62 | if random.random() < RANDOM_ACTION_PROB: 63 | if Directions.STOP in actions: 64 | actions.remove(Directions.STOP) 65 | 66 | # Code to stop pacman from turning around during search 67 | reverse = Directions.REVERSE[gameState.getAgentState(self.index).configuration.direction] 68 | if len (actions) > 1 and reverse in actions: 69 | actions.remove(reverse) 70 | return random.choice(actions) 71 | 72 | # You can profile your evaluation time by uncommenting these lines 73 | # start = time.time() 74 | values = [self.evaluate(gameState, a) for a in actions] 75 | # print 'eval time for agent %d: %.4f' % (self.index, time.time() - start) 76 | 77 | maxValue = max(values) 78 | bestActions = [a for a, v in zip(actions, values) if v == maxValue] 79 | return random.choice(bestActions) 80 | 81 | def getFeatures(self, gameState, action): 82 | features = util.Counter() 83 | successor = self.getSuccessor(gameState, action) 84 | successorScore = self.getScore(successor) 85 | features['successorScore'] = successorScore 86 | 87 | myState = successor.getAgentState(self.index) 88 | myPos = myState.getPosition() 89 | 90 | # Computes distance to invaders we can see 91 | enemies = [successor.getAgentState(i) for i in self.getOpponents(successor)] 92 | invaders = [a for a in enemies if a.isPacman and a.getPosition() != None] 93 | if len(invaders) > 0: 94 | dists = [self.getMazeDistance(myPos, a.getPosition()) for a in invaders] 95 | features['invaderDistance'] = min(dists) 96 | 97 | if action == Directions.STOP: features['stop'] = 1 98 | rev = Directions.REVERSE[gameState.getAgentState(self.index).configuration.direction] 99 | if action == rev: features['reverse'] = 1 100 | 101 | isSafeZone = max(12 - successor.getAgentPosition(self.index)[0], 0) 102 | features['safeZone'] = isSafeZone 103 | 104 | return features 105 | 106 | def getWeights(self, gameState, action): 107 | return {'successorScore': 10000, 'invaderDistance': -1, 'stop': -100, 'reverse': 0, 'safeZone':-100000000} 108 | 109 | def evaluate(self, gameState, action): 110 | """ 111 | Computes a linear combination of features and feature weights 112 | """ 113 | features = self.getFeatures(gameState, action) 114 | weights = self.getWeights(gameState, action) 115 | return features * weights 116 | 117 | def getSuccessor(self, gameState, action): 118 | """ 119 | Finds the next successor which is a grid position (location tuple). 120 | """ 121 | successor = gameState.generateSuccessor(self.index, action) 122 | pos = successor.getAgentState(self.index).getPosition() 123 | if pos != nearestPoint(pos): 124 | # Only half a grid position was covered 125 | return successor.generateSuccessor(self.index, action) 126 | else: 127 | return successor -------------------------------------------------------------------------------- /finalcontest/staffBot.py: -------------------------------------------------------------------------------- 1 | # staffBot.py 2 | # --------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | # This file was based on the starter code for student bots, and edited 14 | # by Mesut (Xiaocheng) Yang and Roshan Rao 15 | 16 | 17 | from captureAgents import CaptureAgent 18 | from game import Directions 19 | 20 | ######### 21 | # Agent # 22 | ######### 23 | 24 | 25 | class SimpleStaffBot(CaptureAgent): 26 | """ 27 | A Simple agent to serve as an example of the necessary agent structure. 28 | """ 29 | 30 | def registerInitialState(self, gameState): 31 | """ 32 | This method handles the initial setup of the 33 | agent to populate useful fields (such as what team 34 | we're on). 35 | 36 | A distanceCalculator instance caches the maze distances 37 | between each pair of positions, so your agents can use: 38 | self.distancer.getDistance(p1, p2) 39 | 40 | IMPORTANT: This method may run for at most 15 seconds. 41 | """ 42 | 43 | # Make sure you do not delete the following line. 44 | # If you would like to use Manhattan distances instead 45 | # of maze distances in order to save on initialization 46 | # time, please take a look at: 47 | # CaptureAgent.registerInitialState in captureAgents.py. 48 | CaptureAgent.registerInitialState(self, gameState) 49 | self.start = gameState.getAgentPosition(self.index) 50 | self.weights = [1, 1, 0, 0] 51 | 52 | def getLimitedActions(self, state, index, remove_reverse=True): 53 | """ 54 | Limit the actions, removing 'Stop', and the reverse action if possible. 55 | """ 56 | actions = state.getLegalActions(index) 57 | actions.remove('Stop') 58 | 59 | if len(actions) > 1 and remove_reverse: 60 | rev = Directions.REVERSE[state.getAgentState(index).configuration.direction] 61 | if rev in actions: 62 | actions.remove(rev) 63 | 64 | return actions 65 | 66 | def chooseAction(self, gameState): 67 | """ 68 | Reflex agent that follows its plan. 69 | """ 70 | 71 | # Follow plan if available and possible 72 | if self.toBroadcast and len(self.toBroadcast) > 0: 73 | action = self.toBroadcast.pop(0) 74 | if action in gameState.getLegalActions(self.index): 75 | ghosts = [gameState.getAgentPosition(ghost) for ghost in gameState.getGhostTeamIndices()] 76 | 77 | pacman = gameState.getAgentPosition(self.index) 78 | closestGhost = min(self.distancer.getDistance(pacman, ghost) for ghost in ghosts) \ 79 | if len(ghosts) > 0 else 1.0 80 | # If the ghost is nearby, replan 81 | if closestGhost >= 10: 82 | return action 83 | 84 | # use actionHelper to pick an action 85 | currentAction = self.actionHelper(gameState) 86 | futureActions = self.generatePlan(gameState.generateSuccessor(self.index, currentAction), 3) 87 | 88 | self.toBroadcast = futureActions 89 | return currentAction 90 | 91 | def actionHelper(self, state): 92 | actions = self.getLimitedActions(state, self.index) 93 | 94 | val = float('-inf') 95 | best = None 96 | for action in actions: 97 | new_state = state.generateSuccessor(self.index, action) 98 | new_state_val = self.evaluationFunction(new_state) 99 | 100 | if new_state_val > val: 101 | val = new_state_val 102 | best = action 103 | 104 | return best 105 | 106 | def evaluationFunction(self, state): 107 | foods = state.getFood().asList() 108 | ghosts = [state.getAgentPosition(ghost) for ghost in state.getGhostTeamIndices()] 109 | friends = [state.getAgentPosition(pacman) for pacman in state.getPacmanTeamIndices() if pacman != self.index] 110 | 111 | pacman = state.getAgentPosition(self.index) 112 | 113 | closestFood = min(self.distancer.getDistance(pacman, food) for food in foods) + 2.0 \ 114 | if len(foods) > 0 else 1.0 115 | closestGhost = min(self.distancer.getDistance(pacman, ghost) for ghost in ghosts) + 1.0 \ 116 | if len(ghosts) > 0 else 1.0 117 | closestFriend = min(self.distancer.getDistance(pacman, friend) for friend in friends) + 1.0 \ 118 | if len(friends) > 0 else 1.0 119 | 120 | closestFoodReward = 1.0 / closestFood 121 | closestGhostPenalty = 1.0 / (closestGhost ** 2) if closestGhost < 20 else 0 122 | closestFriendPenalty = 1.0 / (closestFriend ** 2) if closestFriend < 5 else 0 123 | 124 | numFood = len(foods) 125 | 126 | features = [-numFood, closestFoodReward, closestGhostPenalty, closestFriendPenalty] 127 | 128 | value = sum(feature * weight for feature, weight in zip(features, self.weights)) 129 | return value 130 | 131 | def generatePlan(self, state, plan_length): 132 | plan = [] 133 | other_index = state.getPacmanTeamIndices() 134 | other_index.remove(self.index) 135 | other_index = other_index[0] 136 | for i in range(plan_length): 137 | # If agent doesn't get a broadcast or the broadcasted move is illegal, ignore the move 138 | if self.receivedBroadcast and len(self.receivedBroadcast) > i: 139 | action = self.receivedBroadcast[i] 140 | if action in state.getLegalActions(other_index): 141 | state = state.generateSuccessor(other_index, action) 142 | else: 143 | # NOTE: If you're worried about potentially broadcasting illegal actions, uncomment this line. 144 | # You should only broadcast an illegal action around the time your agent dies (because the death is unexpected). 145 | # In all other circumstances, your broadcasted actions should be legal. 146 | 147 | print('You broadcasted an illegal action!') 148 | pass 149 | 150 | action = self.actionHelper(state) 151 | plan.append(action) 152 | state = state.generateSuccessor(self.index, action) 153 | return plan 154 | -------------------------------------------------------------------------------- /finalcontest/team.py: -------------------------------------------------------------------------------- 1 | # team.py 2 | # --------------- 3 | # Licensing Information: Please do not distribute or publish solutions to this 4 | # project. You are free to use and extend these projects for educational 5 | # purposes. The Pacman AI projects were developed at UC Berkeley, primarily by 6 | # John DeNero (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 7 | # For more info, see http://inst.eecs.berkeley.edu/~cs188/sp09/pacman.html 8 | 9 | from captureAgents import CaptureAgent 10 | from staffBot import SimpleStaffBot 11 | from myAgent import MyAgent 12 | import distanceCalculator 13 | import random, time, util, sys 14 | from game import Directions 15 | import game 16 | from util import nearestPoint 17 | 18 | ################# 19 | # Team creation # 20 | ################# 21 | 22 | def createTeam(firstIndex, secondIndex, isPacman, 23 | first='SimpleStaffBot', second='MyAgent', numTraining=0): 24 | """ 25 | This function should return a list of two agents that will form the 26 | team, initialized using firstIndex and secondIndex as their agent 27 | index numbers. isPacman is True if the pacman team is being created, and 28 | will be False if the ghost team is being created. 29 | 30 | As a potentially helpful development aid, this function can take 31 | additional string-valued keyword arguments ("first" and "second" are 32 | such arguments in the case of this function), which will come from 33 | the --pacmanOpts and --ghostOpts command-line arguments to capture.py. 34 | For the nightly contest, however, your team will be created without 35 | any extra arguments, so you should make sure that the default 36 | behavior is what you want for the nightly contest. 37 | """ 38 | return [eval(first)(firstIndex), eval(second)(secondIndex)] 39 | -------------------------------------------------------------------------------- /finalcontest/team_self.py: -------------------------------------------------------------------------------- 1 | # team.py 2 | # --------------- 3 | # Licensing Information: Please do not distribute or publish solutions to this 4 | # project. You are free to use and extend these projects for educational 5 | # purposes. The Pacman AI projects were developed at UC Berkeley, primarily by 6 | # John DeNero (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 7 | # For more info, see http://inst.eecs.berkeley.edu/~cs188/sp09/pacman.html 8 | 9 | from captureAgents import CaptureAgent 10 | from staffBot import SimpleStaffBot 11 | from myAgent import MyAgent 12 | import distanceCalculator 13 | import random, time, util, sys 14 | from game import Directions 15 | import game 16 | from util import nearestPoint 17 | 18 | ################# 19 | # Team creation # 20 | ################# 21 | 22 | def createTeam(firstIndex, secondIndex, isPacman, 23 | first='MyAgent', second='MyAgent', numTraining=0): 24 | """ 25 | This function should return a list of two agents that will form the 26 | team, initialized using firstIndex and secondIndex as their agent 27 | index numbers. isPacman is True if the pacman team is being created, and 28 | will be False if the ghost team is being created. 29 | 30 | As a potentially helpful development aid, this function can take 31 | additional string-valued keyword arguments ("first" and "second" are 32 | such arguments in the case of this function), which will come from 33 | the --pacmanOpts and --ghostOpts command-line arguments to capture.py. 34 | For the nightly contest, however, your team will be created without 35 | any extra arguments, so you should make sure that the default 36 | behavior is what you want for the nightly contest. 37 | """ 38 | return [eval(first)(firstIndex), eval(second)(secondIndex)] 39 | -------------------------------------------------------------------------------- /finalcontest/textDisplay.py: -------------------------------------------------------------------------------- 1 | # textDisplay.py 2 | # -------------- 3 | # Licensing Information: Please do not distribute or publish solutions to this 4 | # project. You are free to use and extend these projects for educational 5 | # purposes. The Pacman AI projects were developed at UC Berkeley, primarily by 6 | # John DeNero (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 7 | # For more info, see http://inst.eecs.berkeley.edu/~cs188/sp09/pacman.html 8 | 9 | import pacman, time 10 | 11 | DRAW_EVERY = 1 12 | SLEEP_TIME = 0 # This can be overwritten by __init__ 13 | DISPLAY_MOVES = False 14 | QUIET = False # Supresses output 15 | 16 | class NullGraphics: 17 | def initialize(self, state, isGhost = False): 18 | pass 19 | 20 | def update(self, state): 21 | pass 22 | 23 | def pause(self): 24 | time.sleep(SLEEP_TIME) 25 | 26 | def draw(self, state): 27 | print(state) 28 | 29 | def finish(self): 30 | pass 31 | 32 | class PacmanGraphics: 33 | def __init__(self, speed=None): 34 | if speed != None: 35 | global SLEEP_TIME 36 | SLEEP_TIME = speed 37 | 38 | def initialize(self, state, isGhost = False): 39 | self.draw(state) 40 | self.pause() 41 | self.turn = 0 42 | self.agentCounter = 0 43 | 44 | def update(self, state): 45 | numAgents = len(state.agentStates) 46 | self.agentCounter = (self.agentCounter + 1) % numAgents 47 | if self.agentCounter == 0: 48 | self.turn += 1 49 | if DISPLAY_MOVES: 50 | ghosts = [pacman.nearestPoint(state.getGhostPosition(i)) for i in range(1, numAgents)] 51 | print("%4d) P: %-8s" % (self.turn, str(pacman.nearestPoint(state.getPacmanPosition()))),'| Score: %-5d' % state.score,'| Ghosts:', ghosts) 52 | if self.turn % DRAW_EVERY == 0: 53 | self.draw(state) 54 | self.pause() 55 | if state._isOver: 56 | self.draw(state) 57 | 58 | def pause(self): 59 | time.sleep(SLEEP_TIME) 60 | 61 | def draw(self, state): 62 | print(state) 63 | 64 | def finish(self): 65 | pass 66 | -------------------------------------------------------------------------------- /hw/hw1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiming-xu/CS188/693550fd5f68e22339c6282c5b9251f680a2fc95/hw/hw1.pdf -------------------------------------------------------------------------------- /hw/hw2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiming-xu/CS188/693550fd5f68e22339c6282c5b9251f680a2fc95/hw/hw2.pdf -------------------------------------------------------------------------------- /hw/hw3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiming-xu/CS188/693550fd5f68e22339c6282c5b9251f680a2fc95/hw/hw3.pdf -------------------------------------------------------------------------------- /hw/hw4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiming-xu/CS188/693550fd5f68e22339c6282c5b9251f680a2fc95/hw/hw4.pdf -------------------------------------------------------------------------------- /hw/hw5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiming-xu/CS188/693550fd5f68e22339c6282c5b9251f680a2fc95/hw/hw5.pdf -------------------------------------------------------------------------------- /minicontest1/autograder.py: -------------------------------------------------------------------------------- 1 | import json 2 | import argparse 3 | import glob 4 | 5 | import pacman 6 | 7 | 8 | # each evaluation case is a 3-tuple of 9 | # 1. layout (-l in pacman.py) 10 | # 2. agent number (-s in pacman.py) 11 | # 3. weight (used for weight averaging the scores) 12 | # evaluation_cases = [ 13 | # # TODO specify the evaluation cases and their score weights 14 | # ('mediumMaze', 2, 1., 0.1), 15 | # ('mediumMaze', 2, 1., 0.2), 16 | # ('mediumMaze', 2, 1., 0.3), 17 | # ('mediumMaze', 4, 1., 0.1), 18 | # ('mediumMaze', 4, 1., 0.2), 19 | # ('mediumMaze', 4, 1., 0.3), 20 | # ('bigMaze', 4, 1., 0.2), 21 | # ('bigMaze', 4, 1., 0.3), 22 | # ('mediumCorners', 3, 1., 0.2), 23 | # ('tinyMaze', 4, 1., 0), 24 | # ('mediumCorners', 4, 1., 0), 25 | # ('mediumMaze', 1, 1., 0) 26 | # ] 27 | 28 | 29 | def get_test_cases(): 30 | tests = glob.glob('layouts/*.lay') 31 | return [(t, 1.) for i, t in enumerate(tests)] # TODO add weighted? 32 | 33 | evaluation_cases = get_test_cases() 34 | 35 | def main(pacman_agent): 36 | total_scores = 0. 37 | total_weight = 0. 38 | for n_case, case in enumerate(evaluation_cases): 39 | print('running game {} / {}, {}'.format(n_case+1, len(evaluation_cases), case[0])) 40 | layout, score_weight = case 41 | 42 | # Run the pacman game and get its score 43 | pacman_cmd = 'python pacman.py --pacman {} -l {} -q' 44 | pacman_cmd_args = pacman_cmd.format(pacman_agent, layout) 45 | # skip 'python pacman.py' in the command line arguments above 46 | args = pacman.readCommand(pacman_cmd_args.split()[2:]) 47 | games = pacman.runGames(**args) 48 | # Take the average of the game scores. Note that there should be only 49 | # one game in games, unless `-n` is used in pacman.py 50 | scores = [game.state.getScore() for game in games] 51 | game_score = sum(scores) / len(scores) 52 | 53 | total_scores += game_score * score_weight 54 | total_weight += score_weight 55 | 56 | final_score = total_scores / total_weight 57 | print("Final score: ", final_score) 58 | 59 | # Generate results.json 60 | # score_fields = {} 61 | # score_fields['score'] = final_score 62 | # score_fields['visibility'] = 'visible' 63 | # score_fields['leaderboard'] = [{"name": "Score", "value": final_score}] 64 | # score_fields['output'] = 'successfully run {} games!'.format( 65 | # len(evaluation_cases)) 66 | # write_output(score_fields) 67 | 68 | 69 | def write_output(score_fields): 70 | with open('/autograder/results/results.json', 'w') as output_file: 71 | json.dump(score_fields, output_file) 72 | 73 | 74 | if __name__ == '__main__': 75 | parser = argparse.ArgumentParser() 76 | parser.add_argument('--pacman', default='myAgents.py') 77 | args = parser.parse_args() 78 | main(args.pacman) 79 | -------------------------------------------------------------------------------- /minicontest1/myAgents.py: -------------------------------------------------------------------------------- 1 | # myAgents.py 2 | # --------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | from game import Agent 15 | from searchProblems import PositionSearchProblem 16 | 17 | import util 18 | import time 19 | import search 20 | 21 | """ 22 | IMPORTANT 23 | `agent` defines which agent you will use. By default, it is set to ClosestDotAgent, 24 | but when you're ready to test your own agent, replace it with MyAgent 25 | """ 26 | def createAgents(num_pacmen, agent='MyAgent'): 27 | return [eval(agent)(index=i) for i in range(num_pacmen)] 28 | 29 | opt= [] 30 | target = [] 31 | 32 | class MyAgent(Agent): 33 | """ 34 | Implementation of your agent. 35 | """ 36 | def getAction(self, state): 37 | """ 38 | Returns the next action the agent will take 39 | """ 40 | 41 | "*** YOUR CODE HERE ***" 42 | global opt, target 43 | startPosition = state.getPacmanPosition(self.index) 44 | food = state.getFood() 45 | problem = AnyFoodSearchProblem(state, self.index) 46 | index = self.index 47 | target_i, target_j = target[index] 48 | "*** YOUR CODE HERE ***" 49 | flag = 0 50 | if food[target_i][target_j] is False or\ 51 | (target_i, target_j)== (-1, -1) or len(opt[index])<=1: 52 | for i in range(food.width): 53 | for j in range(food.height): 54 | if food[i][j]: 55 | path = search.bfs(problem) 56 | opt[index] = path 57 | target[index] = (i, j) 58 | cost = len(path) 59 | count = 0 60 | for i in range(len(target)): 61 | if target[i] == [i, j]: 62 | count += 1 63 | flag = (count<=1) 64 | if flag: 65 | break 66 | if flag: 67 | break 68 | else: 69 | del(opt[index][0]) 70 | return opt[index][0] 71 | 72 | def initialize(self): 73 | """ 74 | Intialize anything you want to here. This function is called 75 | when the agent is first created. If you don't need to use it, then 76 | leave it blank 77 | """ 78 | 79 | "*** YOUR CODE HERE" 80 | global opt, target 81 | opt=[[1,] for i in range(10)] 82 | target=[[-1, -1] for i in range(10)] 83 | """ 84 | Put any other SearchProblems or search methods below. You may also import classes/methods in 85 | search.py and searchProblems.py. (ClosestDotAgent as an example below) 86 | """ 87 | 88 | 89 | class ClosestDotAgent(Agent): 90 | 91 | def findPathToClosestDot(self, gameState): 92 | """ 93 | Returns a path (a list of actions) to the closest dot, starting from 94 | gameState. 95 | """ 96 | # Here are some useful elements of the startState 97 | startPosition = gameState.getPacmanPosition(self.index) 98 | food = gameState.getFood() 99 | walls = gameState.getWalls() 100 | problem = AnyFoodSearchProblem(gameState, self.index) 101 | 102 | 103 | "*** YOUR CODE HERE ***" 104 | cost = 1000000000 105 | global opt 106 | flag = 0 107 | if len(opt[self.index]) <= 1: 108 | for i in range(food.width): 109 | for j in range(food.height): 110 | if food[i][j]: 111 | path = search.bfs(problem) 112 | if len(path) python pacman.py -p SearchAgent -a fn=depthFirstSearch 22 | 23 | Commands to invoke other search strategies can be found in the project 24 | description. 25 | 26 | Please only change the parts of the file you are asked to. Look for the lines 27 | that say 28 | 29 | "*** YOUR CODE HERE ***" 30 | 31 | The parts you fill in start about 3/4 of the way down. Follow the project 32 | description for details. 33 | 34 | Good luck and happy searching! 35 | """ 36 | 37 | from game import Directions 38 | from game import Agent 39 | from game import Actions 40 | import search 41 | 42 | import util 43 | import time 44 | import random 45 | 46 | class PositionSearchProblem(search.SearchProblem): 47 | """ 48 | A search problem defines the state space, start state, goal test, successor 49 | function and cost function. This search problem can be used to find paths 50 | to a particular point on the pacman board. 51 | 52 | The state space consists of (x,y) positions in a pacman game. 53 | 54 | Note: this search problem is fully specified; you should NOT change it. 55 | """ 56 | 57 | def __init__(self, gameState, agentIndex=None, costFn = lambda x: 1, goal=(1,1), 58 | start=None, warn=True, visualize=True): 59 | """ 60 | Stores the start and goal. 61 | 62 | gameState: A GameState object (pacman.py) 63 | costFn: A function from a search state (tuple) to a non-negative number 64 | goal: A position in the gameState 65 | """ 66 | self.walls = gameState.getWalls() 67 | if start != None: 68 | self.startState = start 69 | else: 70 | self.startState = gameState.getPacmanPosition(agentIndex) 71 | self.agentIndex = agentIndex 72 | self.goal = goal 73 | self.costFn = costFn 74 | self.visualize = visualize 75 | if warn and (gameState.getNumFood() != 1 or not gameState.hasFood(*goal)): 76 | print('Warning: this does not look like a regular search maze') 77 | 78 | # For display purposes 79 | self._visited, self._visitedlist, self._expanded = {}, [], 0 # DO NOT CHANGE 80 | 81 | def getStartState(self): 82 | return self.startState 83 | 84 | def isGoalState(self, state): 85 | isGoal = state == self.goal 86 | 87 | # For display purposes only 88 | if isGoal and self.visualize: 89 | self._visitedlist.append(state) 90 | import __main__ 91 | if '_display' in dir(__main__): 92 | if 'drawExpandedCells' in dir(__main__._display): #@UndefinedVariable 93 | __main__._display.drawExpandedCells(self._visitedlist) #@UndefinedVariable 94 | 95 | return isGoal 96 | 97 | def getSuccessors(self, state): 98 | """ 99 | Returns successor states, the actions they require, and a cost of 1. 100 | 101 | As noted in search.py: 102 | For a given state, this should return a list of triples, 103 | (successor, action, stepCost), where 'successor' is a 104 | successor to the current state, 'action' is the action 105 | required to get there, and 'stepCost' is the incremental 106 | cost of expanding to that successor 107 | """ 108 | 109 | successors = [] 110 | for action in [Directions.NORTH, Directions.SOUTH, Directions.EAST, Directions.WEST]: 111 | x,y = state 112 | dx, dy = Actions.directionToVector(action) 113 | nextx, nexty = int(x + dx), int(y + dy) 114 | if not self.walls[nextx][nexty]: 115 | nextState = (nextx, nexty) 116 | cost = self.costFn(nextState) 117 | successors.append( ( nextState, action, cost) ) 118 | 119 | # Bookkeeping for display purposes 120 | self._expanded += 1 # DO NOT CHANGE 121 | if state not in self._visited: 122 | self._visited[state] = True 123 | self._visitedlist.append(state) 124 | 125 | return successors 126 | 127 | def getCostOfActions(self, actions): 128 | """ 129 | Returns the cost of a particular sequence of actions. If those actions 130 | include an illegal move, return 999999. 131 | """ 132 | if actions == None: return 999999 133 | x,y= self.getStartState() 134 | cost = 0 135 | for action in actions: 136 | # Check figure out the next state and see whether its' legal 137 | dx, dy = Actions.directionToVector(action) 138 | x, y = int(x + dx), int(y + dy) 139 | if self.walls[x][y]: return 999999 140 | cost += self.costFn((x,y)) 141 | return cost 142 | 143 | def manhattanHeuristic(position, problem, info={}): 144 | "The Manhattan distance heuristic for a PositionSearchProblem" 145 | xy1 = position 146 | xy2 = problem.goal 147 | return abs(xy1[0] - xy2[0]) + abs(xy1[1] - xy2[1]) 148 | 149 | def euclideanHeuristic(position, problem, info={}): 150 | "The Euclidean distance heuristic for a PositionSearchProblem" 151 | xy1 = position 152 | xy2 = problem.goal 153 | return ( (xy1[0] - xy2[0]) ** 2 + (xy1[1] - xy2[1]) ** 2 ) ** 0.5 154 | 155 | def mazeDistance(point1, point2, gameState): 156 | """ 157 | Returns the maze distance between any two points, using the search functions 158 | you have already built. The gameState can be any game state -- Pacman's 159 | position in that state is ignored. 160 | 161 | Example usage: mazeDistance( (2,4), (5,6), gameState) 162 | 163 | This might be a useful helper function for your ApproximateSearchAgent. 164 | """ 165 | x1, y1 = point1 166 | x2, y2 = point2 167 | walls = gameState.getWalls() 168 | assert not walls[x1][y1], 'point1 is a wall: ' + str(point1) 169 | assert not walls[x2][y2], 'point2 is a wall: ' + str(point2) 170 | prob = PositionSearchProblem(gameState, start=point1, goal=point2, warn=False, visualize=False) 171 | return len(search.bfs(prob)) 172 | -------------------------------------------------------------------------------- /minicontest1/textDisplay.py: -------------------------------------------------------------------------------- 1 | # textDisplay.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import time 16 | try: 17 | import pacman 18 | except: 19 | pass 20 | 21 | DRAW_EVERY = 1 22 | SLEEP_TIME = 0 # This can be overwritten by __init__ 23 | DISPLAY_MOVES = False 24 | QUIET = False # Supresses output 25 | 26 | class NullGraphics: 27 | def initialize(self, state, isBlue = False): 28 | pass 29 | 30 | def update(self, state): 31 | pass 32 | 33 | def checkNullDisplay(self): 34 | return True 35 | 36 | def pause(self): 37 | time.sleep(SLEEP_TIME) 38 | 39 | def draw(self, state): 40 | print(state) 41 | 42 | def updateDistributions(self, dist): 43 | pass 44 | 45 | def finish(self): 46 | pass 47 | 48 | class PacmanGraphics: 49 | def __init__(self, speed=None): 50 | if speed != None: 51 | global SLEEP_TIME 52 | SLEEP_TIME = speed 53 | 54 | def initialize(self, state, isBlue = False): 55 | self.draw(state) 56 | self.pause() 57 | self.turn = 0 58 | self.agentCounter = 0 59 | 60 | def update(self, state): 61 | numAgents = len(state.agentStates) 62 | self.agentCounter = (self.agentCounter + 1) % numAgents 63 | if self.agentCounter == 0: 64 | self.turn += 1 65 | if DISPLAY_MOVES: 66 | ghosts = [pacman.nearestPoint(state.getGhostPosition(i)) for i in range(1, numAgents)] 67 | print("%4d) P: %-8s" % (self.turn, str(pacman.nearestPoint(state.getPacmanPosition()))),'| Score: %-5d' % state.score,'| Ghosts:', ghosts) 68 | if self.turn % DRAW_EVERY == 0: 69 | self.draw(state) 70 | self.pause() 71 | if state._win or state._lose: 72 | self.draw(state) 73 | 74 | def pause(self): 75 | time.sleep(SLEEP_TIME) 76 | 77 | def draw(self, state): 78 | print(state) 79 | 80 | def finish(self): 81 | pass 82 | -------------------------------------------------------------------------------- /minicontest2/distanceCalculator.py: -------------------------------------------------------------------------------- 1 | # distanceCalculator.py 2 | # --------------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | """ 16 | This file contains a Distancer object which computes and 17 | caches the shortest path between any two points in the maze. 18 | 19 | Example: 20 | distancer = Distancer(gameState.data.layout) 21 | distancer.getDistance( (1,1), (10,10) ) 22 | """ 23 | 24 | import sys, time, random 25 | 26 | class Distancer: 27 | def __init__(self, layout, default = 10000): 28 | """ 29 | Initialize with Distancer(layout). Changing default is unnecessary. 30 | """ 31 | self._distances = None 32 | self.default = default 33 | self.dc = DistanceCalculator(layout, self, default) 34 | 35 | def getMazeDistances(self): 36 | self.dc.run() 37 | 38 | def getDistance(self, pos1, pos2): 39 | """ 40 | The getDistance function is the only one you'll need after you create the object. 41 | """ 42 | if self._distances == None: 43 | return manhattanDistance(pos1, pos2) 44 | if isInt(pos1) and isInt(pos2): 45 | return self.getDistanceOnGrid(pos1, pos2) 46 | pos1Grids = getGrids2D(pos1) 47 | pos2Grids = getGrids2D(pos2) 48 | bestDistance = self.default 49 | for pos1Snap, snap1Distance in pos1Grids: 50 | for pos2Snap, snap2Distance in pos2Grids: 51 | gridDistance = self.getDistanceOnGrid(pos1Snap, pos2Snap) 52 | distance = gridDistance + snap1Distance + snap2Distance 53 | if bestDistance > distance: 54 | bestDistance = distance 55 | return bestDistance 56 | 57 | def getDistanceOnGrid(self, pos1, pos2): 58 | key = (pos1, pos2) 59 | if key in self._distances: 60 | return self._distances[key] 61 | else: 62 | raise Exception("Positions not in grid: " + str(key)) 63 | 64 | def isReadyForMazeDistance(self): 65 | return self._distances != None 66 | 67 | def manhattanDistance(x, y ): 68 | return abs( x[0] - y[0] ) + abs( x[1] - y[1] ) 69 | 70 | def isInt(pos): 71 | x, y = pos 72 | return x == int(x) and y == int(y) 73 | 74 | def getGrids2D(pos): 75 | grids = [] 76 | for x, xDistance in getGrids1D(pos[0]): 77 | for y, yDistance in getGrids1D(pos[1]): 78 | grids.append(((x, y), xDistance + yDistance)) 79 | return grids 80 | 81 | def getGrids1D(x): 82 | intX = int(x) 83 | if x == int(x): 84 | return [(x, 0)] 85 | return [(intX, x-intX), (intX+1, intX+1-x)] 86 | 87 | ########################################## 88 | # MACHINERY FOR COMPUTING MAZE DISTANCES # 89 | ########################################## 90 | 91 | distanceMap = {} 92 | 93 | class DistanceCalculator: 94 | def __init__(self, layout, distancer, default = 10000): 95 | self.layout = layout 96 | self.distancer = distancer 97 | self.default = default 98 | 99 | def run(self): 100 | global distanceMap 101 | 102 | if self.layout.walls not in distanceMap: 103 | distances = computeDistances(self.layout) 104 | distanceMap[self.layout.walls] = distances 105 | else: 106 | distances = distanceMap[self.layout.walls] 107 | 108 | self.distancer._distances = distances 109 | 110 | def computeDistances(layout): 111 | "Runs UCS to all other positions from each position" 112 | distances = {} 113 | allNodes = layout.walls.asList(False) 114 | for source in allNodes: 115 | dist = {} 116 | closed = {} 117 | for node in allNodes: 118 | dist[node] = sys.maxsize 119 | import util 120 | queue = util.PriorityQueue() 121 | queue.push(source, 0) 122 | dist[source] = 0 123 | while not queue.isEmpty(): 124 | node = queue.pop() 125 | if node in closed: 126 | continue 127 | closed[node] = True 128 | nodeDist = dist[node] 129 | adjacent = [] 130 | x, y = node 131 | if not layout.isWall((x,y+1)): 132 | adjacent.append((x,y+1)) 133 | if not layout.isWall((x,y-1)): 134 | adjacent.append((x,y-1) ) 135 | if not layout.isWall((x+1,y)): 136 | adjacent.append((x+1,y) ) 137 | if not layout.isWall((x-1,y)): 138 | adjacent.append((x-1,y)) 139 | for other in adjacent: 140 | if not other in dist: 141 | continue 142 | oldDist = dist[other] 143 | newDist = nodeDist+1 144 | if newDist < oldDist: 145 | dist[other] = newDist 146 | queue.push(other, newDist) 147 | for target in allNodes: 148 | distances[(target, source)] = dist[target] 149 | return distances 150 | 151 | 152 | def getDistanceOnGrid(distances, pos1, pos2): 153 | key = (pos1, pos2) 154 | if key in distances: 155 | return distances[key] 156 | return 100000 157 | 158 | -------------------------------------------------------------------------------- /minicontest2/features.py: -------------------------------------------------------------------------------- 1 | # for offensive agent 2 | def getFeatures(self, gameState, action): 3 | # return a counter of features for this state 4 | successor = self.getSuccessor(gameState, action) 5 | old_state = self.getPreviousObservation() 6 | eat_food = self.getFood(successor) 7 | food_list = eat_food.asList() 8 | defend_food = self.getFoodYouAreDefending(successor) 9 | opponents_index = self.getOpponents(successor) 10 | walls = successor.getWalls() 11 | features = util.Counter() 12 | features['bias'] = 1.0 13 | # compute the location of pacman after the action 14 | new_state = successor.getAgentState(self.index) 15 | next_x, next_y = new_state.getPosition() 16 | # calculate distance to opponents 17 | oppo_position = [successor.getAgentState(oppo).getPosition() for oppo in\ 18 | opponents_index] 19 | distance_to_oppo = [self.getMazeDistance((next_x, next_y), oppo) for oppo\ 20 | in oppo_position] 21 | closest_distance = min(distance_to_oppo) 22 | avg_distance = sum(distance_to_oppo) / len(distance_to_oppo) 23 | features['closest_distance_to_ghost'] = closest_distance 24 | features['average_distance_to_ghost'] = avg_distance 25 | num_of_ghost = 0 26 | for distance_oppo in distance_to_oppo: 27 | if distance_oppo < 3: 28 | num_of_ghost += 1 29 | features['num_of_ghost_nearby'] = num_of_ghost 30 | is_surrounded = oppo_position[0][0] <= next_x <= oppo_position[1][0] or\ 31 | oppo_position[0][1] <= next_y <= oppo_position[1][1] 32 | features['is_surrounded_by_ghost'] = is_surrounded 33 | # closest to food 34 | if food_list: 35 | min_distance = min([self.getMazeDistance((next_x, next_y), food_list)\ 36 | for food in food_list]) 37 | features['min_distance_to_food'] = min_distance 38 | get_food = eat_food[next_x][next_y] 39 | features['eat_food'] = get_food 40 | # carrying food 41 | last_role = old_state.getAgentState(self.index).isPacman() 42 | cur_role = gameState.getAgentState(self.index).isPacman() 43 | if last_role ^ cur_role: 44 | self.carry_food = 0 45 | elif get_food: 46 | self.carry_food += 1 47 | features['carry_food'] = self.carry_food 48 | # distance to frontier 49 | frontier_x = walls.width / 2 50 | return_dis = abs(frontier_x - next_x) 51 | features['return_distance'] = return_dis 52 | # tunnel/crossing/dead end/open 53 | features['is_dead_end'] = self.is_dead_end[(next_x, next_y)] 54 | features['is_tunnel'] = self.is_tunnel[(next_x, next_y)] 55 | features['is_crossing'] = self.is_crossing[(next_x, next_y)] 56 | features['is_open_area'] = self.is_open_area[(next_x, next_y)] 57 | # TODO: power capsules, scared time 58 | 59 | # for defensive agent 60 | def getFeaturesDefensive(self, gameState, action): 61 | # return a counter of feature for new state 62 | successor = self.getSuccessor(gameState, action) 63 | old_state = self.getPreviousObservation() 64 | eat_food = self.getFood(successor) 65 | defend_food = self.getFoodYouAreDefending(successor) 66 | food_list = defend_food.asList() 67 | opponents_index = self.getOpponents(successor) 68 | oppo_position = [self.getAgentState(oppo).getPosition() for oppo\ 69 | in opponents_index] 70 | walls = successor.getWalls() 71 | features = util.Counter() 72 | features['bias'] = 1.0 73 | # opponent in tunnel/crossing/openarea 74 | features['oppo_in_dead_end'] = self.is_dead_end[(oppo_position[0])] or\ 75 | self.is_dead_end[(oppo_position[1])] 76 | features['oppo_in_tunnel'] = self.is_tunnel[(oppo_position[0])] or\ 77 | self.is_tunnel[(oppo_position[1])] 78 | features['oppo_in_crossing'] = self.is_crossing[(oppo_position[0])] or\ 79 | self.is_crossing[(oppo_position[1])] 80 | features['oppo_in_open_area'] = self.is_open_area[(oppo_position[0])] or\ 81 | self.is_open_area[(oppo_position[1])] 82 | # opponent location relative to self 83 | teammate_index = (self.index + 2) % 4 84 | teammate_x, teammate_y = self.getAgentState(teammate_index).getPosition() 85 | for pos in oppo_position: 86 | surrounded_x = min(teammate_x, next_x) <= oppo_position[0][0] <= 87 | max(teammate_x, next_x) or 88 | min(teammate_x, next_x) <= oppo_position[1][0] <= 89 | max(teammate_x, next_x) 90 | 91 | surrounded_y = min(teammate_y, next_y) <= oppo_position[0][1] <= 92 | max(teammate_y, next_y) or 93 | min(teammate_y, next_y) <= oppo_position[1][1] <= 94 | max(teammate_y, next_y) 95 | surrounded_both = surrounded_x and surrounded_y 96 | features['surrounded_x'] = surrounded_x 97 | features['surrounded_y'] = surrounded_y 98 | features['surrounded_both'] = surrounded_both 99 | # distance to frontier 100 | frontier_x = walls.width / 2 101 | frontier_dis = abs(frontier_x - next_x) 102 | features['frontier_distance'] = return_dis 103 | # self in tunnel/crossing/dead end/open 104 | features['is_dead_end'] = self.is_dead_end[(next_x, next_y)] 105 | features['is_tunnel'] = self.is_tunnel[(next_x, next_y)] 106 | features['is_crossing'] = self.is_crossing[(next_x, next_y)] 107 | features['is_open_area'] = self.is_open_area[(next_x, next_y)] 108 | # self is scared 109 | features['is_scared'] = self.getAgentState(self.index).scaredTimer > 0 110 | # calculate distance to opponents 111 | distance_to_oppo = [self.getMazeDistance((next_x, next_y), oppo) for oppo\ 112 | in oppo_position] 113 | closest_distance = min(distance_to_oppo) 114 | avg_distance = sum(distance_to_oppo) / len(distance_to_oppo) 115 | features['closest_distance_to_pacman'] = closest_distance 116 | features['average_distance_to_pacman'] = avg_distance 117 | # calculate opponent distance to defending dots 118 | if food_list: 119 | min_distance = 1e9 120 | for oppo in oppo_position: 121 | # potential bug 122 | min_distance = min([self.getMazeDistance(oppo, food_list)\ 123 | for food in food_list], min_distance) 124 | features['min_distance_to_defend_food'] = min_distance 125 | # get dot loss 126 | if self.red: 127 | old_defending_food = old_state.getRedFood() 128 | else: 129 | old_defending_food = old_state.getBlueFood() 130 | dot_loss = 0 131 | for oppo in oppo_position: 132 | dot_loss += old_defending_food[int(oppo[0])][int(oppo[1])] 133 | features['dot_loss'] = dot_loss 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /minicontest2/keyboardAgents.py: -------------------------------------------------------------------------------- 1 | # keyboardAgents.py 2 | # ----------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from game import Agent 16 | from game import Directions 17 | import random 18 | 19 | class KeyboardAgent(Agent): 20 | """ 21 | An agent controlled by the keyboard. 22 | """ 23 | # NOTE: Arrow keys also work. 24 | WEST_KEY = 'a' 25 | EAST_KEY = 'd' 26 | NORTH_KEY = 'w' 27 | SOUTH_KEY = 's' 28 | STOP_KEY = 'q' 29 | 30 | def __init__( self, index = 0 ): 31 | 32 | self.lastMove = Directions.STOP 33 | self.index = index 34 | self.keys = [] 35 | 36 | def getAction( self, state): 37 | from graphicsUtils import keys_waiting 38 | from graphicsUtils import keys_pressed 39 | keys = list(keys_waiting()) + list(keys_pressed()) 40 | if keys != []: 41 | self.keys = keys 42 | 43 | legal = state.getLegalActions(self.index) 44 | move = self.getMove(legal) 45 | 46 | if move == Directions.STOP: 47 | # Try to move in the same direction as before 48 | if self.lastMove in legal: 49 | move = self.lastMove 50 | 51 | if (self.STOP_KEY in self.keys) and Directions.STOP in legal: move = Directions.STOP 52 | 53 | if move not in legal: 54 | move = random.choice(legal) 55 | 56 | self.lastMove = move 57 | return move 58 | 59 | def getMove(self, legal): 60 | move = Directions.STOP 61 | if (self.WEST_KEY in self.keys or 'Left' in self.keys) and Directions.WEST in legal: move = Directions.WEST 62 | if (self.EAST_KEY in self.keys or 'Right' in self.keys) and Directions.EAST in legal: move = Directions.EAST 63 | if (self.NORTH_KEY in self.keys or 'Up' in self.keys) and Directions.NORTH in legal: move = Directions.NORTH 64 | if (self.SOUTH_KEY in self.keys or 'Down' in self.keys) and Directions.SOUTH in legal: move = Directions.SOUTH 65 | return move 66 | 67 | class KeyboardAgent2(KeyboardAgent): 68 | """ 69 | A second agent controlled by the keyboard. 70 | """ 71 | # NOTE: Arrow keys also work. 72 | WEST_KEY = 'j' 73 | EAST_KEY = "l" 74 | NORTH_KEY = 'i' 75 | SOUTH_KEY = 'k' 76 | STOP_KEY = 'u' 77 | 78 | def getMove(self, legal): 79 | move = Directions.STOP 80 | if (self.WEST_KEY in self.keys) and Directions.WEST in legal: move = Directions.WEST 81 | if (self.EAST_KEY in self.keys) and Directions.EAST in legal: move = Directions.EAST 82 | if (self.NORTH_KEY in self.keys) and Directions.NORTH in legal: move = Directions.NORTH 83 | if (self.SOUTH_KEY in self.keys) and Directions.SOUTH in legal: move = Directions.SOUTH 84 | return move 85 | -------------------------------------------------------------------------------- /minicontest2/layout.py: -------------------------------------------------------------------------------- 1 | # layout.py 2 | # --------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from util import manhattanDistance 16 | from game import Grid 17 | import os 18 | import random 19 | from functools import reduce 20 | 21 | VISIBILITY_MATRIX_CACHE = {} 22 | 23 | class Layout: 24 | """ 25 | A Layout manages the static information about the game board. 26 | """ 27 | 28 | def __init__(self, layoutText): 29 | self.width = len(layoutText[0]) 30 | self.height= len(layoutText) 31 | self.walls = Grid(self.width, self.height, False) 32 | self.food = Grid(self.width, self.height, False) 33 | self.capsules = [] 34 | self.agentPositions = [] 35 | self.numGhosts = 0 36 | self.processLayoutText(layoutText) 37 | self.layoutText = layoutText 38 | self.totalFood = len(self.food.asList()) 39 | # self.initializeVisibilityMatrix() 40 | 41 | def getNumGhosts(self): 42 | return self.numGhosts 43 | 44 | def initializeVisibilityMatrix(self): 45 | global VISIBILITY_MATRIX_CACHE 46 | if reduce(str.__add__, self.layoutText) not in VISIBILITY_MATRIX_CACHE: 47 | from game import Directions 48 | vecs = [(-0.5,0), (0.5,0),(0,-0.5),(0,0.5)] 49 | dirs = [Directions.NORTH, Directions.SOUTH, Directions.WEST, Directions.EAST] 50 | vis = Grid(self.width, self.height, {Directions.NORTH:set(), Directions.SOUTH:set(), Directions.EAST:set(), Directions.WEST:set(), Directions.STOP:set()}) 51 | for x in range(self.width): 52 | for y in range(self.height): 53 | if self.walls[x][y] == False: 54 | for vec, direction in zip(vecs, dirs): 55 | dx, dy = vec 56 | nextx, nexty = x + dx, y + dy 57 | while (nextx + nexty) != int(nextx) + int(nexty) or not self.walls[int(nextx)][int(nexty)] : 58 | vis[x][y][direction].add((nextx, nexty)) 59 | nextx, nexty = x + dx, y + dy 60 | self.visibility = vis 61 | VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)] = vis 62 | else: 63 | self.visibility = VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)] 64 | 65 | def isWall(self, pos): 66 | x, col = pos 67 | return self.walls[x][col] 68 | 69 | def getRandomLegalPosition(self): 70 | x = random.choice(list(range(self.width))) 71 | y = random.choice(list(range(self.height))) 72 | while self.isWall( (x, y) ): 73 | x = random.choice(list(range(self.width))) 74 | y = random.choice(list(range(self.height))) 75 | return (x,y) 76 | 77 | def getRandomCorner(self): 78 | poses = [(1,1), (1, self.height - 2), (self.width - 2, 1), (self.width - 2, self.height - 2)] 79 | return random.choice(poses) 80 | 81 | def getFurthestCorner(self, pacPos): 82 | poses = [(1,1), (1, self.height - 2), (self.width - 2, 1), (self.width - 2, self.height - 2)] 83 | dist, pos = max([(manhattanDistance(p, pacPos), p) for p in poses]) 84 | return pos 85 | 86 | def isVisibleFrom(self, ghostPos, pacPos, pacDirection): 87 | row, col = [int(x) for x in pacPos] 88 | return ghostPos in self.visibility[row][col][pacDirection] 89 | 90 | def __str__(self): 91 | return "\n".join(self.layoutText) 92 | 93 | def deepCopy(self): 94 | return Layout(self.layoutText[:]) 95 | 96 | def processLayoutText(self, layoutText): 97 | """ 98 | Coordinates are flipped from the input format to the (x,y) convention here 99 | 100 | The shape of the maze. Each character 101 | represents a different type of object. 102 | % - Wall 103 | . - Food 104 | o - Capsule 105 | G - Ghost 106 | P - Pacman 107 | Other characters are ignored. 108 | """ 109 | maxY = self.height - 1 110 | for y in range(self.height): 111 | for x in range(self.width): 112 | layoutChar = layoutText[maxY - y][x] 113 | self.processLayoutChar(x, y, layoutChar) 114 | self.agentPositions.sort() 115 | self.agentPositions = [ ( i == 0, pos) for i, pos in self.agentPositions] 116 | 117 | def processLayoutChar(self, x, y, layoutChar): 118 | if layoutChar == '%': 119 | self.walls[x][y] = True 120 | elif layoutChar == '.': 121 | self.food[x][y] = True 122 | elif layoutChar == 'o': 123 | self.capsules.append((x, y)) 124 | elif layoutChar == 'P': 125 | self.agentPositions.append( (0, (x, y) ) ) 126 | elif layoutChar in ['G']: 127 | self.agentPositions.append( (1, (x, y) ) ) 128 | self.numGhosts += 1 129 | elif layoutChar in ['1', '2', '3', '4']: 130 | self.agentPositions.append( (int(layoutChar), (x,y))) 131 | self.numGhosts += 1 132 | def getLayout(name, back = 2): 133 | if name.endswith('.lay'): 134 | layout = tryToLoad('layouts/' + name) 135 | if layout == None: layout = tryToLoad(name) 136 | else: 137 | layout = tryToLoad('layouts/' + name + '.lay') 138 | if layout == None: layout = tryToLoad(name + '.lay') 139 | if layout == None and back >= 0: 140 | curdir = os.path.abspath('.') 141 | os.chdir('..') 142 | layout = getLayout(name, back -1) 143 | os.chdir(curdir) 144 | return layout 145 | 146 | def tryToLoad(fullname): 147 | if(not os.path.exists(fullname)): return None 148 | f = open(fullname) 149 | try: return Layout([line.strip() for line in f]) 150 | finally: f.close() 151 | -------------------------------------------------------------------------------- /minicontest2/score: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /minicontest2/textDisplay.py: -------------------------------------------------------------------------------- 1 | # textDisplay.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import time 16 | try: 17 | import pacman 18 | except: 19 | pass 20 | 21 | DRAW_EVERY = 1 22 | SLEEP_TIME = 0 # This can be overwritten by __init__ 23 | DISPLAY_MOVES = False 24 | QUIET = False # Supresses output 25 | 26 | class NullGraphics: 27 | def initialize(self, state, isBlue = False): 28 | pass 29 | 30 | def update(self, state): 31 | pass 32 | 33 | def checkNullDisplay(self): 34 | return True 35 | 36 | def pause(self): 37 | time.sleep(SLEEP_TIME) 38 | 39 | def draw(self, state): 40 | print(state) 41 | 42 | def updateDistributions(self, dist): 43 | pass 44 | 45 | def finish(self): 46 | pass 47 | 48 | class PacmanGraphics: 49 | def __init__(self, speed=None): 50 | if speed != None: 51 | global SLEEP_TIME 52 | SLEEP_TIME = speed 53 | 54 | def initialize(self, state, isBlue = False): 55 | self.draw(state) 56 | self.pause() 57 | self.turn = 0 58 | self.agentCounter = 0 59 | 60 | def update(self, state): 61 | numAgents = len(state.agentStates) 62 | self.agentCounter = (self.agentCounter + 1) % numAgents 63 | if self.agentCounter == 0: 64 | self.turn += 1 65 | if DISPLAY_MOVES: 66 | ghosts = [pacman.nearestPoint(state.getGhostPosition(i)) for i in range(1, numAgents)] 67 | print("%4d) P: %-8s" % (self.turn, str(pacman.nearestPoint(state.getPacmanPosition()))),'| Score: %-5d' % state.score,'| Ghosts:', ghosts) 68 | if self.turn % DRAW_EVERY == 0: 69 | self.draw(state) 70 | self.pause() 71 | if state._win or state._lose: 72 | self.draw(state) 73 | 74 | def pause(self): 75 | time.sleep(SLEEP_TIME) 76 | 77 | def draw(self, state): 78 | print(state) 79 | 80 | def finish(self): 81 | pass 82 | -------------------------------------------------------------------------------- /minicontest2/unpack.py: -------------------------------------------------------------------------------- 1 | # unpack.py 2 | # --------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import os, pickle, sys 16 | 17 | if len(sys.argv) != 3: 18 | print('Usage: %s stats_file team_name' % sys.argv[0]) 19 | print('Unpacks the stats file of a server into a bunch of replay files.') 20 | if len(sys.argv) == 2: 21 | d = pickle.load(open(sys.argv[1])) 22 | print('Team names:', list(d.keys())) 23 | sys.exit(2) 24 | 25 | d = pickle.load(open(sys.argv[1])) 26 | user = sys.argv[2] 27 | k = 0 28 | print('Unpacking games for', user) 29 | for g, w in d[user]['gameHistory']: 30 | k += 1 31 | t = {'layout': g.state.data.layout, 'agents': g.agents, 'actions': g.moveHistory, 'length': g.length} 32 | fname = 'replay_' + user + '_' + str(k) 33 | print('Game:', fname) 34 | pickle.dump(t,file(fname, 'w')) 35 | -------------------------------------------------------------------------------- /p0-tutorial/addition.py: -------------------------------------------------------------------------------- 1 | # addition.py 2 | # ----------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | """ 16 | Run python autograder.py 17 | """ 18 | 19 | 20 | def add(a, b): 21 | "Return the sum of a and b" 22 | "*** YOUR CODE HERE ***" 23 | 24 | return a + b 25 | -------------------------------------------------------------------------------- /p0-tutorial/buyLotsOfFruit.py: -------------------------------------------------------------------------------- 1 | # buyLotsOfFruit.py 2 | # ----------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | """ 16 | To run this script, type 17 | 18 | python buyLotsOfFruit.py 19 | 20 | Once you have correctly implemented the buyLotsOfFruit function, 21 | the script should produce the output: 22 | 23 | Cost of [('apples', 2.0), ('pears', 3.0), ('limes', 4.0)] is 12.25 24 | """ 25 | from __future__ import print_function 26 | 27 | fruitPrices = {'apples': 2.00, 'oranges': 1.50, 'pears': 1.75, 28 | 'limes': 0.75, 'strawberries': 1.00} 29 | 30 | 31 | def buyLotsOfFruit(orderList): 32 | """ 33 | orderList: List of (fruit, numPounds) tuples 34 | 35 | Returns cost of order 36 | """ 37 | totalCost = 0.0 38 | "*** YOUR CODE HERE ***" 39 | for fruit, pound in orderList: 40 | if fruit not in fruitPrices: 41 | print('Sorry, we do not have %s', fruit) 42 | return None 43 | totalCost += pound * fruitPrices[fruit] 44 | return totalCost 45 | 46 | 47 | # Main Method 48 | if __name__ == '__main__': 49 | "This code runs when you invoke the script from the command line" 50 | orderList = [('apples', 2.0), ('pears', 3.0), ('limes', 4.0)] 51 | print('Cost of', orderList, 'is', buyLotsOfFruit(orderList)) 52 | -------------------------------------------------------------------------------- /p0-tutorial/projectParams.py: -------------------------------------------------------------------------------- 1 | # projectParams.py 2 | # ---------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | STUDENT_CODE_DEFAULT = 'addition.py,buyLotsOfFruit.py,shopSmart.py,shopAroundTown.py' 16 | PROJECT_TEST_CLASSES = 'tutorialTestClasses.py' 17 | PROJECT_NAME = 'Project 0: Tutorial' 18 | BONUS_PIC = False 19 | -------------------------------------------------------------------------------- /p0-tutorial/shop.py: -------------------------------------------------------------------------------- 1 | # shop.py 2 | # ------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | class FruitShop: 16 | 17 | def __init__(self, name, fruitPrices): 18 | """ 19 | name: Name of the fruit shop 20 | 21 | fruitPrices: Dictionary with keys as fruit 22 | strings and prices for values e.g. 23 | {'apples':2.00, 'oranges': 1.50, 'pears': 1.75} 24 | """ 25 | self.fruitPrices = fruitPrices 26 | self.name = name 27 | print('Welcome to %s fruit shop' % (name)) 28 | 29 | def getCostPerPound(self, fruit): 30 | """ 31 | fruit: Fruit string 32 | Returns cost of 'fruit', assuming 'fruit' 33 | is in our inventory or None otherwise 34 | """ 35 | if fruit not in self.fruitPrices: 36 | return None 37 | return self.fruitPrices[fruit] 38 | 39 | def getPriceOfOrder(self, orderList): 40 | """ 41 | orderList: List of (fruit, numPounds) tuples 42 | 43 | Returns cost of orderList, only including the values of 44 | fruits that this fruit shop has. 45 | """ 46 | totalCost = 0.0 47 | for fruit, numPounds in orderList: 48 | costPerPound = self.getCostPerPound(fruit) 49 | if costPerPound != None: 50 | totalCost += numPounds * costPerPound 51 | return totalCost 52 | 53 | def getName(self): 54 | return self.name 55 | 56 | def __str__(self): 57 | return "" % self.getName() 58 | 59 | def __repr__(self): 60 | return str(self) 61 | -------------------------------------------------------------------------------- /p0-tutorial/shopAroundTown.py: -------------------------------------------------------------------------------- 1 | # shopAroundTown.py 2 | # ----------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | """ 16 | Here's the intended output of this script, once you fill it in: 17 | 18 | Welcome to shop1 fruit shop 19 | Welcome to shop2 fruit shop 20 | Welcome to shop3 fruit shop 21 | Orders: [('apples', 1.0), ('oranges', 3.0), ('limes', 2.0)] 22 | At gas price 1 the best route is: ['shop1', 'shop2', 'shop3'] 23 | At gas price 3 the best route is: ['shop1', 'shop3'] 24 | At gas price 5 the best route is: ['shop2'] 25 | At gas price -1 the best route is: ['shop2', 'shop1', 'shop3'] 26 | """ 27 | 28 | from __future__ import print_function 29 | import shop 30 | import town 31 | 32 | 33 | def shopAroundTown(orderList, fruitTown, gasCost): 34 | """ 35 | orderList: List of (fruit, numPound) tuples 36 | fruitTown: A Town object 37 | gasCost: A number representing the cost of going one mile 38 | Returns a list of shops in the order that is the optimal route to take when 39 | buying the fruit in the orderList 40 | """ 41 | possibleRoutes = [] 42 | subsets = getAllSubsets(fruitTown.getShops()) 43 | for subset in subsets: 44 | names = [shop.getName() for shop in subset] 45 | if fruitTown.allFruitsCarriedAtShops(orderList, names): 46 | possibleRoutes += getAllPermutations(subset) 47 | minCost, bestRoute = None, None 48 | for route in possibleRoutes: 49 | cost = fruitTown.getPriceOfOrderOnRoute(orderList, route, gasCost) 50 | if minCost == None or cost < minCost: 51 | minCost, bestRoute = cost, route 52 | return bestRoute 53 | 54 | 55 | def getAllSubsets(lst): 56 | """ 57 | lst: A list 58 | Returns the powerset of lst, i.e. a list of all the possible subsets of lst 59 | """ 60 | if not lst: 61 | return [] 62 | withFirst = [[lst[0]] + rest for rest in getAllSubsets(lst[1:])] 63 | withoutFirst = getAllSubsets(lst[1:]) 64 | return withFirst + withoutFirst 65 | 66 | 67 | def getAllPermutations(lst): 68 | """ 69 | lst: A list 70 | Returns a list of all permutations of lst 71 | """ 72 | if not lst: 73 | return [] 74 | elif len(lst) == 1: 75 | return lst 76 | allPermutations = [] 77 | for i in range(len(lst)): 78 | item = lst[i] 79 | withoutItem = lst[:i] + lst[i:] 80 | allPermutations += prependToAll(item, getAllPermutations(withoutItem)) 81 | return allPermutations 82 | 83 | 84 | def prependToAll(item, lsts): 85 | """ 86 | item: Any object 87 | lsts: A list of lists 88 | Returns a copy of lsts with item prepended to each list contained in lsts 89 | """ 90 | return [[item] + lst for lst in lsts] 91 | 92 | 93 | if __name__ == '__main__': 94 | "This code runs when you invoke the script from the command line" 95 | orders = [('apples', 1.0), ('oranges', 3.0), ('limes', 2.0)] 96 | dir1 = {'apples': 2.0, 'oranges': 1.0} 97 | dir2 = {'apples': 1.0, 'oranges': 5.0, 'limes': 3.0} 98 | dir3 = {'apples': 2.0, 'limes': 2.0} 99 | shop1 = shop.FruitShop('shop1', dir1) 100 | shop2 = shop.FruitShop('shop2', dir2) 101 | shop3 = shop.FruitShop('shop3', dir3) 102 | shops = [shop1, shop2, shop3] 103 | distances = {('home', 'shop1'): 2, 104 | ('home', 'shop2'): 1, 105 | ('home', 'shop3'): 1, 106 | ('shop1', 'shop2'): 2.5, 107 | ('shop1', 'shop3'): 2.5, 108 | ('shop2', 'shop3'): 1 109 | } 110 | fruitTown = town.Town(shops, distances) 111 | print("Orders:", orders) 112 | for price in (1, 3, 5, -1): 113 | print("At gas price", price, "the best route is:", \ 114 | shopAroundTown(orders, fruitTown, price)) 115 | -------------------------------------------------------------------------------- /p0-tutorial/shopSmart.py: -------------------------------------------------------------------------------- 1 | # shopSmart.py 2 | # ------------ 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | """ 16 | Here's the intended output of this script, once you fill it in: 17 | 18 | Welcome to shop1 fruit shop 19 | Welcome to shop2 fruit shop 20 | For orders: [('apples', 1.0), ('oranges', 3.0)] best shop is shop1 21 | For orders: [('apples', 3.0)] best shop is shop2 22 | """ 23 | from __future__ import print_function 24 | import shop 25 | 26 | 27 | def shopSmart(orderList, fruitShops): 28 | """ 29 | orderList: List of (fruit, numPound) tuples 30 | fruitShops: List of FruitShops 31 | """ 32 | "*** YOUR CODE HERE ***" 33 | price_low = 1e31 34 | for shop in fruitShops: 35 | price_now = shop.getPriceOfOrder(orderList) 36 | # print(price_now, price_low) 37 | if price_now < price_low: 38 | price_low = price_now 39 | ret = shop 40 | return ret 41 | 42 | 43 | if __name__ == '__main__': 44 | "This code runs when you invoke the script from the command line" 45 | orders = [('apples', 1.0), ('oranges', 3.0)] 46 | dir1 = {'apples': 2.0, 'oranges': 1.0} 47 | shop1 = shop.FruitShop('shop1', dir1) 48 | dir2 = {'apples': 1.0, 'oranges': 5.0} 49 | shop2 = shop.FruitShop('shop2', dir2) 50 | shops = [shop1, shop2] 51 | print("For orders ", orders, ", the best shop is", shopSmart(orders, shops).getName()) 52 | orders = [('apples', 3.0)] 53 | print("For orders: ", orders, ", the best shop is", shopSmart(orders, shops).getName()) 54 | -------------------------------------------------------------------------------- /p0-tutorial/testParser.py: -------------------------------------------------------------------------------- 1 | # testParser.py 2 | # ------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | from __future__ import print_function 15 | import re 16 | import sys 17 | 18 | 19 | class TestParser(object): 20 | 21 | def __init__(self, path): 22 | # save the path to the test file 23 | self.path = path 24 | 25 | def removeComments(self, rawlines): 26 | # remove any portion of a line following a '#' symbol 27 | fixed_lines = [] 28 | for l in rawlines: 29 | idx = l.find('#') 30 | if idx == -1: 31 | fixed_lines.append(l) 32 | else: 33 | fixed_lines.append(l[0:idx]) 34 | return '\n'.join(fixed_lines) 35 | 36 | def parse(self): 37 | # read in the test case and remove comments 38 | test = {} 39 | with open(self.path) as handle: 40 | raw_lines = handle.read().split('\n') 41 | 42 | test_text = self.removeComments(raw_lines) 43 | test['__raw_lines__'] = raw_lines 44 | test['path'] = self.path 45 | test['__emit__'] = [] 46 | lines = test_text.split('\n') 47 | i = 0 48 | # read a property in each loop cycle 49 | while (i < len(lines)): 50 | # skip blank lines 51 | if re.match('\A\s*\Z', lines[i]): 52 | test['__emit__'].append(("raw", raw_lines[i])) 53 | i += 1 54 | continue 55 | m = re.match('\A([^"]*?):\s*"([^"]*)"\s*\Z', lines[i]) 56 | if m: 57 | test[m.group(1)] = m.group(2) 58 | test['__emit__'].append(("oneline", m.group(1))) 59 | i += 1 60 | continue 61 | m = re.match('\A([^"]*?):\s*"""\s*\Z', lines[i]) 62 | if m: 63 | msg = [] 64 | i += 1 65 | while (not re.match('\A\s*"""\s*\Z', lines[i])): 66 | msg.append(raw_lines[i]) 67 | i += 1 68 | test[m.group(1)] = '\n'.join(msg) 69 | test['__emit__'].append(("multiline", m.group(1))) 70 | i += 1 71 | continue 72 | print('error parsing test file: %s' % self.path) 73 | sys.exit(1) 74 | return test 75 | 76 | 77 | def emitTestDict(testDict, handle): 78 | for kind, data in testDict['__emit__']: 79 | if kind == "raw": 80 | handle.write(data + "\n") 81 | elif kind == "oneline": 82 | handle.write('%s: "%s"\n' % (data, testDict[data])) 83 | elif kind == "multiline": 84 | handle.write('%s: """\n%s\n"""\n' % (data, testDict[data])) 85 | else: 86 | raise Exception("Bad __emit__") 87 | -------------------------------------------------------------------------------- /p0-tutorial/test_cases/CONFIG: -------------------------------------------------------------------------------- 1 | order: "q1 q2 q3" 2 | -------------------------------------------------------------------------------- /p0-tutorial/test_cases/q1/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "1" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p0-tutorial/test_cases/q2/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "1" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p0-tutorial/test_cases/q3/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "1" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p0-tutorial/textDisplay.py: -------------------------------------------------------------------------------- 1 | # textDisplay.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | from __future__ import print_function 15 | import time 16 | 17 | try: 18 | import pacman 19 | except: 20 | pass 21 | 22 | DRAW_EVERY = 1 23 | SLEEP_TIME = 0 # This can be overwritten by __init__ 24 | DISPLAY_MOVES = False 25 | QUIET = False # Supresses output 26 | 27 | 28 | class NullGraphics: 29 | def initialize(self, state, isBlue=False): 30 | pass 31 | 32 | def update(self, state): 33 | pass 34 | 35 | def checkNullDisplay(self): 36 | return True 37 | 38 | def pause(self): 39 | time.sleep(SLEEP_TIME) 40 | 41 | def draw(self, state): 42 | print(state) 43 | 44 | def updateDistributions(self, dist): 45 | pass 46 | 47 | def finish(self): 48 | pass 49 | 50 | 51 | class PacmanGraphics: 52 | def __init__(self, speed=None): 53 | if speed != None: 54 | global SLEEP_TIME 55 | SLEEP_TIME = speed 56 | 57 | def initialize(self, state, isBlue=False): 58 | self.draw(state) 59 | self.pause() 60 | self.turn = 0 61 | self.agentCounter = 0 62 | 63 | def update(self, state): 64 | numAgents = len(state.agentStates) 65 | self.agentCounter = (self.agentCounter + 1) % numAgents 66 | if self.agentCounter == 0: 67 | self.turn += 1 68 | if DISPLAY_MOVES: 69 | ghosts = [pacman.nearestPoint(state.getGhostPosition(i)) for i in range(1, numAgents)] 70 | print("%4d) P: %-8s" % (self.turn, str(pacman.nearestPoint(state.getPacmanPosition()))), 71 | '| Score: %-5d' % state.score, '| Ghosts:', ghosts) 72 | if self.turn % DRAW_EVERY == 0: 73 | self.draw(state) 74 | self.pause() 75 | if state._win or state._lose: 76 | self.draw(state) 77 | 78 | def pause(self): 79 | time.sleep(SLEEP_TIME) 80 | 81 | def draw(self, state): 82 | print(state) 83 | 84 | def finish(self): 85 | pass 86 | -------------------------------------------------------------------------------- /p0-tutorial/town.py: -------------------------------------------------------------------------------- 1 | # town.py 2 | # ------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import shop 16 | 17 | 18 | class Town: 19 | 20 | def __init__(self, shops, distances): 21 | """ 22 | shops: List of FruitShop objects 23 | 24 | distances: Dictionary with keys as pairs (tuples) of names of places 25 | ('home' or name strings of FruitShops) and numbers for values which 26 | represent the distance between the two places in miles, e.g. 27 | {('home','shop1') : 1, ('home','shop2') : 1, ('shop1','shop2') : 2} 28 | """ 29 | self.shops = shops 30 | self.distances = distances 31 | 32 | def getFruitCostPerPoundOnRoute(self, fruit, route): 33 | """ 34 | fruit: Fruit string 35 | 36 | route: List of shop names 37 | Returns the best cost per pound of 'fruit' at any of the shops along 38 | the route. If none of the shops carry 'fruit', returns None 39 | """ 40 | routeShops = [shop for shop in self.shops if shop.getName() in route] 41 | costs = [] 42 | for shop in routeShops: 43 | cost = shop.getCostPerPound(fruit) 44 | if cost is not None: 45 | costs.append(cost) 46 | if not costs: 47 | # None of the shops carry this fruit 48 | return None 49 | return min(costs) 50 | 51 | def allFruitsCarriedAtShops(self, orderList, shops): 52 | """ 53 | orderList: List of (fruit, numPounds) tuples 54 | 55 | shops: List of shop names 56 | Returns whether all fruit in the order list can be purchased at at least 57 | one of these shops. 58 | """ 59 | return None not in [self.getFruitCostPerPoundOnRoute(fruit, shops) 60 | for fruit, _ in orderList] 61 | 62 | def getDistance(self, loc1, loc2): 63 | """ 64 | loc1: A name of a place ('home' or the name of a FruitShop in town) 65 | 66 | loc2: A name of a place ('home' or the name of a FruitShop in town) 67 | Returns the distance between these two places in this town. 68 | """ 69 | if (loc1, loc2) in self.distances: 70 | return self.distances[(loc1, loc2)] 71 | return self.distances[(loc2, loc1)] 72 | 73 | def getTotalDistanceOnRoute(self, route): 74 | """ 75 | route: List of shop names 76 | Returns the total distance traveled by starting at 'home', going to 77 | each shop on the route in order, then returning to 'home' 78 | """ 79 | if not route: 80 | return 0 81 | totalDistance = self.getDistance('home', route[0]) 82 | for i in xrange(len(route) - 1): 83 | totalDistance += self.getDistance(route[i], route[i + 1]) 84 | totalDistance += self.getDistance(route[-1], 'home') 85 | return totalDistance 86 | 87 | def getPriceOfOrderOnRoute(self, orderList, route, gasCost): 88 | """ 89 | orderList: List of (fruit, numPounds) tuples 90 | 91 | route: List of shop names 92 | 93 | gasCost: A number representing the cost of driving 1 mile 94 | Returns cost of orderList on this route. If any fruit are not available 95 | on this route, returns None. 96 | """ 97 | totalCost = self.getTotalDistanceOnRoute(route) * gasCost 98 | for fruit, numPounds in orderList: 99 | costPerPound = self.getFruitCostPerPoundOnRoute(fruit, route) 100 | if costPerPound is not None: 101 | totalCost += numPounds * costPerPound 102 | return totalCost 103 | 104 | def getShops(self): 105 | return self.shops 106 | -------------------------------------------------------------------------------- /p0-tutorial/tutorialTestClasses.py: -------------------------------------------------------------------------------- 1 | # tutorialTestClasses.py 2 | # ---------------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import testClasses 16 | 17 | 18 | # Simple test case which evals an arbitrary piece of python code. 19 | # The test is correct if the output of the code given the student's 20 | # solution matches that of the instructor's. 21 | class EvalTest(testClasses.TestCase): 22 | 23 | def __init__(self, question, testDict): 24 | super(EvalTest, self).__init__(question, testDict) 25 | self.preamble = compile(testDict.get('preamble', ""), "%s.preamble" % self.getPath(), 'exec') 26 | self.test = compile(testDict['test'], "%s.test" % self.getPath(), 'eval') 27 | self.success = testDict['success'] 28 | self.failure = testDict['failure'] 29 | 30 | def evalCode(self, moduleDict): 31 | bindings = dict(moduleDict) 32 | # exec self.preamble in bindings 33 | exec(self.preamble, bindings) 34 | return str(eval(self.test, bindings)) 35 | 36 | def execute(self, grades, moduleDict, solutionDict): 37 | result = self.evalCode(moduleDict) 38 | if result == solutionDict['result']: 39 | grades.addMessage('PASS: %s' % self.path) 40 | grades.addMessage('\t%s' % self.success) 41 | return True 42 | else: 43 | grades.addMessage('FAIL: %s' % self.path) 44 | grades.addMessage('\t%s' % self.failure) 45 | grades.addMessage('\tstudent result: "%s"' % result) 46 | grades.addMessage('\tcorrect result: "%s"' % solutionDict['result']) 47 | 48 | return False 49 | 50 | def writeSolution(self, moduleDict, filePath): 51 | handle = open(filePath, 'w') 52 | handle.write('# This is the solution file for %s.\n' % self.path) 53 | handle.write('# The result of evaluating the test must equal the below when cast to a string.\n') 54 | 55 | handle.write('result: "%s"\n' % self.evalCode(moduleDict)) 56 | handle.close() 57 | return True 58 | -------------------------------------------------------------------------------- /p1-search/VERSION: -------------------------------------------------------------------------------- 1 | v1.001 2 | -------------------------------------------------------------------------------- /p1-search/ghostAgents.py: -------------------------------------------------------------------------------- 1 | # ghostAgents.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from game import Agent 16 | from game import Actions 17 | from game import Directions 18 | import random 19 | from util import manhattanDistance 20 | import util 21 | 22 | class GhostAgent( Agent ): 23 | def __init__( self, index ): 24 | self.index = index 25 | 26 | def getAction( self, state ): 27 | dist = self.getDistribution(state) 28 | if len(dist) == 0: 29 | return Directions.STOP 30 | else: 31 | return util.chooseFromDistribution( dist ) 32 | 33 | def getDistribution(self, state): 34 | "Returns a Counter encoding a distribution over actions from the provided state." 35 | util.raiseNotDefined() 36 | 37 | class RandomGhost( GhostAgent ): 38 | "A ghost that chooses a legal action uniformly at random." 39 | def getDistribution( self, state ): 40 | dist = util.Counter() 41 | for a in state.getLegalActions( self.index ): dist[a] = 1.0 42 | dist.normalize() 43 | return dist 44 | 45 | class DirectionalGhost( GhostAgent ): 46 | "A ghost that prefers to rush Pacman, or flee when scared." 47 | def __init__( self, index, prob_attack=0.8, prob_scaredFlee=0.8 ): 48 | self.index = index 49 | self.prob_attack = prob_attack 50 | self.prob_scaredFlee = prob_scaredFlee 51 | 52 | def getDistribution( self, state ): 53 | # Read variables from state 54 | ghostState = state.getGhostState( self.index ) 55 | legalActions = state.getLegalActions( self.index ) 56 | pos = state.getGhostPosition( self.index ) 57 | isScared = ghostState.scaredTimer > 0 58 | 59 | speed = 1 60 | if isScared: speed = 0.5 61 | 62 | actionVectors = [Actions.directionToVector( a, speed ) for a in legalActions] 63 | newPositions = [( pos[0]+a[0], pos[1]+a[1] ) for a in actionVectors] 64 | pacmanPosition = state.getPacmanPosition() 65 | 66 | # Select best actions given the state 67 | distancesToPacman = [manhattanDistance( pos, pacmanPosition ) for pos in newPositions] 68 | if isScared: 69 | bestScore = max( distancesToPacman ) 70 | bestProb = self.prob_scaredFlee 71 | else: 72 | bestScore = min( distancesToPacman ) 73 | bestProb = self.prob_attack 74 | bestActions = [action for action, distance in zip( legalActions, distancesToPacman ) if distance == bestScore] 75 | 76 | # Construct distribution 77 | dist = util.Counter() 78 | for a in bestActions: dist[a] = bestProb / len(bestActions) 79 | for a in legalActions: dist[a] += ( 1-bestProb ) / len(legalActions) 80 | dist.normalize() 81 | return dist 82 | -------------------------------------------------------------------------------- /p1-search/keyboardAgents.py: -------------------------------------------------------------------------------- 1 | # keyboardAgents.py 2 | # ----------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from game import Agent 16 | from game import Directions 17 | import random 18 | 19 | class KeyboardAgent(Agent): 20 | """ 21 | An agent controlled by the keyboard. 22 | """ 23 | # NOTE: Arrow keys also work. 24 | WEST_KEY = 'a' 25 | EAST_KEY = 'd' 26 | NORTH_KEY = 'w' 27 | SOUTH_KEY = 's' 28 | STOP_KEY = 'q' 29 | 30 | def __init__( self, index = 0 ): 31 | 32 | self.lastMove = Directions.STOP 33 | self.index = index 34 | self.keys = [] 35 | 36 | def getAction( self, state): 37 | from graphicsUtils import keys_waiting 38 | from graphicsUtils import keys_pressed 39 | keys = list(keys_waiting()) + list(keys_pressed()) 40 | if keys != []: 41 | self.keys = keys 42 | 43 | legal = state.getLegalActions(self.index) 44 | move = self.getMove(legal) 45 | 46 | if move == Directions.STOP: 47 | # Try to move in the same direction as before 48 | if self.lastMove in legal: 49 | move = self.lastMove 50 | 51 | if (self.STOP_KEY in self.keys) and Directions.STOP in legal: move = Directions.STOP 52 | 53 | if move not in legal: 54 | move = random.choice(legal) 55 | 56 | self.lastMove = move 57 | return move 58 | 59 | def getMove(self, legal): 60 | move = Directions.STOP 61 | if (self.WEST_KEY in self.keys or 'Left' in self.keys) and Directions.WEST in legal: move = Directions.WEST 62 | if (self.EAST_KEY in self.keys or 'Right' in self.keys) and Directions.EAST in legal: move = Directions.EAST 63 | if (self.NORTH_KEY in self.keys or 'Up' in self.keys) and Directions.NORTH in legal: move = Directions.NORTH 64 | if (self.SOUTH_KEY in self.keys or 'Down' in self.keys) and Directions.SOUTH in legal: move = Directions.SOUTH 65 | return move 66 | 67 | class KeyboardAgent2(KeyboardAgent): 68 | """ 69 | A second agent controlled by the keyboard. 70 | """ 71 | # NOTE: Arrow keys also work. 72 | WEST_KEY = 'j' 73 | EAST_KEY = "l" 74 | NORTH_KEY = 'i' 75 | SOUTH_KEY = 'k' 76 | STOP_KEY = 'u' 77 | 78 | def getMove(self, legal): 79 | move = Directions.STOP 80 | if (self.WEST_KEY in self.keys) and Directions.WEST in legal: move = Directions.WEST 81 | if (self.EAST_KEY in self.keys) and Directions.EAST in legal: move = Directions.EAST 82 | if (self.NORTH_KEY in self.keys) and Directions.NORTH in legal: move = Directions.NORTH 83 | if (self.SOUTH_KEY in self.keys) and Directions.SOUTH in legal: move = Directions.SOUTH 84 | return move 85 | -------------------------------------------------------------------------------- /p1-search/layout.py: -------------------------------------------------------------------------------- 1 | # layout.py 2 | # --------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from util import manhattanDistance 16 | from game import Grid 17 | import os 18 | import random 19 | from functools import reduce 20 | 21 | VISIBILITY_MATRIX_CACHE = {} 22 | 23 | class Layout: 24 | """ 25 | A Layout manages the static information about the game board. 26 | """ 27 | 28 | def __init__(self, layoutText): 29 | self.width = len(layoutText[0]) 30 | self.height= len(layoutText) 31 | self.walls = Grid(self.width, self.height, False) 32 | self.food = Grid(self.width, self.height, False) 33 | self.capsules = [] 34 | self.agentPositions = [] 35 | self.numGhosts = 0 36 | self.processLayoutText(layoutText) 37 | self.layoutText = layoutText 38 | self.totalFood = len(self.food.asList()) 39 | # self.initializeVisibilityMatrix() 40 | 41 | def getNumGhosts(self): 42 | return self.numGhosts 43 | 44 | def initializeVisibilityMatrix(self): 45 | global VISIBILITY_MATRIX_CACHE 46 | if reduce(str.__add__, self.layoutText) not in VISIBILITY_MATRIX_CACHE: 47 | from game import Directions 48 | vecs = [(-0.5,0), (0.5,0),(0,-0.5),(0,0.5)] 49 | dirs = [Directions.NORTH, Directions.SOUTH, Directions.WEST, Directions.EAST] 50 | vis = Grid(self.width, self.height, {Directions.NORTH:set(), Directions.SOUTH:set(), Directions.EAST:set(), Directions.WEST:set(), Directions.STOP:set()}) 51 | for x in range(self.width): 52 | for y in range(self.height): 53 | if self.walls[x][y] == False: 54 | for vec, direction in zip(vecs, dirs): 55 | dx, dy = vec 56 | nextx, nexty = x + dx, y + dy 57 | while (nextx + nexty) != int(nextx) + int(nexty) or not self.walls[int(nextx)][int(nexty)] : 58 | vis[x][y][direction].add((nextx, nexty)) 59 | nextx, nexty = x + dx, y + dy 60 | self.visibility = vis 61 | VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)] = vis 62 | else: 63 | self.visibility = VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)] 64 | 65 | def isWall(self, pos): 66 | x, col = pos 67 | return self.walls[x][col] 68 | 69 | def getRandomLegalPosition(self): 70 | x = random.choice(range(self.width)) 71 | y = random.choice(range(self.height)) 72 | while self.isWall( (x, y) ): 73 | x = random.choice(range(self.width)) 74 | y = random.choice(range(self.height)) 75 | return (x,y) 76 | 77 | def getRandomCorner(self): 78 | poses = [(1,1), (1, self.height - 2), (self.width - 2, 1), (self.width - 2, self.height - 2)] 79 | return random.choice(poses) 80 | 81 | def getFurthestCorner(self, pacPos): 82 | poses = [(1,1), (1, self.height - 2), (self.width - 2, 1), (self.width - 2, self.height - 2)] 83 | dist, pos = max([(manhattanDistance(p, pacPos), p) for p in poses]) 84 | return pos 85 | 86 | def isVisibleFrom(self, ghostPos, pacPos, pacDirection): 87 | row, col = [int(x) for x in pacPos] 88 | return ghostPos in self.visibility[row][col][pacDirection] 89 | 90 | def __str__(self): 91 | return "\n".join(self.layoutText) 92 | 93 | def deepCopy(self): 94 | return Layout(self.layoutText[:]) 95 | 96 | def processLayoutText(self, layoutText): 97 | """ 98 | Coordinates are flipped from the input format to the (x,y) convention here 99 | 100 | The shape of the maze. Each character 101 | represents a different type of object. 102 | % - Wall 103 | . - Food 104 | o - Capsule 105 | G - Ghost 106 | P - Pacman 107 | Other characters are ignored. 108 | """ 109 | maxY = self.height - 1 110 | for y in range(self.height): 111 | for x in range(self.width): 112 | layoutChar = layoutText[maxY - y][x] 113 | self.processLayoutChar(x, y, layoutChar) 114 | self.agentPositions.sort() 115 | self.agentPositions = [ ( i == 0, pos) for i, pos in self.agentPositions] 116 | 117 | def processLayoutChar(self, x, y, layoutChar): 118 | if layoutChar == '%': 119 | self.walls[x][y] = True 120 | elif layoutChar == '.': 121 | self.food[x][y] = True 122 | elif layoutChar == 'o': 123 | self.capsules.append((x, y)) 124 | elif layoutChar == 'P': 125 | self.agentPositions.append( (0, (x, y) ) ) 126 | elif layoutChar in ['G']: 127 | self.agentPositions.append( (1, (x, y) ) ) 128 | self.numGhosts += 1 129 | elif layoutChar in ['1', '2', '3', '4']: 130 | self.agentPositions.append( (int(layoutChar), (x,y))) 131 | self.numGhosts += 1 132 | def getLayout(name, back = 2): 133 | if name.endswith('.lay'): 134 | layout = tryToLoad('layouts/' + name) 135 | if layout == None: layout = tryToLoad(name) 136 | else: 137 | layout = tryToLoad('layouts/' + name + '.lay') 138 | if layout == None: layout = tryToLoad(name + '.lay') 139 | if layout == None and back >= 0: 140 | curdir = os.path.abspath('.') 141 | os.chdir('..') 142 | layout = getLayout(name, back -1) 143 | os.chdir(curdir) 144 | return layout 145 | 146 | def tryToLoad(fullname): 147 | if(not os.path.exists(fullname)): return None 148 | f = open(fullname) 149 | try: return Layout([line.strip() for line in f]) 150 | finally: f.close() 151 | -------------------------------------------------------------------------------- /p1-search/pacmanAgents.py: -------------------------------------------------------------------------------- 1 | # pacmanAgents.py 2 | # --------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from pacman import Directions 16 | from game import Agent 17 | import random 18 | import game 19 | import util 20 | 21 | class LeftTurnAgent(game.Agent): 22 | "An agent that turns left at every opportunity" 23 | 24 | def getAction(self, state): 25 | legal = state.getLegalPacmanActions() 26 | current = state.getPacmanState().configuration.direction 27 | if current == Directions.STOP: current = Directions.NORTH 28 | left = Directions.LEFT[current] 29 | if left in legal: return left 30 | if current in legal: return current 31 | if Directions.RIGHT[current] in legal: return Directions.RIGHT[current] 32 | if Directions.LEFT[left] in legal: return Directions.LEFT[left] 33 | return Directions.STOP 34 | 35 | class GreedyAgent(Agent): 36 | def __init__(self, evalFn="scoreEvaluation"): 37 | self.evaluationFunction = util.lookup(evalFn, globals()) 38 | assert self.evaluationFunction != None 39 | 40 | def getAction(self, state): 41 | # Generate candidate actions 42 | legal = state.getLegalPacmanActions() 43 | if Directions.STOP in legal: legal.remove(Directions.STOP) 44 | 45 | successors = [(state.generateSuccessor(0, action), action) for action in legal] 46 | scored = [(self.evaluationFunction(state), action) for state, action in successors] 47 | bestScore = max(scored)[0] 48 | bestActions = [pair[1] for pair in scored if pair[0] == bestScore] 49 | return random.choice(bestActions) 50 | 51 | def scoreEvaluation(state): 52 | return state.getScore() 53 | -------------------------------------------------------------------------------- /p1-search/projectParams.py: -------------------------------------------------------------------------------- 1 | # projectParams.py 2 | # ---------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | STUDENT_CODE_DEFAULT = 'searchAgents.py,search.py' 16 | PROJECT_TEST_CLASSES = 'searchTestClasses.py' 17 | PROJECT_NAME = 'Project 1: Search' 18 | BONUS_PIC = False 19 | -------------------------------------------------------------------------------- /p1-search/testParser.py: -------------------------------------------------------------------------------- 1 | # testParser.py 2 | # ------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import re 16 | import sys 17 | 18 | class TestParser(object): 19 | 20 | def __init__(self, path): 21 | # save the path to the test file 22 | self.path = path 23 | 24 | def removeComments(self, rawlines): 25 | # remove any portion of a line following a '#' symbol 26 | fixed_lines = [] 27 | for l in rawlines: 28 | idx = l.find('#') 29 | if idx == -1: 30 | fixed_lines.append(l) 31 | else: 32 | fixed_lines.append(l[0:idx]) 33 | return '\n'.join(fixed_lines) 34 | 35 | def parse(self): 36 | # read in the test case and remove comments 37 | test = {} 38 | with open(self.path) as handle: 39 | raw_lines = handle.read().split('\n') 40 | 41 | test_text = self.removeComments(raw_lines) 42 | test['__raw_lines__'] = raw_lines 43 | test['path'] = self.path 44 | test['__emit__'] = [] 45 | lines = test_text.split('\n') 46 | i = 0 47 | # read a property in each loop cycle 48 | while(i < len(lines)): 49 | # skip blank lines 50 | if re.match('\A\s*\Z', lines[i]): 51 | test['__emit__'].append(("raw", raw_lines[i])) 52 | i += 1 53 | continue 54 | m = re.match('\A([^"]*?):\s*"([^"]*)"\s*\Z', lines[i]) 55 | if m: 56 | test[m.group(1)] = m.group(2) 57 | test['__emit__'].append(("oneline", m.group(1))) 58 | i += 1 59 | continue 60 | m = re.match('\A([^"]*?):\s*"""\s*\Z', lines[i]) 61 | if m: 62 | msg = [] 63 | i += 1 64 | while(not re.match('\A\s*"""\s*\Z', lines[i])): 65 | msg.append(raw_lines[i]) 66 | i += 1 67 | test[m.group(1)] = '\n'.join(msg) 68 | test['__emit__'].append(("multiline", m.group(1))) 69 | i += 1 70 | continue 71 | print('error parsing test file: %s' % self.path) 72 | sys.exit(1) 73 | return test 74 | 75 | 76 | def emitTestDict(testDict, handle): 77 | for kind, data in testDict['__emit__']: 78 | if kind == "raw": 79 | handle.write(data + "\n") 80 | elif kind == "oneline": 81 | handle.write('%s: "%s"\n' % (data, testDict[data])) 82 | elif kind == "multiline": 83 | handle.write('%s: """\n%s\n"""\n' % (data, testDict[data])) 84 | else: 85 | raise Exception("Bad __emit__") 86 | -------------------------------------------------------------------------------- /p1-search/test_cases/CONFIG: -------------------------------------------------------------------------------- 1 | order: "q1 q2 q3 q4 q5 q6 q7 q8" -------------------------------------------------------------------------------- /p1-search/test_cases/q1/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p1-search/test_cases/q2/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p1-search/test_cases/q3/CONFIG: -------------------------------------------------------------------------------- 1 | class: "PassAllTestsQuestion" 2 | max_points: "3" 3 | -------------------------------------------------------------------------------- /p1-search/test_cases/q4/CONFIG: -------------------------------------------------------------------------------- 1 | class: "PassAllTestsQuestion" 2 | max_points: "3" -------------------------------------------------------------------------------- /p1-search/test_cases/q5/CONFIG: -------------------------------------------------------------------------------- 1 | class: "PassAllTestsQuestion" 2 | max_points: "3" 3 | depends: "q2" -------------------------------------------------------------------------------- /p1-search/test_cases/q6/CONFIG: -------------------------------------------------------------------------------- 1 | class: "Q6PartialCreditQuestion" 2 | max_points: "3" 3 | depends: "q4" -------------------------------------------------------------------------------- /p1-search/test_cases/q7/CONFIG: -------------------------------------------------------------------------------- 1 | class: "PartialCreditQuestion" 2 | max_points: "4" 3 | depends: "q4" -------------------------------------------------------------------------------- /p1-search/test_cases/q8/CONFIG: -------------------------------------------------------------------------------- 1 | class: "PassAllTestsQuestion" 2 | max_points: "3" -------------------------------------------------------------------------------- /p1-search/textDisplay.py: -------------------------------------------------------------------------------- 1 | # textDisplay.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import time 16 | try: 17 | import pacman 18 | except: 19 | pass 20 | 21 | DRAW_EVERY = 1 22 | SLEEP_TIME = 0 # This can be overwritten by __init__ 23 | DISPLAY_MOVES = False 24 | QUIET = False # Supresses output 25 | 26 | class NullGraphics: 27 | def initialize(self, state, isBlue = False): 28 | pass 29 | 30 | def update(self, state): 31 | pass 32 | 33 | def checkNullDisplay(self): 34 | return True 35 | 36 | def pause(self): 37 | time.sleep(SLEEP_TIME) 38 | 39 | def draw(self, state): 40 | print(state) 41 | 42 | def updateDistributions(self, dist): 43 | pass 44 | 45 | def finish(self): 46 | pass 47 | 48 | class PacmanGraphics: 49 | def __init__(self, speed=None): 50 | if speed != None: 51 | global SLEEP_TIME 52 | SLEEP_TIME = speed 53 | 54 | def initialize(self, state, isBlue = False): 55 | self.draw(state) 56 | self.pause() 57 | self.turn = 0 58 | self.agentCounter = 0 59 | 60 | def update(self, state): 61 | numAgents = len(state.agentStates) 62 | self.agentCounter = (self.agentCounter + 1) % numAgents 63 | if self.agentCounter == 0: 64 | self.turn += 1 65 | if DISPLAY_MOVES: 66 | ghosts = [pacman.nearestPoint(state.getGhostPosition(i)) for i in range(1, numAgents)] 67 | print("%4d) P: %-8s" % (self.turn, str(pacman.nearestPoint(state.getPacmanPosition()))),'| Score: %-5d' % state.score,'| Ghosts:', ghosts) 68 | if self.turn % DRAW_EVERY == 0: 69 | self.draw(state) 70 | self.pause() 71 | if state._win or state._lose: 72 | self.draw(state) 73 | 74 | def pause(self): 75 | time.sleep(SLEEP_TIME) 76 | 77 | def draw(self, state): 78 | print(state) 79 | 80 | def finish(self): 81 | pass 82 | -------------------------------------------------------------------------------- /p2-multiagent/VERSION: -------------------------------------------------------------------------------- 1 | v1.004 2 | -------------------------------------------------------------------------------- /p2-multiagent/ghostAgents.py: -------------------------------------------------------------------------------- 1 | # ghostAgents.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from game import Agent 16 | from game import Actions 17 | from game import Directions 18 | import random 19 | from util import manhattanDistance 20 | import util 21 | 22 | 23 | class GhostAgent(Agent): 24 | def __init__(self, index): 25 | self.index = index 26 | 27 | def getAction(self, state): 28 | dist = self.getDistribution(state) 29 | if len(dist) == 0: 30 | return Directions.STOP 31 | else: 32 | return util.chooseFromDistribution(dist) 33 | 34 | def getDistribution(self, state): 35 | "Returns a Counter encoding a distribution over actions from the provided state." 36 | util.raiseNotDefined() 37 | 38 | 39 | class RandomGhost(GhostAgent): 40 | "A ghost that chooses a legal action uniformly at random." 41 | 42 | def getDistribution(self, state): 43 | dist = util.Counter() 44 | for a in state.getLegalActions(self.index): 45 | dist[a] = 1.0 46 | dist.normalize() 47 | return dist 48 | 49 | 50 | class DirectionalGhost(GhostAgent): 51 | "A ghost that prefers to rush Pacman, or flee when scared." 52 | 53 | def __init__(self, index, prob_attack=0.8, prob_scaredFlee=0.8): 54 | self.index = index 55 | self.prob_attack = prob_attack 56 | self.prob_scaredFlee = prob_scaredFlee 57 | 58 | def getDistribution(self, state): 59 | # Read variables from state 60 | ghostState = state.getGhostState(self.index) 61 | legalActions = state.getLegalActions(self.index) 62 | pos = state.getGhostPosition(self.index) 63 | isScared = ghostState.scaredTimer > 0 64 | 65 | speed = 1 66 | if isScared: 67 | speed = 0.5 68 | 69 | actionVectors = [Actions.directionToVector( 70 | a, speed) for a in legalActions] 71 | newPositions = [(pos[0]+a[0], pos[1]+a[1]) for a in actionVectors] 72 | pacmanPosition = state.getPacmanPosition() 73 | 74 | # Select best actions given the state 75 | distancesToPacman = [manhattanDistance( 76 | pos, pacmanPosition) for pos in newPositions] 77 | if isScared: 78 | bestScore = max(distancesToPacman) 79 | bestProb = self.prob_scaredFlee 80 | else: 81 | bestScore = min(distancesToPacman) 82 | bestProb = self.prob_attack 83 | bestActions = [action for action, distance in zip( 84 | legalActions, distancesToPacman) if distance == bestScore] 85 | 86 | # Construct distribution 87 | dist = util.Counter() 88 | for a in bestActions: 89 | dist[a] = bestProb / len(bestActions) 90 | for a in legalActions: 91 | dist[a] += (1-bestProb) / len(legalActions) 92 | dist.normalize() 93 | return dist 94 | -------------------------------------------------------------------------------- /p2-multiagent/keyboardAgents.py: -------------------------------------------------------------------------------- 1 | # keyboardAgents.py 2 | # ----------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from game import Agent 16 | from game import Directions 17 | import random 18 | 19 | 20 | class KeyboardAgent(Agent): 21 | """ 22 | An agent controlled by the keyboard. 23 | """ 24 | # NOTE: Arrow keys also work. 25 | WEST_KEY = 'a' 26 | EAST_KEY = 'd' 27 | NORTH_KEY = 'w' 28 | SOUTH_KEY = 's' 29 | STOP_KEY = 'q' 30 | 31 | def __init__(self, index=0): 32 | 33 | self.lastMove = Directions.STOP 34 | self.index = index 35 | self.keys = [] 36 | 37 | def getAction(self, state): 38 | from graphicsUtils import keys_waiting 39 | from graphicsUtils import keys_pressed 40 | keys = keys_waiting() + keys_pressed() 41 | if keys != []: 42 | self.keys = keys 43 | 44 | legal = state.getLegalActions(self.index) 45 | move = self.getMove(legal) 46 | 47 | if move == Directions.STOP: 48 | # Try to move in the same direction as before 49 | if self.lastMove in legal: 50 | move = self.lastMove 51 | 52 | if (self.STOP_KEY in self.keys) and Directions.STOP in legal: 53 | move = Directions.STOP 54 | 55 | if move not in legal: 56 | move = random.choice(legal) 57 | 58 | self.lastMove = move 59 | return move 60 | 61 | def getMove(self, legal): 62 | move = Directions.STOP 63 | if (self.WEST_KEY in self.keys or 'Left' in self.keys) and Directions.WEST in legal: 64 | move = Directions.WEST 65 | if (self.EAST_KEY in self.keys or 'Right' in self.keys) and Directions.EAST in legal: 66 | move = Directions.EAST 67 | if (self.NORTH_KEY in self.keys or 'Up' in self.keys) and Directions.NORTH in legal: 68 | move = Directions.NORTH 69 | if (self.SOUTH_KEY in self.keys or 'Down' in self.keys) and Directions.SOUTH in legal: 70 | move = Directions.SOUTH 71 | return move 72 | 73 | 74 | class KeyboardAgent2(KeyboardAgent): 75 | """ 76 | A second agent controlled by the keyboard. 77 | """ 78 | # NOTE: Arrow keys also work. 79 | WEST_KEY = 'j' 80 | EAST_KEY = "l" 81 | NORTH_KEY = 'i' 82 | SOUTH_KEY = 'k' 83 | STOP_KEY = 'u' 84 | 85 | def getMove(self, legal): 86 | move = Directions.STOP 87 | if (self.WEST_KEY in self.keys) and Directions.WEST in legal: 88 | move = Directions.WEST 89 | if (self.EAST_KEY in self.keys) and Directions.EAST in legal: 90 | move = Directions.EAST 91 | if (self.NORTH_KEY in self.keys) and Directions.NORTH in legal: 92 | move = Directions.NORTH 93 | if (self.SOUTH_KEY in self.keys) and Directions.SOUTH in legal: 94 | move = Directions.SOUTH 95 | return move 96 | -------------------------------------------------------------------------------- /p2-multiagent/layout.py: -------------------------------------------------------------------------------- 1 | # layout.py 2 | # --------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from util import manhattanDistance 16 | from game import Grid 17 | import os 18 | import random 19 | from functools import reduce 20 | 21 | VISIBILITY_MATRIX_CACHE = {} 22 | 23 | 24 | class Layout: 25 | """ 26 | A Layout manages the static information about the game board. 27 | """ 28 | 29 | def __init__(self, layoutText): 30 | self.width = len(layoutText[0]) 31 | self.height = len(layoutText) 32 | self.walls = Grid(self.width, self.height, False) 33 | self.food = Grid(self.width, self.height, False) 34 | self.capsules = [] 35 | self.agentPositions = [] 36 | self.numGhosts = 0 37 | self.processLayoutText(layoutText) 38 | self.layoutText = layoutText 39 | self.totalFood = len(self.food.asList()) 40 | # self.initializeVisibilityMatrix() 41 | 42 | def getNumGhosts(self): 43 | return self.numGhosts 44 | 45 | def initializeVisibilityMatrix(self): 46 | global VISIBILITY_MATRIX_CACHE 47 | if reduce(str.__add__, self.layoutText) not in VISIBILITY_MATRIX_CACHE: 48 | from game import Directions 49 | vecs = [(-0.5, 0), (0.5, 0), (0, -0.5), (0, 0.5)] 50 | dirs = [Directions.NORTH, Directions.SOUTH, 51 | Directions.WEST, Directions.EAST] 52 | vis = Grid(self.width, self.height, {Directions.NORTH: set(), Directions.SOUTH: set( 53 | ), Directions.EAST: set(), Directions.WEST: set(), Directions.STOP: set()}) 54 | for x in range(self.width): 55 | for y in range(self.height): 56 | if self.walls[x][y] == False: 57 | for vec, direction in zip(vecs, dirs): 58 | dx, dy = vec 59 | nextx, nexty = x + dx, y + dy 60 | while (nextx + nexty) != int(nextx) + int(nexty) or not self.walls[int(nextx)][int(nexty)]: 61 | vis[x][y][direction].add((nextx, nexty)) 62 | nextx, nexty = x + dx, y + dy 63 | self.visibility = vis 64 | VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)] = vis 65 | else: 66 | self.visibility = VISIBILITY_MATRIX_CACHE[reduce( 67 | str.__add__, self.layoutText)] 68 | 69 | def isWall(self, pos): 70 | x, col = pos 71 | return self.walls[x][col] 72 | 73 | def getRandomLegalPosition(self): 74 | x = random.choice(list(range(self.width))) 75 | y = random.choice(list(range(self.height))) 76 | while self.isWall((x, y)): 77 | x = random.choice(list(range(self.width))) 78 | y = random.choice(list(range(self.height))) 79 | return (x, y) 80 | 81 | def getRandomCorner(self): 82 | poses = [(1, 1), (1, self.height - 2), (self.width - 2, 1), 83 | (self.width - 2, self.height - 2)] 84 | return random.choice(poses) 85 | 86 | def getFurthestCorner(self, pacPos): 87 | poses = [(1, 1), (1, self.height - 2), (self.width - 2, 1), 88 | (self.width - 2, self.height - 2)] 89 | dist, pos = max([(manhattanDistance(p, pacPos), p) for p in poses]) 90 | return pos 91 | 92 | def isVisibleFrom(self, ghostPos, pacPos, pacDirection): 93 | row, col = [int(x) for x in pacPos] 94 | return ghostPos in self.visibility[row][col][pacDirection] 95 | 96 | def __str__(self): 97 | return "\n".join(self.layoutText) 98 | 99 | def deepCopy(self): 100 | return Layout(self.layoutText[:]) 101 | 102 | def processLayoutText(self, layoutText): 103 | """ 104 | Coordinates are flipped from the input format to the (x,y) convention here 105 | 106 | The shape of the maze. Each character 107 | represents a different type of object. 108 | % - Wall 109 | . - Food 110 | o - Capsule 111 | G - Ghost 112 | P - Pacman 113 | Other characters are ignored. 114 | """ 115 | maxY = self.height - 1 116 | for y in range(self.height): 117 | for x in range(self.width): 118 | layoutChar = layoutText[maxY - y][x] 119 | self.processLayoutChar(x, y, layoutChar) 120 | self.agentPositions.sort() 121 | self.agentPositions = [(i == 0, pos) for i, pos in self.agentPositions] 122 | 123 | def processLayoutChar(self, x, y, layoutChar): 124 | if layoutChar == '%': 125 | self.walls[x][y] = True 126 | elif layoutChar == '.': 127 | self.food[x][y] = True 128 | elif layoutChar == 'o': 129 | self.capsules.append((x, y)) 130 | elif layoutChar == 'P': 131 | self.agentPositions.append((0, (x, y))) 132 | elif layoutChar in ['G']: 133 | self.agentPositions.append((1, (x, y))) 134 | self.numGhosts += 1 135 | elif layoutChar in ['1', '2', '3', '4']: 136 | self.agentPositions.append((int(layoutChar), (x, y))) 137 | self.numGhosts += 1 138 | 139 | 140 | def getLayout(name, back=2): 141 | if name.endswith('.lay'): 142 | layout = tryToLoad('layouts/' + name) 143 | if layout == None: 144 | layout = tryToLoad(name) 145 | else: 146 | layout = tryToLoad('layouts/' + name + '.lay') 147 | if layout == None: 148 | layout = tryToLoad(name + '.lay') 149 | if layout == None and back >= 0: 150 | curdir = os.path.abspath('.') 151 | os.chdir('..') 152 | layout = getLayout(name, back - 1) 153 | os.chdir(curdir) 154 | return layout 155 | 156 | 157 | def tryToLoad(fullname): 158 | if(not os.path.exists(fullname)): 159 | return None 160 | f = open(fullname) 161 | try: 162 | return Layout([line.strip() for line in f]) 163 | finally: 164 | f.close() 165 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/capsuleClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%% 2 | %G. G ....% 3 | %.% % %%%%%% %.%%.% 4 | %.%o% % o% %.o%.% 5 | %.%%%.% %%% %..%.% 6 | %..... P %..%G% 7 | %%%%%%%%%%%%%%%%%%%% 8 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/contestClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%% 2 | %o...%........%...o% 3 | %.%%.%.%%..%%.%.%%.% 4 | %...... G GG%......% 5 | %.%.%%.%% %%%.%%.%.% 6 | %.%....% ooo%.%..%.% 7 | %.%.%%.% %% %.%.%%.% 8 | %o%......P....%....% 9 | %%%%%%%%%%%%%%%%%%%% 10 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/mediumClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%% 2 | %o...%........%....% 3 | %.%%.%.%%%%%%.%.%%.% 4 | %.%..............%.% 5 | %.%.%%.%% %%.%%.%.% 6 | %......%G G%......% 7 | %.%.%%.%%%%%%.%%.%.% 8 | %.%..............%.% 9 | %.%%.%.%%%%%%.%.%%.% 10 | %....%...P....%...o% 11 | %%%%%%%%%%%%%%%%%%%% 12 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/minimaxClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%%% 2 | %.P G% 3 | % %.%G%%% 4 | %G %%% 5 | %%%%%%%%% 6 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/openClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%% 2 | %.. P .... .... % 3 | %.. ... ... ... ... % 4 | %.. ... ... ... ... % 5 | %.. .... .... G % 6 | %.. ... ... ... ... % 7 | %.. ... ... ... ... % 8 | %.. .... .... o% 9 | %%%%%%%%%%%%%%%%%%%%%%%%% 10 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/originalClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | %............%%............% 3 | %.%%%%.%%%%%.%%.%%%%%.%%%%.% 4 | %o%%%%.%%%%%.%%.%%%%%.%%%%o% 5 | %.%%%%.%%%%%.%%.%%%%%.%%%%.% 6 | %..........................% 7 | %.%%%%.%%.%%%%%%%%.%%.%%%%.% 8 | %.%%%%.%%.%%%%%%%%.%%.%%%%.% 9 | %......%%....%%....%%......% 10 | %%%%%%.%%%%% %% %%%%%.%%%%%% 11 | %%%%%%.%%%%% %% %%%%%.%%%%%% 12 | %%%%%%.% %.%%%%%% 13 | %%%%%%.% %%%% %%%% %.%%%%%% 14 | % . %G GG G% . % 15 | %%%%%%.% %%%%%%%%%% %.%%%%%% 16 | %%%%%%.% %.%%%%%% 17 | %%%%%%.% %%%%%%%%%% %.%%%%%% 18 | %............%%............% 19 | %.%%%%.%%%%%.%%.%%%%%.%%%%.% 20 | %.%%%%.%%%%%.%%.%%%%%.%%%%.% 21 | %o..%%....... .......%%..o% 22 | %%%.%%.%%.%%%%%%%%.%%.%%.%%% 23 | %%%.%%.%%.%%%%%%%%.%%.%%.%%% 24 | %......%%....%%....%%......% 25 | %.%%%%%%%%%%.%%.%%%%%%%%%%.% 26 | %.............P............% 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/powerClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%% 2 | %o....o%GGGG%o....o% 3 | %..%...%% %%...%..% 4 | %.%o.%........%.o%.% 5 | %.o%.%.%%%%%%.%.%o.% 6 | %........P.........% 7 | %%%%%%%%%%%%%%%%%%%% 8 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/smallClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%% 2 | %......%G G%......% 3 | %.%%...%% %%...%%.% 4 | %.%o.%........%.o%.% 5 | %.%%.%.%%%%%%.%.%%.% 6 | %........P.........% 7 | %%%%%%%%%%%%%%%%%%%% 8 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/testClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%% 2 | % . % 3 | %.G.% 4 | % . % 5 | %. .% 6 | % % 7 | % .% 8 | % % 9 | %P .% 10 | %%%%% 11 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/trappedClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%% 2 | % P G% 3 | %G%%%%%% 4 | %.... % 5 | %%%%%%%% 6 | -------------------------------------------------------------------------------- /p2-multiagent/layouts/trickyClassic.lay: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%% 2 | %o...%........%...o% 3 | %.%%.%.%%..%%.%.%%.% 4 | %.%.....%..%.....%.% 5 | %.%.%%.%% %%.%%.%.% 6 | %...... GGGG%.%....% 7 | %.%....%%%%%%.%..%.% 8 | %.%....% oo%.%..%.% 9 | %.%....% %%%%.%..%.% 10 | %.%...........%..%.% 11 | %.%%.%.%%%%%%.%.%%.% 12 | %o...%...P....%...o% 13 | %%%%%%%%%%%%%%%%%%%% 14 | -------------------------------------------------------------------------------- /p2-multiagent/pacmanAgents.py: -------------------------------------------------------------------------------- 1 | # pacmanAgents.py 2 | # --------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from pacman import Directions 16 | from game import Agent 17 | import random 18 | import game 19 | import util 20 | 21 | 22 | class LeftTurnAgent(game.Agent): 23 | "An agent that turns left at every opportunity" 24 | 25 | def getAction(self, state): 26 | legal = state.getLegalPacmanActions() 27 | current = state.getPacmanState().configuration.direction 28 | if current == Directions.STOP: 29 | current = Directions.NORTH 30 | left = Directions.LEFT[current] 31 | if left in legal: 32 | return left 33 | if current in legal: 34 | return current 35 | if Directions.RIGHT[current] in legal: 36 | return Directions.RIGHT[current] 37 | if Directions.LEFT[left] in legal: 38 | return Directions.LEFT[left] 39 | return Directions.STOP 40 | 41 | 42 | class GreedyAgent(Agent): 43 | def __init__(self, evalFn="scoreEvaluation"): 44 | self.evaluationFunction = util.lookup(evalFn, globals()) 45 | assert self.evaluationFunction != None 46 | 47 | def getAction(self, state): 48 | # Generate candidate actions 49 | legal = state.getLegalPacmanActions() 50 | if Directions.STOP in legal: 51 | legal.remove(Directions.STOP) 52 | 53 | successors = [(state.generateSuccessor(0, action), action) 54 | for action in legal] 55 | scored = [(self.evaluationFunction(state), action) 56 | for state, action in successors] 57 | bestScore = max(scored)[0] 58 | bestActions = [pair[1] for pair in scored if pair[0] == bestScore] 59 | return random.choice(bestActions) 60 | 61 | 62 | def scoreEvaluation(state): 63 | return state.getScore() 64 | -------------------------------------------------------------------------------- /p2-multiagent/projectParams.py: -------------------------------------------------------------------------------- 1 | # projectParams.py 2 | # ---------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | STUDENT_CODE_DEFAULT = 'multiAgents.py' 16 | PROJECT_TEST_CLASSES = 'multiagentTestClasses.py' 17 | PROJECT_NAME = 'Project 2: Multiagent search' 18 | BONUS_PIC = False 19 | -------------------------------------------------------------------------------- /p2-multiagent/testParser.py: -------------------------------------------------------------------------------- 1 | # testParser.py 2 | # ------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import re 16 | import sys 17 | 18 | 19 | class TestParser(object): 20 | 21 | def __init__(self, path): 22 | # save the path to the test file 23 | self.path = path 24 | 25 | def removeComments(self, rawlines): 26 | # remove any portion of a line following a '#' symbol 27 | fixed_lines = [] 28 | for l in rawlines: 29 | idx = l.find('#') 30 | if idx == -1: 31 | fixed_lines.append(l) 32 | else: 33 | fixed_lines.append(l[0:idx]) 34 | return '\n'.join(fixed_lines) 35 | 36 | def parse(self): 37 | # read in the test case and remove comments 38 | test = {} 39 | with open(self.path) as handle: 40 | raw_lines = handle.read().split('\n') 41 | 42 | test_text = self.removeComments(raw_lines) 43 | test['__raw_lines__'] = raw_lines 44 | test['path'] = self.path 45 | test['__emit__'] = [] 46 | lines = test_text.split('\n') 47 | i = 0 48 | # read a property in each loop cycle 49 | while(i < len(lines)): 50 | # skip blank lines 51 | if re.match('\A\s*\Z', lines[i]): 52 | test['__emit__'].append(("raw", raw_lines[i])) 53 | i += 1 54 | continue 55 | m = re.match('\A([^"]*?):\s*"([^"]*)"\s*\Z', lines[i]) 56 | if m: 57 | test[m.group(1)] = m.group(2) 58 | test['__emit__'].append(("oneline", m.group(1))) 59 | i += 1 60 | continue 61 | m = re.match('\A([^"]*?):\s*"""\s*\Z', lines[i]) 62 | if m: 63 | msg = [] 64 | i += 1 65 | while(not re.match('\A\s*"""\s*\Z', lines[i])): 66 | msg.append(raw_lines[i]) 67 | i += 1 68 | test[m.group(1)] = '\n'.join(msg) 69 | test['__emit__'].append(("multiline", m.group(1))) 70 | i += 1 71 | continue 72 | print('error parsing test file: %s' % self.path) 73 | sys.exit(1) 74 | return test 75 | 76 | 77 | def emitTestDict(testDict, handle): 78 | for kind, data in testDict['__emit__']: 79 | if kind == "raw": 80 | handle.write(data + "\n") 81 | elif kind == "oneline": 82 | handle.write('%s: "%s"\n' % (data, testDict[data])) 83 | elif kind == "multiline": 84 | handle.write('%s: """\n%s\n"""\n' % (data, testDict[data])) 85 | else: 86 | raise Exception("Bad __emit__") 87 | -------------------------------------------------------------------------------- /p2-multiagent/test_cases/CONFIG: -------------------------------------------------------------------------------- 1 | order: "q1 q2 q3 q4 q5" 2 | -------------------------------------------------------------------------------- /p2-multiagent/test_cases/extra/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "0" 2 | class: "PartialCreditQuestion" 3 | -------------------------------------------------------------------------------- /p2-multiagent/test_cases/q1/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "4" 2 | class: "PartialCreditQuestion" 3 | -------------------------------------------------------------------------------- /p2-multiagent/test_cases/q2/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "5" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p2-multiagent/test_cases/q3/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "5" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p2-multiagent/test_cases/q4/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "5" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p2-multiagent/test_cases/q5/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "6" 2 | class: "PartialCreditQuestion" 3 | -------------------------------------------------------------------------------- /p2-multiagent/textDisplay.py: -------------------------------------------------------------------------------- 1 | # textDisplay.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import time 16 | try: 17 | import pacman 18 | except: 19 | pass 20 | 21 | DRAW_EVERY = 1 22 | SLEEP_TIME = 0 # This can be overwritten by __init__ 23 | DISPLAY_MOVES = False 24 | QUIET = False # Supresses output 25 | 26 | 27 | class NullGraphics: 28 | def initialize(self, state, isBlue=False): 29 | pass 30 | 31 | def update(self, state): 32 | pass 33 | 34 | def checkNullDisplay(self): 35 | return True 36 | 37 | def pause(self): 38 | time.sleep(SLEEP_TIME) 39 | 40 | def draw(self, state): 41 | print(state) 42 | 43 | def updateDistributions(self, dist): 44 | pass 45 | 46 | def finish(self): 47 | pass 48 | 49 | 50 | class PacmanGraphics: 51 | def __init__(self, speed=None): 52 | if speed != None: 53 | global SLEEP_TIME 54 | SLEEP_TIME = speed 55 | 56 | def initialize(self, state, isBlue=False): 57 | self.draw(state) 58 | self.pause() 59 | self.turn = 0 60 | self.agentCounter = 0 61 | 62 | def update(self, state): 63 | numAgents = len(state.agentStates) 64 | self.agentCounter = (self.agentCounter + 1) % numAgents 65 | if self.agentCounter == 0: 66 | self.turn += 1 67 | if DISPLAY_MOVES: 68 | ghosts = [pacman.nearestPoint( 69 | state.getGhostPosition(i)) for i in range(1, numAgents)] 70 | print("%4d) P: %-8s" % (self.turn, str(pacman.nearestPoint(state.getPacmanPosition()))), 71 | '| Score: %-5d' % state.score, '| Ghosts:', ghosts) 72 | if self.turn % DRAW_EVERY == 0: 73 | self.draw(state) 74 | self.pause() 75 | if state._win or state._lose: 76 | self.draw(state) 77 | 78 | def pause(self): 79 | time.sleep(SLEEP_TIME) 80 | 81 | def draw(self, state): 82 | print(state) 83 | 84 | def finish(self): 85 | pass 86 | -------------------------------------------------------------------------------- /p3-rl/VERSION: -------------------------------------------------------------------------------- 1 | v1.001 2 | -------------------------------------------------------------------------------- /p3-rl/analysis.py: -------------------------------------------------------------------------------- 1 | # analysis.py 2 | # ----------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | ###################### 16 | # ANALYSIS QUESTIONS # 17 | ###################### 18 | 19 | # Set the given parameters to obtain the specified policies through 20 | # value iteration. 21 | 22 | def question2(): 23 | answerDiscount = 0.9 24 | answerNoise = 0. 25 | return answerDiscount, answerNoise 26 | 27 | def question3a(): 28 | answerDiscount = .8 29 | answerNoise = 0. 30 | answerLivingReward = -4 31 | return answerDiscount, answerNoise, answerLivingReward 32 | # If not possible, return 'NOT POSSIBLE' 33 | 34 | def question3b(): 35 | answerDiscount = .2 36 | answerNoise = 0.21 37 | answerLivingReward = .6 38 | return answerDiscount, answerNoise, answerLivingReward 39 | # If not possible, return 'NOT POSSIBLE' 40 | 41 | def question3c(): 42 | answerDiscount = 1 43 | answerNoise = 0. 44 | answerLivingReward = -1 45 | return answerDiscount, answerNoise, answerLivingReward 46 | # If not possible, return 'NOT POSSIBLE' 47 | 48 | def question3d(): 49 | answerDiscount = .7 50 | answerNoise = .4 51 | answerLivingReward = 2 52 | return answerDiscount, answerNoise, answerLivingReward 53 | # If not possible, return 'NOT POSSIBLE' 54 | 55 | def question3e(): 56 | answerDiscount = 0 57 | answerNoise = 1 58 | answerLivingReward = 0 59 | return answerDiscount, answerNoise, answerLivingReward 60 | # If not possible, return 'NOT POSSIBLE' 61 | 62 | def question8(): 63 | answerEpsilon = .1 64 | answerLearningRate = .5 65 | # return answerEpsilon, answerLearningRate 66 | return 'NOT POSSIBLE' 67 | # If not possible, return 'NOT POSSIBLE' 68 | 69 | if __name__ == '__main__': 70 | print('Answers to analysis questions:') 71 | import analysis 72 | for q in [q for q in dir(analysis) if q.startswith('question')]: 73 | response = getattr(analysis, q)() 74 | print(' Question %s:\t%s' % (q, str(response))) 75 | -------------------------------------------------------------------------------- /p3-rl/environment.py: -------------------------------------------------------------------------------- 1 | # environment.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | #!/usr/bin/python 16 | 17 | class Environment: 18 | 19 | def getCurrentState(self): 20 | """ 21 | Returns the current state of enviornment 22 | """ 23 | abstract 24 | 25 | def getPossibleActions(self, state): 26 | """ 27 | Returns possible actions the agent 28 | can take in the given state. Can 29 | return the empty list if we are in 30 | a terminal state. 31 | """ 32 | abstract 33 | 34 | def doAction(self, action): 35 | """ 36 | Performs the given action in the current 37 | environment state and updates the enviornment. 38 | 39 | Returns a (reward, nextState) pair 40 | """ 41 | abstract 42 | 43 | def reset(self): 44 | """ 45 | Resets the current state to the start state 46 | """ 47 | abstract 48 | 49 | def isTerminal(self): 50 | """ 51 | Has the enviornment entered a terminal 52 | state? This means there are no successors 53 | """ 54 | state = self.getCurrentState() 55 | actions = self.getPossibleActions(state) 56 | return len(actions) == 0 57 | -------------------------------------------------------------------------------- /p3-rl/featureExtractors.py: -------------------------------------------------------------------------------- 1 | # featureExtractors.py 2 | # -------------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | "Feature extractors for Pacman game states" 16 | 17 | from game import Directions, Actions 18 | import util 19 | 20 | class FeatureExtractor: 21 | def getFeatures(self, state, action): 22 | """ 23 | Returns a dict from features to counts 24 | Usually, the count will just be 1.0 for 25 | indicator functions. 26 | """ 27 | util.raiseNotDefined() 28 | 29 | class IdentityExtractor(FeatureExtractor): 30 | def getFeatures(self, state, action): 31 | feats = util.Counter() 32 | feats[(state,action)] = 1.0 33 | return feats 34 | 35 | class CoordinateExtractor(FeatureExtractor): 36 | def getFeatures(self, state, action): 37 | feats = util.Counter() 38 | feats[state] = 1.0 39 | feats['x=%d' % state[0]] = 1.0 40 | feats['y=%d' % state[0]] = 1.0 41 | feats['action=%s' % action] = 1.0 42 | return feats 43 | 44 | def closestFood(pos, food, walls): 45 | """ 46 | closestFood -- this is similar to the function that we have 47 | worked on in the search project; here its all in one place 48 | """ 49 | fringe = [(pos[0], pos[1], 0)] 50 | expanded = set() 51 | while fringe: 52 | pos_x, pos_y, dist = fringe.pop(0) 53 | if (pos_x, pos_y) in expanded: 54 | continue 55 | expanded.add((pos_x, pos_y)) 56 | # if we find a food at this location then exit 57 | if food[pos_x][pos_y]: 58 | return dist 59 | # otherwise spread out from the location to its neighbours 60 | nbrs = Actions.getLegalNeighbors((pos_x, pos_y), walls) 61 | for nbr_x, nbr_y in nbrs: 62 | fringe.append((nbr_x, nbr_y, dist+1)) 63 | # no food found 64 | return None 65 | 66 | class SimpleExtractor(FeatureExtractor): 67 | """ 68 | Returns simple features for a basic reflex Pacman: 69 | - whether food will be eaten 70 | - how far away the next food is 71 | - whether a ghost collision is imminent 72 | - whether a ghost is one step away 73 | """ 74 | 75 | def getFeatures(self, state, action): 76 | # extract the grid of food and wall locations and get the ghost locations 77 | food = state.getFood() 78 | walls = state.getWalls() 79 | ghosts = state.getGhostPositions() 80 | 81 | features = util.Counter() 82 | 83 | features["bias"] = 1.0 84 | 85 | # compute the location of pacman after he takes the action 86 | x, y = state.getPacmanPosition() 87 | dx, dy = Actions.directionToVector(action) 88 | next_x, next_y = int(x + dx), int(y + dy) 89 | 90 | # count the number of ghosts 1-step away 91 | features["#-of-ghosts-1-step-away"] = sum((next_x, next_y) in Actions.getLegalNeighbors(g, walls) for g in ghosts) 92 | 93 | # if there is no danger of ghosts then add the food feature 94 | if not features["#-of-ghosts-1-step-away"] and food[next_x][next_y]: 95 | features["eats-food"] = 1.0 96 | 97 | dist = closestFood((next_x, next_y), food, walls) 98 | if dist is not None: 99 | # make the distance a number less than one otherwise the update 100 | # will diverge wildly 101 | features["closest-food"] = float(dist) / (walls.width * walls.height) 102 | features.divideAll(10.0) 103 | return features 104 | -------------------------------------------------------------------------------- /p3-rl/ghostAgents.py: -------------------------------------------------------------------------------- 1 | # ghostAgents.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from game import Agent 16 | from game import Actions 17 | from game import Directions 18 | import random 19 | from util import manhattanDistance 20 | import util 21 | 22 | 23 | class GhostAgent(Agent): 24 | def __init__(self, index): 25 | self.index = index 26 | 27 | def getAction(self, state): 28 | dist = self.getDistribution(state) 29 | if len(dist) == 0: 30 | return Directions.STOP 31 | else: 32 | return util.chooseFromDistribution(dist) 33 | 34 | def getDistribution(self, state): 35 | "Returns a Counter encoding a distribution over actions from the provided state." 36 | util.raiseNotDefined() 37 | 38 | 39 | class RandomGhost(GhostAgent): 40 | "A ghost that chooses a legal action uniformly at random." 41 | 42 | def getDistribution(self, state): 43 | dist = util.Counter() 44 | for a in state.getLegalActions(self.index): 45 | dist[a] = 1.0 46 | dist.normalize() 47 | return dist 48 | 49 | 50 | class DirectionalGhost(GhostAgent): 51 | "A ghost that prefers to rush Pacman, or flee when scared." 52 | 53 | def __init__(self, index, prob_attack=0.8, prob_scaredFlee=0.8): 54 | self.index = index 55 | self.prob_attack = prob_attack 56 | self.prob_scaredFlee = prob_scaredFlee 57 | 58 | def getDistribution(self, state): 59 | # Read variables from state 60 | ghostState = state.getGhostState(self.index) 61 | legalActions = state.getLegalActions(self.index) 62 | pos = state.getGhostPosition(self.index) 63 | isScared = ghostState.scaredTimer > 0 64 | 65 | speed = 1 66 | if isScared: 67 | speed = 0.5 68 | 69 | actionVectors = [Actions.directionToVector( 70 | a, speed) for a in legalActions] 71 | newPositions = [(pos[0]+a[0], pos[1]+a[1]) for a in actionVectors] 72 | pacmanPosition = state.getPacmanPosition() 73 | 74 | # Select best actions given the state 75 | distancesToPacman = [manhattanDistance( 76 | pos, pacmanPosition) for pos in newPositions] 77 | if isScared: 78 | bestScore = max(distancesToPacman) 79 | bestProb = self.prob_scaredFlee 80 | else: 81 | bestScore = min(distancesToPacman) 82 | bestProb = self.prob_attack 83 | bestActions = [action for action, distance in zip( 84 | legalActions, distancesToPacman) if distance == bestScore] 85 | 86 | # Construct distribution 87 | dist = util.Counter() 88 | for a in bestActions: 89 | dist[a] = bestProb / len(bestActions) 90 | for a in legalActions: 91 | dist[a] += (1-bestProb) / len(legalActions) 92 | dist.normalize() 93 | return dist 94 | -------------------------------------------------------------------------------- /p3-rl/keyboardAgents.py: -------------------------------------------------------------------------------- 1 | # keyboardAgents.py 2 | # ----------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from game import Agent 16 | from game import Directions 17 | import random 18 | 19 | 20 | class KeyboardAgent(Agent): 21 | """ 22 | An agent controlled by the keyboard. 23 | """ 24 | # NOTE: Arrow keys also work. 25 | WEST_KEY = 'a' 26 | EAST_KEY = 'd' 27 | NORTH_KEY = 'w' 28 | SOUTH_KEY = 's' 29 | STOP_KEY = 'q' 30 | 31 | def __init__(self, index=0): 32 | 33 | self.lastMove = Directions.STOP 34 | self.index = index 35 | self.keys = [] 36 | 37 | def getAction(self, state): 38 | from graphicsUtils import keys_waiting 39 | from graphicsUtils import keys_pressed 40 | keys = keys_waiting() + keys_pressed() 41 | if keys != []: 42 | self.keys = keys 43 | 44 | legal = state.getLegalActions(self.index) 45 | move = self.getMove(legal) 46 | 47 | if move == Directions.STOP: 48 | # Try to move in the same direction as before 49 | if self.lastMove in legal: 50 | move = self.lastMove 51 | 52 | if (self.STOP_KEY in self.keys) and Directions.STOP in legal: 53 | move = Directions.STOP 54 | 55 | if move not in legal: 56 | move = random.choice(legal) 57 | 58 | self.lastMove = move 59 | return move 60 | 61 | def getMove(self, legal): 62 | move = Directions.STOP 63 | if (self.WEST_KEY in self.keys or 'Left' in self.keys) and Directions.WEST in legal: 64 | move = Directions.WEST 65 | if (self.EAST_KEY in self.keys or 'Right' in self.keys) and Directions.EAST in legal: 66 | move = Directions.EAST 67 | if (self.NORTH_KEY in self.keys or 'Up' in self.keys) and Directions.NORTH in legal: 68 | move = Directions.NORTH 69 | if (self.SOUTH_KEY in self.keys or 'Down' in self.keys) and Directions.SOUTH in legal: 70 | move = Directions.SOUTH 71 | return move 72 | 73 | 74 | class KeyboardAgent2(KeyboardAgent): 75 | """ 76 | A second agent controlled by the keyboard. 77 | """ 78 | # NOTE: Arrow keys also work. 79 | WEST_KEY = 'j' 80 | EAST_KEY = "l" 81 | NORTH_KEY = 'i' 82 | SOUTH_KEY = 'k' 83 | STOP_KEY = 'u' 84 | 85 | def getMove(self, legal): 86 | move = Directions.STOP 87 | if (self.WEST_KEY in self.keys) and Directions.WEST in legal: 88 | move = Directions.WEST 89 | if (self.EAST_KEY in self.keys) and Directions.EAST in legal: 90 | move = Directions.EAST 91 | if (self.NORTH_KEY in self.keys) and Directions.NORTH in legal: 92 | move = Directions.NORTH 93 | if (self.SOUTH_KEY in self.keys) and Directions.SOUTH in legal: 94 | move = Directions.SOUTH 95 | return move 96 | -------------------------------------------------------------------------------- /p3-rl/layout.py: -------------------------------------------------------------------------------- 1 | # layout.py 2 | # --------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from util import manhattanDistance 16 | from game import Grid 17 | import os 18 | import random 19 | from functools import reduce 20 | 21 | VISIBILITY_MATRIX_CACHE = {} 22 | 23 | 24 | class Layout: 25 | """ 26 | A Layout manages the static information about the game board. 27 | """ 28 | 29 | def __init__(self, layoutText): 30 | self.width = len(layoutText[0]) 31 | self.height = len(layoutText) 32 | self.walls = Grid(self.width, self.height, False) 33 | self.food = Grid(self.width, self.height, False) 34 | self.capsules = [] 35 | self.agentPositions = [] 36 | self.numGhosts = 0 37 | self.processLayoutText(layoutText) 38 | self.layoutText = layoutText 39 | self.totalFood = len(self.food.asList()) 40 | # self.initializeVisibilityMatrix() 41 | 42 | def getNumGhosts(self): 43 | return self.numGhosts 44 | 45 | def initializeVisibilityMatrix(self): 46 | global VISIBILITY_MATRIX_CACHE 47 | if reduce(str.__add__, self.layoutText) not in VISIBILITY_MATRIX_CACHE: 48 | from game import Directions 49 | vecs = [(-0.5, 0), (0.5, 0), (0, -0.5), (0, 0.5)] 50 | dirs = [Directions.NORTH, Directions.SOUTH, 51 | Directions.WEST, Directions.EAST] 52 | vis = Grid(self.width, self.height, {Directions.NORTH: set(), Directions.SOUTH: set( 53 | ), Directions.EAST: set(), Directions.WEST: set(), Directions.STOP: set()}) 54 | for x in range(self.width): 55 | for y in range(self.height): 56 | if self.walls[x][y] == False: 57 | for vec, direction in zip(vecs, dirs): 58 | dx, dy = vec 59 | nextx, nexty = x + dx, y + dy 60 | while (nextx + nexty) != int(nextx) + int(nexty) or not self.walls[int(nextx)][int(nexty)]: 61 | vis[x][y][direction].add((nextx, nexty)) 62 | nextx, nexty = x + dx, y + dy 63 | self.visibility = vis 64 | VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)] = vis 65 | else: 66 | self.visibility = VISIBILITY_MATRIX_CACHE[reduce( 67 | str.__add__, self.layoutText)] 68 | 69 | def isWall(self, pos): 70 | x, col = pos 71 | return self.walls[x][col] 72 | 73 | def getRandomLegalPosition(self): 74 | x = random.choice(list(range(self.width))) 75 | y = random.choice(list(range(self.height))) 76 | while self.isWall((x, y)): 77 | x = random.choice(list(range(self.width))) 78 | y = random.choice(list(range(self.height))) 79 | return (x, y) 80 | 81 | def getRandomCorner(self): 82 | poses = [(1, 1), (1, self.height - 2), (self.width - 2, 1), 83 | (self.width - 2, self.height - 2)] 84 | return random.choice(poses) 85 | 86 | def getFurthestCorner(self, pacPos): 87 | poses = [(1, 1), (1, self.height - 2), (self.width - 2, 1), 88 | (self.width - 2, self.height - 2)] 89 | dist, pos = max([(manhattanDistance(p, pacPos), p) for p in poses]) 90 | return pos 91 | 92 | def isVisibleFrom(self, ghostPos, pacPos, pacDirection): 93 | row, col = [int(x) for x in pacPos] 94 | return ghostPos in self.visibility[row][col][pacDirection] 95 | 96 | def __str__(self): 97 | return "\n".join(self.layoutText) 98 | 99 | def deepCopy(self): 100 | return Layout(self.layoutText[:]) 101 | 102 | def processLayoutText(self, layoutText): 103 | """ 104 | Coordinates are flipped from the input format to the (x,y) convention here 105 | 106 | The shape of the maze. Each character 107 | represents a different type of object. 108 | % - Wall 109 | . - Food 110 | o - Capsule 111 | G - Ghost 112 | P - Pacman 113 | Other characters are ignored. 114 | """ 115 | maxY = self.height - 1 116 | for y in range(self.height): 117 | for x in range(self.width): 118 | layoutChar = layoutText[maxY - y][x] 119 | self.processLayoutChar(x, y, layoutChar) 120 | self.agentPositions.sort() 121 | self.agentPositions = [(i == 0, pos) for i, pos in self.agentPositions] 122 | 123 | def processLayoutChar(self, x, y, layoutChar): 124 | if layoutChar == '%': 125 | self.walls[x][y] = True 126 | elif layoutChar == '.': 127 | self.food[x][y] = True 128 | elif layoutChar == 'o': 129 | self.capsules.append((x, y)) 130 | elif layoutChar == 'P': 131 | self.agentPositions.append((0, (x, y))) 132 | elif layoutChar in ['G']: 133 | self.agentPositions.append((1, (x, y))) 134 | self.numGhosts += 1 135 | elif layoutChar in ['1', '2', '3', '4']: 136 | self.agentPositions.append((int(layoutChar), (x, y))) 137 | self.numGhosts += 1 138 | 139 | 140 | def getLayout(name, back=2): 141 | if name.endswith('.lay'): 142 | layout = tryToLoad('layouts/' + name) 143 | if layout == None: 144 | layout = tryToLoad(name) 145 | else: 146 | layout = tryToLoad('layouts/' + name + '.lay') 147 | if layout == None: 148 | layout = tryToLoad(name + '.lay') 149 | if layout == None and back >= 0: 150 | curdir = os.path.abspath('.') 151 | os.chdir('..') 152 | layout = getLayout(name, back - 1) 153 | os.chdir(curdir) 154 | return layout 155 | 156 | 157 | def tryToLoad(fullname): 158 | if(not os.path.exists(fullname)): 159 | return None 160 | f = open(fullname) 161 | try: 162 | return Layout([line.strip() for line in f]) 163 | finally: 164 | f.close() 165 | -------------------------------------------------------------------------------- /p3-rl/mdp.py: -------------------------------------------------------------------------------- 1 | # mdp.py 2 | # ------ 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import random 16 | 17 | class MarkovDecisionProcess: 18 | 19 | def getStates(self): 20 | """ 21 | Return a list of all states in the MDP. 22 | Not generally possible for large MDPs. 23 | """ 24 | abstract 25 | 26 | def getStartState(self): 27 | """ 28 | Return the start state of the MDP. 29 | """ 30 | abstract 31 | 32 | def getPossibleActions(self, state): 33 | """ 34 | Return list of possible actions from 'state'. 35 | """ 36 | abstract 37 | 38 | def getTransitionStatesAndProbs(self, state, action): 39 | """ 40 | Returns list of (nextState, prob) pairs 41 | representing the states reachable 42 | from 'state' by taking 'action' along 43 | with their transition probabilities. 44 | 45 | Note that in Q-Learning and reinforcment 46 | learning in general, we do not know these 47 | probabilities nor do we directly model them. 48 | """ 49 | abstract 50 | 51 | def getReward(self, state, action, nextState): 52 | """ 53 | Get the reward for the state, action, nextState transition. 54 | 55 | Not available in reinforcement learning. 56 | """ 57 | abstract 58 | 59 | def isTerminal(self, state): 60 | """ 61 | Returns true if the current state is a terminal state. By convention, 62 | a terminal state has zero future rewards. Sometimes the terminal state(s) 63 | may have no possible actions. It is also common to think of the terminal 64 | state as having a self-loop action 'pass' with zero reward; the formulations 65 | are equivalent. 66 | """ 67 | abstract 68 | -------------------------------------------------------------------------------- /p3-rl/pacmanAgents.py: -------------------------------------------------------------------------------- 1 | # pacmanAgents.py 2 | # --------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from pacman import Directions 16 | from game import Agent 17 | import random 18 | import game 19 | import util 20 | 21 | 22 | class LeftTurnAgent(game.Agent): 23 | "An agent that turns left at every opportunity" 24 | 25 | def getAction(self, state): 26 | legal = state.getLegalPacmanActions() 27 | current = state.getPacmanState().configuration.direction 28 | if current == Directions.STOP: 29 | current = Directions.NORTH 30 | left = Directions.LEFT[current] 31 | if left in legal: 32 | return left 33 | if current in legal: 34 | return current 35 | if Directions.RIGHT[current] in legal: 36 | return Directions.RIGHT[current] 37 | if Directions.LEFT[left] in legal: 38 | return Directions.LEFT[left] 39 | return Directions.STOP 40 | 41 | 42 | class GreedyAgent(Agent): 43 | def __init__(self, evalFn="scoreEvaluation"): 44 | self.evaluationFunction = util.lookup(evalFn, globals()) 45 | assert self.evaluationFunction != None 46 | 47 | def getAction(self, state): 48 | # Generate candidate actions 49 | legal = state.getLegalPacmanActions() 50 | if Directions.STOP in legal: 51 | legal.remove(Directions.STOP) 52 | 53 | successors = [(state.generateSuccessor(0, action), action) 54 | for action in legal] 55 | scored = [(self.evaluationFunction(state), action) 56 | for state, action in successors] 57 | bestScore = max(scored)[0] 58 | bestActions = [pair[1] for pair in scored if pair[0] == bestScore] 59 | return random.choice(bestActions) 60 | 61 | 62 | def scoreEvaluation(state): 63 | return state.getScore() 64 | -------------------------------------------------------------------------------- /p3-rl/projectParams.py: -------------------------------------------------------------------------------- 1 | # projectParams.py 2 | # ---------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | STUDENT_CODE_DEFAULT = 'analysis.py,qlearningAgents.py,valueIterationAgents.py' 16 | PROJECT_TEST_CLASSES = 'reinforcementTestClasses.py' 17 | PROJECT_NAME = 'Project 3: Reinforcement learning' 18 | BONUS_PIC = False 19 | -------------------------------------------------------------------------------- /p3-rl/testParser.py: -------------------------------------------------------------------------------- 1 | # testParser.py 2 | # ------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import re 16 | import sys 17 | 18 | 19 | class TestParser(object): 20 | 21 | def __init__(self, path): 22 | # save the path to the test file 23 | self.path = path 24 | 25 | def removeComments(self, rawlines): 26 | # remove any portion of a line following a '#' symbol 27 | fixed_lines = [] 28 | for l in rawlines: 29 | idx = l.find('#') 30 | if idx == -1: 31 | fixed_lines.append(l) 32 | else: 33 | fixed_lines.append(l[0:idx]) 34 | return '\n'.join(fixed_lines) 35 | 36 | def parse(self): 37 | # read in the test case and remove comments 38 | test = {} 39 | with open(self.path) as handle: 40 | raw_lines = handle.read().split('\n') 41 | 42 | test_text = self.removeComments(raw_lines) 43 | test['__raw_lines__'] = raw_lines 44 | test['path'] = self.path 45 | test['__emit__'] = [] 46 | lines = test_text.split('\n') 47 | i = 0 48 | # read a property in each loop cycle 49 | while(i < len(lines)): 50 | # skip blank lines 51 | if re.match('\A\s*\Z', lines[i]): 52 | test['__emit__'].append(("raw", raw_lines[i])) 53 | i += 1 54 | continue 55 | m = re.match('\A([^"]*?):\s*"([^"]*)"\s*\Z', lines[i]) 56 | if m: 57 | test[m.group(1)] = m.group(2) 58 | test['__emit__'].append(("oneline", m.group(1))) 59 | i += 1 60 | continue 61 | m = re.match('\A([^"]*?):\s*"""\s*\Z', lines[i]) 62 | if m: 63 | msg = [] 64 | i += 1 65 | while(not re.match('\A\s*"""\s*\Z', lines[i])): 66 | msg.append(raw_lines[i]) 67 | i += 1 68 | test[m.group(1)] = '\n'.join(msg) 69 | test['__emit__'].append(("multiline", m.group(1))) 70 | i += 1 71 | continue 72 | print('error parsing test file: %s' % self.path) 73 | sys.exit(1) 74 | return test 75 | 76 | 77 | def emitTestDict(testDict, handle): 78 | for kind, data in testDict['__emit__']: 79 | if kind == "raw": 80 | handle.write(data + "\n") 81 | elif kind == "oneline": 82 | handle.write('%s: "%s"\n' % (data, testDict[data])) 83 | elif kind == "multiline": 84 | handle.write('%s: """\n%s\n"""\n' % (data, testDict[data])) 85 | else: 86 | raise Exception("Bad __emit__") 87 | -------------------------------------------------------------------------------- /p3-rl/test_cases/CONFIG: -------------------------------------------------------------------------------- 1 | order: "q1 q2 q3 q4 q5 q6 q7 q8 q9 q10" -------------------------------------------------------------------------------- /p3-rl/test_cases/q1/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "4" 2 | class: "PassAllTestsQuestion" -------------------------------------------------------------------------------- /p3-rl/test_cases/q10/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p3-rl/test_cases/q2/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "1" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p3-rl/test_cases/q3/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "5" 2 | class: "NumberPassedQuestion" 3 | -------------------------------------------------------------------------------- /p3-rl/test_cases/q4/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "1" 2 | class: "PassAllTestsQuestion" -------------------------------------------------------------------------------- /p3-rl/test_cases/q5/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" -------------------------------------------------------------------------------- /p3-rl/test_cases/q6/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "4" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p3-rl/test_cases/q7/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "2" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p3-rl/test_cases/q8/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "1" 2 | class: "PassAllTestsQuestion" 3 | -------------------------------------------------------------------------------- /p3-rl/test_cases/q9/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "1" 2 | class: "PartialCreditQuestion" 3 | -------------------------------------------------------------------------------- /p3-rl/textDisplay.py: -------------------------------------------------------------------------------- 1 | # textDisplay.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import time 16 | try: 17 | import pacman 18 | except: 19 | pass 20 | 21 | DRAW_EVERY = 1 22 | SLEEP_TIME = 0 # This can be overwritten by __init__ 23 | DISPLAY_MOVES = False 24 | QUIET = False # Supresses output 25 | 26 | 27 | class NullGraphics: 28 | def initialize(self, state, isBlue=False): 29 | pass 30 | 31 | def update(self, state): 32 | pass 33 | 34 | def checkNullDisplay(self): 35 | return True 36 | 37 | def pause(self): 38 | time.sleep(SLEEP_TIME) 39 | 40 | def draw(self, state): 41 | print(state) 42 | 43 | def updateDistributions(self, dist): 44 | pass 45 | 46 | def finish(self): 47 | pass 48 | 49 | 50 | class PacmanGraphics: 51 | def __init__(self, speed=None): 52 | if speed != None: 53 | global SLEEP_TIME 54 | SLEEP_TIME = speed 55 | 56 | def initialize(self, state, isBlue=False): 57 | self.draw(state) 58 | self.pause() 59 | self.turn = 0 60 | self.agentCounter = 0 61 | 62 | def update(self, state): 63 | numAgents = len(state.agentStates) 64 | self.agentCounter = (self.agentCounter + 1) % numAgents 65 | if self.agentCounter == 0: 66 | self.turn += 1 67 | if DISPLAY_MOVES: 68 | ghosts = [pacman.nearestPoint( 69 | state.getGhostPosition(i)) for i in range(1, numAgents)] 70 | print("%4d) P: %-8s" % (self.turn, str(pacman.nearestPoint(state.getPacmanPosition()))), 71 | '| Score: %-5d' % state.score, '| Ghosts:', ghosts) 72 | if self.turn % DRAW_EVERY == 0: 73 | self.draw(state) 74 | self.pause() 75 | if state._win or state._lose: 76 | self.draw(state) 77 | 78 | def pause(self): 79 | time.sleep(SLEEP_TIME) 80 | 81 | def draw(self, state): 82 | print(state) 83 | 84 | def finish(self): 85 | pass 86 | -------------------------------------------------------------------------------- /p4-tracking/VERSION: -------------------------------------------------------------------------------- 1 | v1.003 2 | -------------------------------------------------------------------------------- /p4-tracking/bustersGhostAgents.py: -------------------------------------------------------------------------------- 1 | # bustersGhostAgents.py 2 | # --------------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import ghostAgents 16 | from game import Directions 17 | from game import Actions 18 | from util import manhattanDistance 19 | import util 20 | 21 | class StationaryGhost( ghostAgents.GhostAgent ): 22 | def getDistribution( self, state ): 23 | dist = util.Counter() 24 | dist[Directions.STOP] = 1.0 25 | return dist 26 | 27 | class DispersingGhost( ghostAgents.GhostAgent ): 28 | "Chooses an action that distances the ghost from the other ghosts with probability spreadProb." 29 | def __init__( self, index, spreadProb=0.5): 30 | self.index = index 31 | self.spreadProb = spreadProb 32 | 33 | def getDistribution( self, state ): 34 | ghostState = state.getGhostState( self.index ) 35 | legalActions = state.getLegalActions( self.index ) 36 | pos = state.getGhostPosition( self.index ) 37 | isScared = ghostState.scaredTimer > 0 38 | 39 | speed = 1 40 | if isScared: speed = 0.5 41 | actionVectors = [Actions.directionToVector( a, speed ) for a in legalActions] 42 | newPositions = [( pos[0]+a[0], pos[1]+a[1] ) for a in actionVectors] 43 | 44 | # get other ghost positions 45 | others = [i for i in range(1,state.getNumAgents()) if i != self.index] 46 | for a in others: assert state.getGhostState(a) != None, "Ghost position unspecified in state!" 47 | otherGhostPositions = [state.getGhostPosition(a) for a in others if state.getGhostPosition(a)[1] > 1] 48 | 49 | # for each action, get the sum of inverse squared distances to the other ghosts 50 | sumOfDistances = [] 51 | for pos in newPositions: 52 | sumOfDistances.append( sum([(1+manhattanDistance(pos, g))**(-2) for g in otherGhostPositions]) ) 53 | 54 | bestDistance = min(sumOfDistances) 55 | numBest = [bestDistance == dist for dist in sumOfDistances].count(True) 56 | distribution = util.Counter() 57 | for action, distance in zip(legalActions, sumOfDistances): 58 | if distance == bestDistance: distribution[action] += self.spreadProb / numBest 59 | distribution[action] += (1 - self.spreadProb) / len(legalActions) 60 | return distribution 61 | -------------------------------------------------------------------------------- /p4-tracking/distanceCalculator.py: -------------------------------------------------------------------------------- 1 | # distanceCalculator.py 2 | # --------------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | """ 16 | This file contains a Distancer object which computes and 17 | caches the shortest path between any two points in the maze. It 18 | returns a Manhattan distance between two points if the maze distance 19 | has not yet been calculated. 20 | 21 | Example: 22 | distancer = Distancer(gameState.data.layout) 23 | distancer.getDistance( (1,1), (10,10) ) 24 | 25 | The Distancer object also serves as an example of sharing data 26 | safely among agents via a global dictionary (distanceMap), 27 | and performing asynchronous computation via threads. These 28 | examples may help you in designing your own objects, but you 29 | shouldn't need to modify the Distancer code in order to use its 30 | distances. 31 | """ 32 | 33 | import threading, sys, time, random 34 | 35 | class Distancer: 36 | def __init__(self, layout, background=True, default=10000): 37 | """ 38 | Initialize with Distancer(layout). Changing default is unnecessary. 39 | 40 | This will start computing maze distances in the background and use them 41 | as soon as they are ready. In the meantime, it returns manhattan distance. 42 | 43 | To compute all maze distances on initialization, set background=False 44 | """ 45 | self._distances = None 46 | self.default = default 47 | 48 | # Start computing distances in the background; when the dc finishes, 49 | # it will fill in self._distances for us. 50 | dc = DistanceCalculator() 51 | dc.setAttr(layout, self) 52 | dc.setDaemon(True) 53 | if background: 54 | dc.start() 55 | else: 56 | dc.run() 57 | 58 | def getDistance(self, pos1, pos2): 59 | """ 60 | The getDistance function is the only one you'll need after you create the object. 61 | """ 62 | if self._distances == None: 63 | return manhattanDistance(pos1, pos2) 64 | if isInt(pos1) and isInt(pos2): 65 | return self.getDistanceOnGrid(pos1, pos2) 66 | pos1Grids = getGrids2D(pos1) 67 | pos2Grids = getGrids2D(pos2) 68 | bestDistance = self.default 69 | for pos1Snap, snap1Distance in pos1Grids: 70 | for pos2Snap, snap2Distance in pos2Grids: 71 | gridDistance = self.getDistanceOnGrid(pos1Snap, pos2Snap) 72 | distance = gridDistance + snap1Distance + snap2Distance 73 | if bestDistance > distance: 74 | bestDistance = distance 75 | return bestDistance 76 | 77 | def getDistanceOnGrid(self, pos1, pos2): 78 | key = (pos1, pos2) 79 | if key in self._distances: 80 | return self._distances[key] 81 | else: 82 | raise Exception("Positions not in grid: " + str(key)) 83 | 84 | def isReadyForMazeDistance(self): 85 | return self._distances != None 86 | 87 | def manhattanDistance(x, y ): 88 | return abs( x[0] - y[0] ) + abs( x[1] - y[1] ) 89 | 90 | def isInt(pos): 91 | x, y = pos 92 | return x == int(x) and y == int(y) 93 | 94 | def getGrids2D(pos): 95 | grids = [] 96 | for x, xDistance in getGrids1D(pos[0]): 97 | for y, yDistance in getGrids1D(pos[1]): 98 | grids.append(((x, y), xDistance + yDistance)) 99 | return grids 100 | 101 | def getGrids1D(x): 102 | intX = int(x) 103 | if x == int(x): 104 | return [(x, 0)] 105 | return [(intX, x-intX), (intX+1, intX+1-x)] 106 | 107 | ########################################## 108 | # MACHINERY FOR COMPUTING MAZE DISTANCES # 109 | ########################################## 110 | 111 | distanceMap = {} 112 | distanceMapSemaphore = threading.Semaphore(1) 113 | distanceThread = None 114 | 115 | def waitOnDistanceCalculator(t): 116 | global distanceThread 117 | if distanceThread != None: 118 | time.sleep(t) 119 | 120 | class DistanceCalculator(threading.Thread): 121 | def setAttr(self, layout, distancer, default = 10000): 122 | self.layout = layout 123 | self.distancer = distancer 124 | self.default = default 125 | 126 | def run(self): 127 | global distanceMap, distanceThread 128 | distanceMapSemaphore.acquire() 129 | 130 | if self.layout.walls not in distanceMap: 131 | if distanceThread != None: raise Exception('Multiple distance threads') 132 | distanceThread = self 133 | 134 | distances = computeDistances(self.layout) 135 | print('[Distancer]: Switching to maze distances',file=sys.stdout) 136 | 137 | distanceMap[self.layout.walls] = distances 138 | distanceThread = None 139 | else: 140 | distances = distanceMap[self.layout.walls] 141 | 142 | distanceMapSemaphore.release() 143 | self.distancer._distances = distances 144 | 145 | def computeDistances(layout): 146 | distances = {} 147 | allNodes = layout.walls.asList(False) 148 | for source in allNodes: 149 | dist = {} 150 | closed = {} 151 | for node in allNodes: 152 | dist[node] = 1000000000 153 | import util 154 | queue = util.PriorityQueue() 155 | queue.push(source, 0) 156 | dist[source] = 0 157 | while not queue.isEmpty(): 158 | node = queue.pop() 159 | if node in closed: 160 | continue 161 | closed[node] = True 162 | nodeDist = dist[node] 163 | adjacent = [] 164 | x, y = node 165 | if not layout.isWall((x,y+1)): 166 | adjacent.append((x,y+1)) 167 | if not layout.isWall((x,y-1)): 168 | adjacent.append((x,y-1) ) 169 | if not layout.isWall((x+1,y)): 170 | adjacent.append((x+1,y) ) 171 | if not layout.isWall((x-1,y)): 172 | adjacent.append((x-1,y)) 173 | for other in adjacent: 174 | if not other in dist: 175 | continue 176 | oldDist = dist[other] 177 | newDist = nodeDist+1 178 | if newDist < oldDist: 179 | dist[other] = newDist 180 | queue.push(other, newDist) 181 | for target in allNodes: 182 | distances[(target, source)] = dist[target] 183 | return distances 184 | 185 | 186 | def getDistanceOnGrid(distances, pos1, pos2): 187 | key = (pos1, pos2) 188 | if key in distances: 189 | return distances[key] 190 | return 100000 191 | 192 | -------------------------------------------------------------------------------- /p4-tracking/ghostAgents.py: -------------------------------------------------------------------------------- 1 | # ghostAgents.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from game import Agent 16 | from game import Actions 17 | from game import Directions 18 | import random 19 | from util import manhattanDistance 20 | import util 21 | 22 | class GhostAgent( Agent ): 23 | def __init__( self, index ): 24 | self.index = index 25 | 26 | def getAction( self, state ): 27 | dist = self.getDistribution(state) 28 | if len(dist) == 0: 29 | return Directions.STOP 30 | else: 31 | return util.chooseFromDistribution( dist ) 32 | 33 | def getDistribution(self, state): 34 | "Returns a Counter encoding a distribution over actions from the provided state." 35 | util.raiseNotDefined() 36 | 37 | class RandomGhost( GhostAgent ): 38 | "A ghost that chooses a legal action uniformly at random." 39 | def getDistribution( self, state ): 40 | dist = util.Counter() 41 | for a in state.getLegalActions( self.index ): dist[a] = 1.0 42 | dist.normalize() 43 | return dist 44 | 45 | class DirectionalGhost( GhostAgent ): 46 | "A ghost that prefers to rush Pacman, or flee when scared." 47 | def __init__( self, index, prob_attack=0.8, prob_scaredFlee=0.8 ): 48 | self.index = index 49 | self.prob_attack = prob_attack 50 | self.prob_scaredFlee = prob_scaredFlee 51 | 52 | def getDistribution( self, state ): 53 | # Read variables from state 54 | ghostState = state.getGhostState( self.index ) 55 | legalActions = state.getLegalActions( self.index ) 56 | pos = state.getGhostPosition( self.index ) 57 | isScared = ghostState.scaredTimer > 0 58 | 59 | speed = 1 60 | if isScared: speed = 0.5 61 | 62 | actionVectors = [Actions.directionToVector( a, speed ) for a in legalActions] 63 | newPositions = [( pos[0]+a[0], pos[1]+a[1] ) for a in actionVectors] 64 | pacmanPosition = state.getPacmanPosition() 65 | 66 | # Select best actions given the state 67 | distancesToPacman = [manhattanDistance( pos, pacmanPosition ) for pos in newPositions] 68 | if isScared: 69 | bestScore = max( distancesToPacman ) 70 | bestProb = self.prob_scaredFlee 71 | else: 72 | bestScore = min( distancesToPacman ) 73 | bestProb = self.prob_attack 74 | bestActions = [action for action, distance in zip( legalActions, distancesToPacman ) if distance == bestScore] 75 | 76 | # Construct distribution 77 | dist = util.Counter() 78 | for a in bestActions: dist[a] = bestProb / len(bestActions) 79 | for a in legalActions: dist[a] += ( 1-bestProb ) / len(legalActions) 80 | dist.normalize() 81 | return dist 82 | -------------------------------------------------------------------------------- /p4-tracking/keyboardAgents.py: -------------------------------------------------------------------------------- 1 | # keyboardAgents.py 2 | # ----------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from game import Agent 16 | from game import Directions 17 | import random 18 | 19 | class KeyboardAgent(Agent): 20 | """ 21 | An agent controlled by the keyboard. 22 | """ 23 | # NOTE: Arrow keys also work. 24 | WEST_KEY = 'a' 25 | EAST_KEY = 'd' 26 | NORTH_KEY = 'w' 27 | SOUTH_KEY = 's' 28 | STOP_KEY = 'q' 29 | 30 | def __init__( self, index = 0 ): 31 | 32 | self.lastMove = Directions.STOP 33 | self.index = index 34 | self.keys = [] 35 | 36 | def getAction( self, state): 37 | from graphicsUtils import keys_waiting 38 | from graphicsUtils import keys_pressed 39 | keys = list(keys_waiting()) + list(keys_pressed()) 40 | if keys != []: 41 | self.keys = keys 42 | 43 | legal = state.getLegalActions(self.index) 44 | move = self.getMove(legal) 45 | 46 | if move == Directions.STOP: 47 | # Try to move in the same direction as before 48 | if self.lastMove in legal: 49 | move = self.lastMove 50 | 51 | if (self.STOP_KEY in self.keys) and Directions.STOP in legal: move = Directions.STOP 52 | 53 | if move not in legal: 54 | move = random.choice(legal) 55 | 56 | self.lastMove = move 57 | return move 58 | 59 | def getMove(self, legal): 60 | move = Directions.STOP 61 | if (self.WEST_KEY in self.keys or 'Left' in self.keys) and Directions.WEST in legal: move = Directions.WEST 62 | if (self.EAST_KEY in self.keys or 'Right' in self.keys) and Directions.EAST in legal: move = Directions.EAST 63 | if (self.NORTH_KEY in self.keys or 'Up' in self.keys) and Directions.NORTH in legal: move = Directions.NORTH 64 | if (self.SOUTH_KEY in self.keys or 'Down' in self.keys) and Directions.SOUTH in legal: move = Directions.SOUTH 65 | return move 66 | 67 | class KeyboardAgent2(KeyboardAgent): 68 | """ 69 | A second agent controlled by the keyboard. 70 | """ 71 | # NOTE: Arrow keys also work. 72 | WEST_KEY = 'j' 73 | EAST_KEY = "l" 74 | NORTH_KEY = 'i' 75 | SOUTH_KEY = 'k' 76 | STOP_KEY = 'u' 77 | 78 | def getMove(self, legal): 79 | move = Directions.STOP 80 | if (self.WEST_KEY in self.keys) and Directions.WEST in legal: move = Directions.WEST 81 | if (self.EAST_KEY in self.keys) and Directions.EAST in legal: move = Directions.EAST 82 | if (self.NORTH_KEY in self.keys) and Directions.NORTH in legal: move = Directions.NORTH 83 | if (self.SOUTH_KEY in self.keys) and Directions.SOUTH in legal: move = Directions.SOUTH 84 | return move 85 | -------------------------------------------------------------------------------- /p4-tracking/layout.py: -------------------------------------------------------------------------------- 1 | # layout.py 2 | # --------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | from util import manhattanDistance 16 | from game import Grid 17 | import os 18 | import random 19 | from functools import reduce 20 | 21 | VISIBILITY_MATRIX_CACHE = {} 22 | 23 | class Layout: 24 | """ 25 | A Layout manages the static information about the game board. 26 | """ 27 | 28 | def __init__(self, layoutText): 29 | self.width = len(layoutText[0]) 30 | self.height= len(layoutText) 31 | self.walls = Grid(self.width, self.height, False) 32 | self.food = Grid(self.width, self.height, False) 33 | self.capsules = [] 34 | self.agentPositions = [] 35 | self.numGhosts = 0 36 | self.processLayoutText(layoutText) 37 | self.layoutText = layoutText 38 | self.totalFood = len(self.food.asList()) 39 | # self.initializeVisibilityMatrix() 40 | 41 | def getNumGhosts(self): 42 | return self.numGhosts 43 | 44 | def initializeVisibilityMatrix(self): 45 | global VISIBILITY_MATRIX_CACHE 46 | if reduce(str.__add__, self.layoutText) not in VISIBILITY_MATRIX_CACHE: 47 | from game import Directions 48 | vecs = [(-0.5,0), (0.5,0),(0,-0.5),(0,0.5)] 49 | dirs = [Directions.NORTH, Directions.SOUTH, Directions.WEST, Directions.EAST] 50 | vis = Grid(self.width, self.height, {Directions.NORTH:set(), Directions.SOUTH:set(), Directions.EAST:set(), Directions.WEST:set(), Directions.STOP:set()}) 51 | for x in range(self.width): 52 | for y in range(self.height): 53 | if self.walls[x][y] == False: 54 | for vec, direction in zip(vecs, dirs): 55 | dx, dy = vec 56 | nextx, nexty = x + dx, y + dy 57 | while (nextx + nexty) != int(nextx) + int(nexty) or not self.walls[int(nextx)][int(nexty)] : 58 | vis[x][y][direction].add((nextx, nexty)) 59 | nextx, nexty = x + dx, y + dy 60 | self.visibility = vis 61 | VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)] = vis 62 | else: 63 | self.visibility = VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)] 64 | 65 | def isWall(self, pos): 66 | x, col = pos 67 | return self.walls[x][col] 68 | 69 | def getRandomLegalPosition(self): 70 | x = random.choice(range(self.width)) 71 | y = random.choice(range(self.height)) 72 | while self.isWall( (x, y) ): 73 | x = random.choice(range(self.width)) 74 | y = random.choice(range(self.height)) 75 | return (x,y) 76 | 77 | def getRandomCorner(self): 78 | poses = [(1,1), (1, self.height - 2), (self.width - 2, 1), (self.width - 2, self.height - 2)] 79 | return random.choice(poses) 80 | 81 | def getFurthestCorner(self, pacPos): 82 | poses = [(1,1), (1, self.height - 2), (self.width - 2, 1), (self.width - 2, self.height - 2)] 83 | dist, pos = max([(manhattanDistance(p, pacPos), p) for p in poses]) 84 | return pos 85 | 86 | def isVisibleFrom(self, ghostPos, pacPos, pacDirection): 87 | row, col = [int(x) for x in pacPos] 88 | return ghostPos in self.visibility[row][col][pacDirection] 89 | 90 | def __str__(self): 91 | return "\n".join(self.layoutText) 92 | 93 | def deepCopy(self): 94 | return Layout(self.layoutText[:]) 95 | 96 | def processLayoutText(self, layoutText): 97 | """ 98 | Coordinates are flipped from the input format to the (x,y) convention here 99 | 100 | The shape of the maze. Each character 101 | represents a different type of object. 102 | % - Wall 103 | . - Food 104 | o - Capsule 105 | G - Ghost 106 | P - Pacman 107 | Other characters are ignored. 108 | """ 109 | maxY = self.height - 1 110 | for y in range(self.height): 111 | for x in range(self.width): 112 | layoutChar = layoutText[maxY - y][x] 113 | self.processLayoutChar(x, y, layoutChar) 114 | self.agentPositions.sort() 115 | self.agentPositions = [ ( i == 0, pos) for i, pos in self.agentPositions] 116 | 117 | def processLayoutChar(self, x, y, layoutChar): 118 | if layoutChar == '%': 119 | self.walls[x][y] = True 120 | elif layoutChar == '.': 121 | self.food[x][y] = True 122 | elif layoutChar == 'o': 123 | self.capsules.append((x, y)) 124 | elif layoutChar == 'P': 125 | self.agentPositions.append( (0, (x, y) ) ) 126 | elif layoutChar in ['G']: 127 | self.agentPositions.append( (1, (x, y) ) ) 128 | self.numGhosts += 1 129 | elif layoutChar in ['1', '2', '3', '4']: 130 | self.agentPositions.append( (int(layoutChar), (x,y))) 131 | self.numGhosts += 1 132 | def getLayout(name, back = 2): 133 | if name.endswith('.lay'): 134 | layout = tryToLoad('layouts/' + name) 135 | if layout == None: layout = tryToLoad(name) 136 | else: 137 | layout = tryToLoad('layouts/' + name + '.lay') 138 | if layout == None: layout = tryToLoad(name + '.lay') 139 | if layout == None and back >= 0: 140 | curdir = os.path.abspath('.') 141 | os.chdir('..') 142 | layout = getLayout(name, back -1) 143 | os.chdir(curdir) 144 | return layout 145 | 146 | def tryToLoad(fullname): 147 | if(not os.path.exists(fullname)): return None 148 | f = open(fullname) 149 | try: return Layout([line.strip() for line in f]) 150 | finally: f.close() 151 | -------------------------------------------------------------------------------- /p4-tracking/projectParams.py: -------------------------------------------------------------------------------- 1 | # projectParams.py 2 | # ---------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | STUDENT_CODE_DEFAULT = 'inference.py' 16 | PROJECT_TEST_CLASSES = 'tracking_fa18TestClasses.py' 17 | PROJECT_NAME = 'Project 4: Ghostbusters' 18 | BONUS_PIC = True 19 | -------------------------------------------------------------------------------- /p4-tracking/testParser.py: -------------------------------------------------------------------------------- 1 | # testParser.py 2 | # ------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import re 16 | import sys 17 | 18 | class TestParser(object): 19 | 20 | def __init__(self, path): 21 | # save the path to the test file 22 | self.path = path 23 | 24 | def removeComments(self, rawlines): 25 | # remove any portion of a line following a '#' symbol 26 | fixed_lines = [] 27 | for l in rawlines: 28 | idx = l.find('#') 29 | if idx == -1: 30 | fixed_lines.append(l) 31 | else: 32 | fixed_lines.append(l[0:idx]) 33 | return '\n'.join(fixed_lines) 34 | 35 | def parse(self): 36 | # read in the test case and remove comments 37 | test = {} 38 | with open(self.path) as handle: 39 | raw_lines = handle.read().split('\n') 40 | 41 | test_text = self.removeComments(raw_lines) 42 | test['__raw_lines__'] = raw_lines 43 | test['path'] = self.path 44 | test['__emit__'] = [] 45 | lines = test_text.split('\n') 46 | i = 0 47 | # read a property in each loop cycle 48 | while(i < len(lines)): 49 | # skip blank lines 50 | if re.match('\A\s*\Z', lines[i]): 51 | test['__emit__'].append(("raw", raw_lines[i])) 52 | i += 1 53 | continue 54 | m = re.match('\A([^"]*?):\s*"([^"]*)"\s*\Z', lines[i]) 55 | if m: 56 | test[m.group(1)] = m.group(2) 57 | test['__emit__'].append(("oneline", m.group(1))) 58 | i += 1 59 | continue 60 | m = re.match('\A([^"]*?):\s*"""\s*\Z', lines[i]) 61 | if m: 62 | msg = [] 63 | i += 1 64 | while(not re.match('\A\s*"""\s*\Z', lines[i])): 65 | msg.append(raw_lines[i]) 66 | i += 1 67 | test[m.group(1)] = '\n'.join(msg) 68 | test['__emit__'].append(("multiline", m.group(1))) 69 | i += 1 70 | continue 71 | print('error parsing test file: %s' % self.path) 72 | sys.exit(1) 73 | return test 74 | 75 | 76 | def emitTestDict(testDict, handle): 77 | for kind, data in testDict['__emit__']: 78 | if kind == "raw": 79 | handle.write(data + "\n") 80 | elif kind == "oneline": 81 | handle.write('%s: "%s"\n' % (data, testDict[data])) 82 | elif kind == "multiline": 83 | handle.write('%s: """\n%s\n"""\n' % (data, testDict[data])) 84 | else: 85 | raise Exception("Bad __emit__") 86 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/CONFIG: -------------------------------------------------------------------------------- 1 | order: "q1 q2 q3 q4 q5 q6 q7 q8 q9 q10" 2 | 3 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q1/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "2" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q10/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q2/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q3/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q4/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "2" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q5/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "2" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q6/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q7/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q8/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "1" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/test_cases/q9/CONFIG: -------------------------------------------------------------------------------- 1 | max_points: "3" 2 | class: "PassAllTestsQuestion" 3 | 4 | -------------------------------------------------------------------------------- /p4-tracking/textDisplay.py: -------------------------------------------------------------------------------- 1 | # textDisplay.py 2 | # -------------- 3 | # Licensing Information: You are free to use or extend these projects for 4 | # educational purposes provided that (1) you do not distribute or publish 5 | # solutions, (2) you retain this notice, and (3) you provide clear 6 | # attribution to UC Berkeley, including a link to http://ai.berkeley.edu. 7 | # 8 | # Attribution Information: The Pacman AI projects were developed at UC Berkeley. 9 | # The core projects and autograders were primarily created by John DeNero 10 | # (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu). 11 | # Student side autograding was added by Brad Miller, Nick Hay, and 12 | # Pieter Abbeel (pabbeel@cs.berkeley.edu). 13 | 14 | 15 | import time 16 | try: 17 | import pacman 18 | except: 19 | pass 20 | 21 | DRAW_EVERY = 1 22 | SLEEP_TIME = 0 # This can be overwritten by __init__ 23 | DISPLAY_MOVES = False 24 | QUIET = False # Supresses output 25 | 26 | class NullGraphics: 27 | def initialize(self, state, isBlue = False): 28 | pass 29 | 30 | def update(self, state): 31 | pass 32 | 33 | def checkNullDisplay(self): 34 | return True 35 | 36 | def pause(self): 37 | time.sleep(SLEEP_TIME) 38 | 39 | def draw(self, state): 40 | print(state) 41 | 42 | def updateDistributions(self, dist): 43 | pass 44 | 45 | def finish(self): 46 | pass 47 | 48 | class PacmanGraphics: 49 | def __init__(self, speed=None): 50 | if speed != None: 51 | global SLEEP_TIME 52 | SLEEP_TIME = speed 53 | 54 | def initialize(self, state, isBlue = False): 55 | self.draw(state) 56 | self.pause() 57 | self.turn = 0 58 | self.agentCounter = 0 59 | 60 | def update(self, state): 61 | numAgents = len(state.agentStates) 62 | self.agentCounter = (self.agentCounter + 1) % numAgents 63 | if self.agentCounter == 0: 64 | self.turn += 1 65 | if DISPLAY_MOVES: 66 | ghosts = [pacman.nearestPoint(state.getGhostPosition(i)) for i in range(1, numAgents)] 67 | print("%4d) P: %-8s" % (self.turn, str(pacman.nearestPoint(state.getPacmanPosition()))),'| Score: %-5d' % state.score,'| Ghosts:', ghosts) 68 | if self.turn % DRAW_EVERY == 0: 69 | self.draw(state) 70 | self.pause() 71 | if state._win or state._lose: 72 | self.draw(state) 73 | 74 | def pause(self): 75 | time.sleep(SLEEP_TIME) 76 | 77 | def draw(self, state): 78 | print(state) 79 | 80 | def finish(self): 81 | pass 82 | --------------------------------------------------------------------------------