=========================================================================== CS2710 ISSP 2610 Foundations of Artificial Intelligence Fall 2015 Assignment 2: Checkers! **THIS MUST be your own individual work.** The purpose of this assignment is to give you experience with minimax search with alpha beta pruning, and with developing heuristics. Your task is to figure out or automatically create heuristic functions, implement them, and then perform experiments exploring their performance. The TA will run a tournament. If your program runs too long, it will forfeit. Your assignment will be graded on: Correctness (35%) Interestingness of the heuristics (and cutoff test, if you experiment with that) (40%) Quality of experiments and report (25%) The winner will be announced, and will have the opportunity to present their heuristics to the class. ------------------------------------------------------------------- *** Please submit your solution to the incoming folder in AFS: /afs/cs.pitt.edu/public/incoming/CS2710/ Please submit one thing (tarball, zipfile) containing: your report and your code. If you wish to submit a correction, please append a version number to the new archive to indicate this version should be graded instead. For example, if the original file was "luginiluca.zip" then please submit "luginiluca_v2.zip" as the updated version. Please submit by 11:59pm on the due date to avoid a late penalty. *** -------------------------------------------------------------------- Two python codes are provided: Checkers.py and driver.py. You should implement heuristic functions in Checkers.py. The driver.py is used to play two versions of Checkers against each other. 1) The format for a state is as follows: It is a list of lists. Each inner list represents a row of the checkers board. Individual elements on the checker board are denoted by characters: "." (no piece), "b" (a black checker), "r" (a red checker), "B" (a kinged black piece) and "R" (a kinged red piece). Here is the initial configuration of the board: 7 : . r . r . r . r 6 : r . r . r . r . 5 : . r . r . r . r 4 : . . . . . . . . 3 : . . . . . . . . 2 : b . b . b . b . 1 : . b . b . b . b 0 : b . b . b . b . 0 1 2 3 4 5 6 7 Here is its representation in Python: [ ['b','.','b','.','b','.','b','.'],\ ['.','b','.','b','.','b','.','b'],\ ['b','.','b','.','b','.','b','.'],\ ['.','.','.','.','.','.','.','.'],\ ['.','.','.','.','.','.','.','.'],\ ['.','r','.','r','.','r','.','r'],\ ['r','.','r','.','r','.','r','.'],\ ['.','r','.','r','.','r','.','r'] ] 2) The format for a move is as follows: It is a list of tuples, where each tuple represents a position (x,y) counting from 0,0 in the lower left corner. The first tuple in the list represents the initial position of the checker; the ith tuple represents the ith move in the hop; and the last tuple represents the final position of the checker. For example, if a move involves two hops, the path might look like this: [(1,1), (3,3), (5,5)] 3) The heuristic and cutoff function A very simple (and bad) heuristic function is already implemented in Checker.py. You should create multiple new heuristic functions (you'll submit your best one for the class tournament). Definition: def evalFun(node,space,player): node: node.state.board: contains the current checker board -- refer to 1) above node.parent: contains the parent state -- node.parent.state.board contains the previous checker board node.gval: path cost from the initial state to itself (note that all edgecost = 1) node.hval: (heuristic val) for your bookkeeping; not used in the base code. space: used only for output player: 'r', or 'b' Return value: a number. In the code, the cutoff function simply encodes a fixed cutoff depth of 5. You can change the cutoff strategy and/or specific depth, but please be careful that your search time does not become too great. If your program takes more than one minute for one move, we'll need to make the judgment that your program is lost. 4) Note: In Checkers.py, you should only change the heuristic function (evalFun) and the cutoff function. 5) Create multiple heuristics. There are several avenues to pursue to make this interesting, including automatic methods for developing heuristics. Use driver.py program to play one heuristic against another. Be sure to test them in the two cases where they start from the initial board but taking turns going first. But two games won't give us much information. So, to explore the quality of the heuristics, you should do the following. Pretend that games are already in progress, and your heuristic players need to step in and finish the games. Do this repeatedly, and you will get an idea how well each heuristic performs in different board configurations. Practically, this means you should modify driver.py so that (1) it plays many games, and (2) the line "state = Initial_Board" is replaced by a function call which returns a random (but legal) initial configuration. Also, record relevant information, that will enable you to report statistics about how often and under what circumstances each heuristic wins. 6) What should you submit? (1) A report: a) describe your heuristic functions and cutoff tests. For heuristics you thought of yourself, explain why you thought it would be good (i.e., your motivations for trying them). For heuristics you automatically developed, explain the process. b) describe the results of your experiments, and what they tell us about the performance of your heuristics. (2) Your code for Checkers with your best heuristic included (you don't need to hand in code for the other heuristics or your modified driver.py). Please name your file Checkers.py. For example, my program would be named LucaLuginiCheckers.py Please place your entire program in a single file. 7) To play two checkers programs "checkers1.py" and "checkers2.py" against each other, change the last line of driver.py from play("Checkers","Checkers") to play("checkers1","checkers2") 8) If you find any bug in the original code, Please contact the TA.