186 lines
6.2 KiB
Python
186 lines
6.2 KiB
Python
import pygame
|
|
|
|
from .constants import BLACK, ROWS, GREEN, SQUARE_SIZE, COLS, WHITE
|
|
from .piece import Piece
|
|
|
|
|
|
class Board:
|
|
def __init__(self):
|
|
self.board = []
|
|
self.greenLeft = self.whiteLeft = 12
|
|
self.greenKings = self.whiteKings = 0
|
|
self.createBoard()
|
|
|
|
def drawSquares(self, win):
|
|
win.fill(BLACK)
|
|
for row in range(ROWS):
|
|
for col in range(row % 2, ROWS, 2):
|
|
pygame.draw.rect(win, GREEN, (row * SQUARE_SIZE, col * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
|
|
|
|
def createBoard(self):
|
|
for row in range(ROWS):
|
|
self.board.append([])
|
|
for col in range(COLS):
|
|
if col % 2 == ((row + 1) % 2):
|
|
if row < 3:
|
|
self.board[row].append(Piece(row, col, WHITE))
|
|
elif row > 4:
|
|
self.board[row].append(Piece(row, col, GREEN))
|
|
else:
|
|
self.board[row].append(None)
|
|
else:
|
|
self.board[row].append(None)
|
|
|
|
def draw(self, win):
|
|
self.drawSquares(win)
|
|
for row in range(ROWS):
|
|
for col in range(COLS):
|
|
piece = self.board[row][col]
|
|
if piece is not None:
|
|
piece.draw(win)
|
|
|
|
def move(self, piece, row, col):
|
|
self.board[piece.row][piece.col], self.board[row][col] = self.board[row][col], self.board[piece.row][piece.col]
|
|
piece.move(row, col)
|
|
|
|
if row == ROWS - 1 or row == 0:
|
|
piece.makeKing()
|
|
if piece.colour == WHITE:
|
|
self.whiteKings += 1
|
|
else:
|
|
self.greenKings += 1
|
|
|
|
def remove(self, skipped):
|
|
for piece in skipped:
|
|
self.board[piece.row][piece.col] = None
|
|
if piece is not None:
|
|
if piece.colour == GREEN:
|
|
self.greenLeft -= 1
|
|
else:
|
|
self.whiteLeft -= 1
|
|
|
|
def getPiece(self, row, col):
|
|
return self.board[row][col]
|
|
|
|
def winner(self):
|
|
if self.greenLeft <= 0:
|
|
return WHITE
|
|
elif self.whiteLeft <= 0:
|
|
return GREEN
|
|
|
|
return None
|
|
|
|
def getValidMoves(self, piece):
|
|
moves = {}
|
|
forcedCapture = {}
|
|
left = piece.col - 1
|
|
right = piece.col + 1
|
|
row = piece.row
|
|
if piece.colour == GREEN:
|
|
moves.update(self._traverseLeft(row - 1, max(row - 3, -1), -1, piece.colour, left))
|
|
moves.update(self._traverseRight(row - 1, max(row - 3, -1), -1, piece.colour, right))
|
|
if piece.colour == WHITE:
|
|
moves.update(self._traverseLeft(row + 1, min(row + 3, ROWS), 1, piece.colour, left))
|
|
moves.update(self._traverseRight(row + 1, min(row + 3, ROWS), 1, piece.colour, right))
|
|
|
|
if piece.king:
|
|
moves.update(self._traverseLeft(row - 1, max(row - 3, -1), -1, piece.colour, left))
|
|
moves.update(self._traverseRight(row - 1, max(row - 3, -1), -1, piece.colour, right))
|
|
moves.update(self._traverseLeft(row + 1, min(row + 3, ROWS), 1, piece.colour, left))
|
|
moves.update(self._traverseRight(row + 1, min(row + 3, ROWS), 1, piece.colour, right))
|
|
|
|
if len(moves.values()) <= 1:
|
|
return moves
|
|
|
|
movesValues = list(moves.values())
|
|
movesKeys = list(moves.keys())
|
|
|
|
forced = {}
|
|
|
|
for i in range(len(movesKeys)):
|
|
if not movesValues[i]:
|
|
forced[movesKeys[i]] = moves[movesKeys[i]]
|
|
if len(forced) != len(moves):
|
|
forced.clear()
|
|
for i in range(len(movesKeys)):
|
|
if movesValues[i]:
|
|
forced[movesKeys[i]] = moves[movesKeys[i]]
|
|
if len(forced) != len(moves):
|
|
for i in range(len(movesKeys)):
|
|
if movesValues[i]:
|
|
forcedCapture[movesKeys[i]] = moves[movesKeys[i]]
|
|
else:
|
|
forcedCapture = forced
|
|
else:
|
|
forcedCapture = forced
|
|
return forcedCapture
|
|
|
|
def scoreOfTheBoard(self):
|
|
return self.whiteLeft - self.greenLeft
|
|
|
|
def getAllPieces(self, colour):
|
|
pieces = []
|
|
for row in self.board:
|
|
for piece in row:
|
|
if piece is not None and piece.colour == colour:
|
|
pieces.append(piece)
|
|
return pieces
|
|
|
|
def _traverseLeft(self, start, stop, step, colour, left, skipped=[]):
|
|
moves = {}
|
|
last = []
|
|
for row in range(start, stop, step):
|
|
if left < 0:
|
|
break
|
|
mvs = self._traverse(row, left, skipped, moves, step, last, colour)
|
|
if mvs is None:
|
|
break
|
|
elif isinstance(mvs, list):
|
|
last = mvs
|
|
else:
|
|
moves.update(mvs)
|
|
left -= 1
|
|
return moves
|
|
|
|
def _traverseRight(self, start, stop, step, colour, right, skipped=[]):
|
|
moves = {}
|
|
last = []
|
|
for row in range(start, stop, step):
|
|
if right >= COLS:
|
|
break
|
|
|
|
mvs = self._traverse(row, right, skipped, moves, step, last, colour)
|
|
if mvs is None:
|
|
break
|
|
elif isinstance(mvs, list):
|
|
last = mvs
|
|
else:
|
|
moves.update(mvs)
|
|
|
|
right += 1
|
|
return moves
|
|
|
|
def _traverse(self, row, col, skipped, moves, step, last, colour):
|
|
current = self.board[row][col]
|
|
if current is None:
|
|
if skipped and not last:
|
|
return None
|
|
elif skipped:
|
|
moves[(row, col)] = last + skipped
|
|
else:
|
|
moves[(row, col)] = last
|
|
|
|
if last:
|
|
if step == -1:
|
|
rowCalc = max(row - 3, 0)
|
|
else:
|
|
rowCalc = min(row + 3, ROWS)
|
|
moves.update(self._traverseLeft(row + step, rowCalc, step, colour, col - 1, skipped=last))
|
|
moves.update(self._traverseRight(row + step, rowCalc, step, colour, col + 1, skipped=last))
|
|
return None
|
|
elif current.colour == colour:
|
|
return None
|
|
else:
|
|
last = [current]
|
|
return last
|