ultimate/board2.py

126 lines
3.6 KiB
Python

#!/usr/bin/env python
import copy
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]
spaces = 0
for i in range(3):
for j in range(3):
if b[i][j] != Board.unplayed:
spaces += 1
if spaces == 9:
return Board.tie
return Board.unplayed
class Board:
unplayed = 0
cross = 1
nought = 2
tie = 3
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 copy(self):
new = Board()
new.board = copy.deepcopy(self.board)
new.moves = copy.deepcopy(self.moves)
new.turn = copy.deepcopy(self.turn)
return new
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[j][i] == Board.unplayed:
for k in range(3):
for l in range(3):
if self.board[i][j][k][l] == Board.unplayed:
buf.append(TwoDPos(TwoDPos.l, (i, j, k, l)))
return buf
def possible(self):
# check if board is in final state
isFinal = BoardTools.winning(self, self.metaboard())
if isFinal in [Board.tie, Board.cross, Board.nought]:
return []
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]) in [Board.tie, Board.nought, Board.cross]:
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