HW 6: Problems 2&3 - Northwestern Networks Group

advertisement
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
... (your code here)
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
... (your code here)
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)
def setBoard(self,moveStr):
>>> b.setBoard('02353')
ch = 'O'
| | | | | | | |
for colStr in moveStr:
| | | | | | | |
col = int(colStr)
| | | | | | | |
if 0<=col<=self.width:
| | | |O| | | |
self.addMove(col,ch)
|O| |X|O| |X| |
if ch == 'X':
--------------ch = 'O'
0 1 2 3 4 5 6
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
b
EC Problem
3: Connect 4
Player
0-ply scores for O:
1-ply scores for O:
2-ply scores for O:
3-ply scores for O:
‘X’
‘O’
col 0
col 1
col 2
col 3
col 4
col 5
col 6
-1
50
50
50
50
50
50
col 0
col 1
col 2
col 3
col 4
col 5
col 6
-1
50
50
100
50
50
50
col 0
col 1
col 2
col 3
col 4
col 5
col 6
-1
0
0
100
0
0
50
col 0
col 1
col 2
col 3
col 4
col 5
col 6
-1
0
0
100
0
0
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
Download