tictactoe (reprise)

Sean McIlroy sean_mcilroy at yahoo.com
Sat Jun 28 16:22:21 EDT 2008


"""
AUTHOR: Sean McIlroy
LANGUAGE: Python 2.5
OVERVIEW: instances of "tictactoeplayer" play optimal tictactoe
SPECIALIZED TYPES: player={ex,oh}; empty={blank}; cell=player+empty;
board=[cell]
TYPE RELATIONS: bool(c)==True for any c in cell
"""

ex, oh, blank = 'X', '0', ' '
linear = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],
[2,4,6]]
lines = lambda board: [[board[i] for i in x] for x in linear]
mover = lambda board: board.count(ex)==board.count(oh) and ex or oh
opponent = lambda player: player==ex and oh or ex
makesthreat = lambda player, cells: cells.count(blank)==1 and
opponent(player) not in cells
numthreats = lambda player, board: len([x for x in lines(board) if
makesthreat(player,x)])
haswon = lambda player, board: [player]*3 in lines(board)
marked = lambda board, index: [(board[i],mover(board))[i==index] for i
in range(9)]
display = lambda board: '\n\n' + '\n-+-+-\n'.join(['|'.join(board[3*i:
3*(i+1)]) for i in range(3)]) + '\n\n'
blankindices = lambda board: [i for i in range(9) if board[i]==blank]
isfinished = lambda board: blankindices(board)==[] or [ex]*3 in
lines(board) or [oh]*3 in lines(board)
numownthreats = lambda board: numthreats(mover(board),board)
numopponentsthreats = lambda board:
numthreats(opponent(mover(board)),board)
outcomevalue = lambda board: haswon(opponent(mover(board)),board) and
(-1) or haswon(mover(board),board) and (+1) or 0
assessment = lambda board: [outcomevalue(board),
(-1)*numopponentsthreats(board),(+1)*numownthreats(board)]
value = lambda board, index: blankindices(board) in [[],[index]] and
assessment(marked(board,index)) or \
 
min([assessment(marked(marked(board,index),i)) for i in
blankindices(board)if not i==index])
blankindexvalues = lambda board: [value(board,i) for i in
blankindices(board)]
analogisoptimal = lambda list1, list2, optimum: [x for (i,x) in
enumerate(list1) if list2[i]==optimum(list2)]
optimalblankindices = lambda board: blankindices(board) and
analogisoptimal(blankindices(board),blankindexvalues(board),max)
optimalmoves = lambda board: [marked(board,i) for i in
optimalblankindices(board)]
centergrabs = lambda board: [marked(board,i) for i in [4] if i in
blankindices(board)]
cornergrabs = lambda board: [marked(board,i) for i in [0,2,6,8] if i
in blankindices(board)]
tictactoemove = lambda board: len(blankindices(board)) in [8,9] and
(centergrabs(board) or cornergrabs(board))[0] or \
                              optimalmoves(board) and
optimalmoves(board)[0] or isfinished(board) and board

class tictactoeplayer:
    def __init__(self):
        globals()['mark'] = self.mark
        globals()['newgame'] = self.newgame
        globals()['turn'] = self.turn
        print 'ENTER mark(i) TO PLACE A MARK ON THE i-TH CELL'
        print '123' + '\n' + '456' + '\n' + '789'
        print 'ENTER newgame() TO START A NEW GAME'
        print 'ENTER turn() TO GIVE UP YOUR TURN'
        self.newgame()
    def mark(self,offbyoneindex):
        self.board = marked(self.board,offbyoneindex-1)
        print 'your move:' + display(self.board)
        self.turn()
    def newgame(self):
        self.board = [blank]*9
        print 'new game:' + display(self.board)
    def turn(self):
        self.board = tictactoemove(self.board)
        print 'my move:' + display(self.board)



More information about the Python-list mailing list