""" 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) -- http://mail.python.org/mailman/listinfo/python-list