HW 6: Problems 2 & 3 Simulating Connect 4
HW 6: Overview Connect 4: Variation of Tic-Tac-Toe Board: Vertical 7x6 Two players take alternating move Move = Placing checkers on the board Winning = 4 checkers in a row (vert., horz., diag.) Move constraints: On top of each other, or Start a new column Problems: Board class (p2), Player class (p3)
Problem 2: Connect 4 Board Variables Board Representation: Two-dimensional List Width & height vary (i.e. not just 7x6) Board Class variables Variable data storing the 2D list Variable height storing the number of rows Variable width storing the number of columns
Problem 2: Connect 4 Board Method: Constructor The Constructor __init__: Return nothing Take in the board dimension Set board height, width, & initialize data elements def __init__( self, width, height ): self.width = width self.height = height self.data = [] for row in range( self.height ): boardRow = [] for col in range( self.width ): boardRow += [' '] self.data += [boardRow]
Problem 2: Connect 4 Board Method: Representation Method __repr__: Print out the board | | | | | | | | --------------- 0 1 2 3 4 5 6 def __repr__(self): s = '' for row in range(self.height): s += '|' for col in range(self.width): s += self.data[row][col]+'|' s += '\n' #print out separator ... (your code here) #print out column numbers return s
Problem 2: Connect 4 Board Method: addMove Method addMove: take in column & symbol >>> b = Board(7,5) >>> b.addMove(0, 'X') >>> b.addMove(1, 'O') >>> b.addMove(1, 'X') >>> b.addMove(3, 'O') | | | | | | | | | |X| | | | | | |X|O| |O| | | | --------------- 0 1 2 3 4 5 6 def addMove(self, col, ox ): if allowMove(col): # find the first row in # col without a checker ... (your code here) # put ox in this position
Problem 2: Connect 4 Board Methods: clear, delMove, allowMove, isFull Method clear(self): Clear all data to ' ' Method delMove(self, col): Opposite of addMove Delete the top checker of column col Do nothing if column is empty Method allowMove(self, col): False if col is an invalid column number, or full True otherwise Method isFull(self) checks if the board is full
Problem 2: Connect 4 Board Method: setBoard Method setBoard: take in the string of moves >>> b = Board(7,5) >>> b.setBoard('02353') | | | | | | | | | | | |O| | | | |O| |X|O| |X| | --------------- 0 1 2 3 4 5 6 def setBoard(self,moveStr): ch = 'O' for colStr in moveStr: col = int(colStr) if 0<=col<=self.width: self.addMove(col,ch) if ch == 'X': else: ch = 'X'
Problem 2: Connect 4 Board Methods: winFor Method winFor(self, ox): Check if there are 4 ox ’s in a run Horizontal, vertical, and diagonal Possible direction: Anchor checkers = checks that may start run Check each of these anchor checkers in 8 directions
Problem 2: Connect 4 Board Methods: hostGame Method hostGame(self): Runs until the game ends: A player wins The board is full (draw) Alternatively ask player 'O' and 'X' to move Print out the board before asking to move Invalid move = ask the same player to move again Valid move = place checker & check for win At game end report the winner (or tie)
EC Problem 3: Connect 4 Player Overview Goal: Creating an automated player Player class: Examine the board Find appropriate move May look for several moves ahead The variables: At least the following Character ox Tie breaking type tbt (either 'LEFT', 'RIGHT' or 'RANDOM', more detail later) Number of moves ahead ply
EC Problem 3: Connect 4 Player The Essential Methods Construction __init__(self,ox,tbt,ply) Representation __repr__(self) def __init__( self, ox, tbt, ply ): self.ox = ox self.tbt = tbt self.ply = ply def __repr__( self ): s = 'Player for ' + self.ox + '\n' s += 'with tiebreak type: ' + self.tbt + '\n' s += 'and ply == ' + str(self.ply) + '\n\n' return s
EC Problem 3: Connect 4 Player The Required Methods Opposite character oppCh(self): Returns 'X' if own character is 'O', vice versa Evaluating Board scoreBoard(self, b): Given a board b, return 100.0, 50.0 and 0.0 respectively for win, tie, and lose situation Tie-breaking: tiebreakMove(self, scores): Score = list of floating point Returns the column with the highest score Multiple highest score: select one based on tbt Example: tiebreakMove([0,50,0,50]) returns 1 if self.tbt == ‘LEFT’
EC Problem 3: Connect 4 Player The Brain: scoreFor Returns a list of scores: The cth score = goodness after a move to column c Goodness = what happens after self.ply moves Using recursion: Base case 1: A full column = score of -1.0 Base case 2: 0-ply = state of the game right now (hence, all non-full columns have the same score) Base case 3: Game-over = state of the game right now Recursive case: Make a move into a corresponding column, change the (local) board, evaluate recursively
EC Problem 3: Connect 4 Player ‘X’ ‘O’ col 0 col 1 col 2 col 3 col 4 col 5 col 6 0-ply scores for O: -1 50 50 50 50 50 50 col 0 col 1 col 2 col 3 col 4 col 5 col 6 1-ply scores for O: -1 50 50 100 50 50 50 col 0 col 1 col 2 col 3 col 4 col 5 col 6 2-ply scores for O: -1 100 50 col 0 col 1 col 2 col 3 col 4 col 5 col 6 3-ply scores for O: -1 100 100
EC Problem 3: Connect 4 Player Put them all together Choose the next move: nextMove(self,b): Return the best column to move to Wrapper method (heavy lifting is already done) Play the game playGame(self,px,po): Modify hostGame from the Board class Instead of getting user input, it use moves getting from px and po alternatively Additional twist: if one of px and po is a string human, then get the input from the user instead