#!/usr/bin/env python from pos import TwoDPos class BoardTools: def __init__(self): pass def winning(self, b): for i in range(3): if b[i][0] == b[i][1] == b[i][2]: if b[i][0] != Board.unplayed: return b[i][0] if b[0][i] == b[1][i] == b[2][i]: if b[0][i] != Board.unplayed: return b[0][i] if b[0][0] == b[1][1] == b[2][2]: if b[0][0] != Board.unplayed: return b[0][0] if b[2][0] == b[1][1] == b[0][2]: if b[2][0] != Board.unplayed: return b[2][0] return Board.unplayed class Board: unplayed = 0 cross = 1 nought = 2 def __init__(self): self.board = [ [ [ [Board.unplayed for i in range(3)] for j in range(3) ] for k in range(3) ] for l in range(3) ] self.moves = [] self.turn = Board.cross def set(self, a, b, c, d, val): self.board[a][b][c][d] = val def get(self, a, b, c, d): return self.board[a][b][c][d] def alternate(self): if self.turn == Board.cross: self.turn = Board.nought else: self.turn = Board.cross def subWin(self, x, y): return BoardTools.winning(None, self.board[x][y]) def metaboard(self): return [[BoardTools.winning(None, self.board[x][y]) for x in range(3)] for y in range(3)] def win(self): return BoardTools.winning(self.metaboard()) def append(self, move): self.moves.append(move) self.set(*move.local(), self.turn) self.alternate() def reachableEmpty(self): metaboard = self.metaboard() buf = [] for i in range(3): for j in range(3): if metaboard[i][j] == Board.unplayed: for k in range(3): for l in range(3): buf.append(TwoDPos(TwoDPos.l, (i, j, k, l))) return buf def possible(self): try: move = self.moves[-1] except IndexError: buf = [] for i in range(3): for j in range(3): for k in range(3): for l in range(3): buf.append(TwoDPos(TwoDPos.l, (i, j, k, l))) return buf local = move.local() if self.subWin(local[2], local[3]): return self.reachableEmpty() buf = [] for i in range(3): for j in range(3): if self.board[local[2]][local[3]][i][j] == Board.unplayed: buf.append(TwoDPos(TwoDPos.l, (local[2], local[3], i, j))) return buf