""" this program makes an optimal tictactoe move by answering the following questions in their given order until it is told where to put its mark:
1) can you win the game? if so then do it 2) could your opponent win the game if it was his turn? if so then put your own mark where a mark of his would win him the game 3) could you win the game if you had two turns in a row? if so then make a move that leaves you with the largest number of second moves that would win you the game if you could really make them 4) is the center square open? if so then put your mark there 5) are any of the corners open? if so then put your mark on one of them 6) put your mark on any open square """ #) tictactoe; python 3.6.1 count = lambda dictionary, value: list(dictionary.values()).count(value) subdictionary = lambda dictionary, keys: {key: dictionary[key] for key in keys} ex, oh, blank = 'X0 ' indices = list(range(3)) vectors = [(i,j) for i in indices for j in indices] startgrid = {vector: blank for vector in vectors} display = lambda grid: '\n-+-+-\n'.join('|'.join(grid[i,j] for j in indices) for i in indices) iscenter = lambda vector: vector == (1,1) iscorner = lambda vector: vector[0]%2 == vector[1]%2 == 0 horizontal = [[(i,j) for j in indices] for i in indices] vertical = [[(i,j) for i in indices] for j in indices] diagonal = [[(i,i) for i in indices], [(i,2-i) for i in indices]] linear = horizontal + vertical + diagonal getrows = lambda grid: [subdictionary(grid,coordlist) for coordlist in linear] movermark = lambda grid: ex if count(grid,ex) == count(grid,oh) else oh opponent = lambda mark: ex if mark == oh else oh if mark == ex else blank strike = lambda vector, rows, ownmark: int(any(row for row in rows if vector in row and count(row,blank)==1 and count(row,ownmark)==2)) parry = lambda vector, rows, ownmark: int(any(row for row in rows if vector in row and count(row,blank)==1 and count(row,opponent(ownmark))==2)) threaten = lambda vector, rows, ownmark: len([row for row in rows if vector in row and count(row,blank)==2 and count(row,ownmark)==1]) position = lambda vector, rows, ownmark: 2 * int(iscenter(vector)) + int(iscorner(vector)) evaluate = lambda vector, rows, ownmark: [f(vector,rows,ownmark) for f in (strike,parry,threaten,position)] def movevector(grid,ownmark): from random import choice rows = getrows(grid) value = lambda vector: evaluate(vector,rows,ownmark) candidates = [(i,j) for i in indices for j in indices if grid[i,j] == blank] maximum = value(max(candidates,key=value)) if candidates else None coords = [vector for vector in candidates if value(vector) == maximum] return choice(coords) if coords and blank in grid.values() else None def getwinner(grid): rows = getrows(grid) rows = [list(row.values()) for row in rows] return ex if [ex]*3 in rows else oh if [oh]*3 in rows else None def makemove(grid): grid = grid.copy() ownmark = movermark(grid) vector = movevector(grid,ownmark) if vector: grid[vector] = ownmark return grid def getinteger(lower,upper,prompt): integer = None while integer == None: try: integer = int(input(prompt)) assert lower <= integer <= upper except KeyboardInterrupt: raise except: pass return integer def play(mark): grid = startgrid.copy() if mark == ex: grid = makemove(grid) print('\n\n' + display(grid) + '\n\n') winner = None while not winner and blank in grid.values(): cellnumber = getinteger(1,9,'cell number: ') grid[divmod(cellnumber-1,3)] = movermark(grid) winner = getwinner(grid) if not winner: grid = makemove(grid) winner = getwinner(grid) print('\n\n' + display(grid) + '\n\n') message = winner + ' wins' if winner else 'tied game' print(message) -- https://mail.python.org/mailman/listinfo/python-list