def test_diagonal_finder(self): WIN.blit(BOARD, (0, 0)) checkers_test = Checkers(WIN) self.assertEqual(checkers_test.diagonal_finder(1, 1, 1, 1), (0, 0)) self.assertEqual(checkers_test.diagonal_finder(1, 1, 2, 1), (0, 2)) self.assertEqual(checkers_test.diagonal_finder(1, 1, 3, 1), (2, 2)) self.assertEqual(checkers_test.diagonal_finder(1, 1, 4, 1), (2, 0))
def getTree(self, board): tree = Node([0, 0, 0, 0], []) # create dummy node for move in Checkers.movesAvailable( Checkers(), board, self.player, False): # for all moves available to make tree.addChild( self.fillSubTree(board, self.player, 1, move)) # fill their trees and add to the return tree
def test_game_over(self): WIN.blit(BOARD, (0, 0)) checkers_test = Checkers(WIN) checkers_test.whitePeaces = 0 self.assertEqual(checkers_test.game_over(), "black") checkers_test.whitePeaces = 2 checkers_test.blackPeaces = 0 self.assertEqual(checkers_test.game_over(), "white")
def fillSubTree(self, board, player, depth, move): top = Node(move, copy.deepcopy(board)) # generate the boardstate root's move would make newBoard = Checkers.movePiece(self.checkers, copy.deepcopy(board), player, move, False, False) if depth > 1: # This will not go beyond depths of 1 (Add lowest children cared about) availMoves = Checkers.movesAvailable(Checkers(), copy.deepcopy(newBoard), ((-1) * player), False) for i in range(0, len(availMoves)): newChild = self.fillSubTree(copy.deepcopy(newBoard), ((-1) * player), (depth - 1), availMoves[i]) # make a new child node given A) the move it represents, and B) the boardstate that represents (created by movePiece) top.addChild(newChild) return top
def test_change_turn(self): WIN.blit(BOARD, (0, 0)) checkers_test = Checkers(WIN) if checkers_test.turn == "black": checkers_test.change_turn() self.assertEqual(checkers_test.turn, "white") else: checkers_test.change_turn() self.assertEqual(checkers_test.turn, "black")
def scoreNode(self, node): board = Checkers.movePiece(checkers, node.value, self.player * ((-1)**(self.depth + 1)), node.name, False, False) score = 0 for i in range(0, len(board)): for j in range(0, len(board[i])): # for every space in the board if isint(board[i][j]): # if it is an integer score += self.player * board[i][ j] # add score (accounting for who we're emulating) to score # end for loops # print(str(node.name) + " has a score of " + str(score) + " for player " + str(self.player)) # Checkers.printBoard(self, node.value) return score # when done with that, return score
from Checkers import Checkers wins = 0 draws = 0 games = 200 START_PLAYER = Checkers.BLACK for i in range(games): game = Checkers() # game.printBoard() player = START_PLAYER cnt = 0 # statesCounter = {} # state = None while cnt < 100: # state = game.encodeBoard() # if state not in statesCounter: # statesCounter[state] = 0 # statesCounter[state] += 1 # # the exact same state repeated 3 times -> draw # if statesCounter[state] == 3: # print("state repeated 3 times") # break evaluator1 = Checkers.evaluate1 evaluator2 = Checkers.evaluate2 if cnt > 25: evaluator1 = evaluator2 = Checkers.endGame if player == START_PLAYER: cont, reset = game.minimaxPlay(player, maxDepth=3, evaluate=evaluator1, enablePrint=False) if not cont:
for j in range(0, len(board[i])): # for every space in the board if isint(board[i][j]): # if it is an integer score += self.player * board[i][ j] # add score (accounting for who we're emulating) to score # end for loops # print(str(node.name) + " has a score of " + str(score) + " for player " + str(self.player)) # Checkers.printBoard(self, node.value) return score # when done with that, return score # end ABPruner if __name__ == "__main__": print("We're Agenting in here") checkers = Checkers() checkers.nextTurn depth = 3 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ print("AI will play team B") black = AlphaBeta(depth, 1, checkers) while checkers.nextTurn(): checkers.printBoard(checkers.board) print("It is %s's turn" % checkers.whoseTurn()) if checkers.whoseTurn() == "R": checkers.board = checkers.getMove(copy.deepcopy(checkers.board), checkers.turn, False) else:
def __init__(self) -> None: super().__init__() self.game = Checkers(CHECKER_SIZE) self.history = [self.game.getBoard()] self.historyPtr = 0 self.maxDepth = MAX_DEPTH self.player = STARTING_PLAYER if self.player == Checkers.WHITE and GAME_MODE == Mode.SINGLE_PLAYER: if USED_ALGORITHM == Algorithm.MINIMAX: self.game.minimaxPlay(1 - self.player, maxDepth=self.maxDepth, evaluate=EVALUATION_FUNCTION, enablePrint=False) elif USED_ALGORITHM == Algorithm.RANDOM: self.game.randomPlay(1 - self.player, enablePrint=False) self.history = [self.game.getBoard()] self.lastX = None self.lastY = None self.willCapture = False self.cnt = 0 self.btn = [[None] * self.game.size for _ in range(self.game.size)] frm_board = tk.Frame(master=window) frm_board.pack(fill=tk.BOTH, expand=True) for i in range(self.game.size): frm_board.columnconfigure(i, weight=1, minsize=IMG_SIZE) frm_board.rowconfigure(i, weight=1, minsize=IMG_SIZE) for j in range(self.game.size): frame = tk.Frame(master=frm_board) frame.grid(row=i, column=j, sticky="nsew") self.btn[i][j] = tk.Button(master=frame, width=IMG_SIZE, height=IMG_SIZE, relief=tk.FLAT) self.btn[i][j].bind("<Button-1>", self.click) self.btn[i][j].pack(expand=True, fill=tk.BOTH) frm_options = tk.Frame(master=window) frm_options.pack(expand=True) btn_undo = tk.Button(master=frm_options, command=self.undo, text="Undo") btn_undo.pack(side=tk.LEFT, padx=5, pady=5) btn_redo = tk.Button(master=frm_options, command=self.redo, text="Redo") btn_redo.pack(side=tk.LEFT, padx=5, pady=5) frm_counter = tk.Frame(master=window) frm_counter.pack(expand=True) self.lbl_counter = tk.Label(master=frm_counter) self.lbl_counter.pack() self.update() nextPositions = [move[0] for move in self.game.nextMoves(self.player)] self.highlight(nextPositions) window.mainloop()
def test_check_if_peace_there(self): WIN.blit(BOARD, (0, 0)) checkers_test = Checkers(WIN) self.assertFalse(checkers_test.check_if_peace_there(1, 1))
def main(): clock = pygame.time.Clock() run = True WIN.blit(BOARD, (0, 0)) checkers = Checkers(WIN) while run: clock.tick(FPS) if checkers.game_over() == "black": checkers.draw_winner_black() elif checkers.game_over() == "white": checkers.draw_winner_white() for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.MOUSEBUTTONDOWN: pos = pygame.mouse.get_pos() col, row = get_click_col_row(pos) WIN.blit(BOARD, (0, 0)) checkers.draw_turn() checkers.check_move(col, row) checkers.update_board() checkers.draw_turn() pygame.display.update()
from Checkers import Checkers game = Checkers() game.run()
def test_get_diagonal_tuple_black(self): WIN.blit(BOARD, (0, 0)) checkers_test = Checkers(WIN) self.assertEqual(checkers_test.get_diagonal_tuple_black(5, 5), tuple(range(3, 5)))
def test_check_if_used_legal_move(self): WIN.blit(BOARD, (0, 0)) checkers_test = Checkers(WIN) self.assertFalse(checkers_test.check_if_used_legal_move(1, 1))
def _checkers_pattern(self, name, c1, c2): col1 = getattr(world, c1) col2 = getattr(world, c2) p = Checkers(col1, col2) setattr(world, name, p)
from Checkers import Checkers wins = 0 draws = 0 games = 1000 START_PLAYER = Checkers.BLACK for i in range(games): game = Checkers() # game.printBoard() player = START_PLAYER cnt = 0 # statesCounter = {} # state = None while cnt < 100: # state = game.encodeBoard() # if state not in statesCounter: # statesCounter[state] = 0 # statesCounter[state] += 1 # # the exact same state repeated 3 times -> draw # if statesCounter[state] == 3: # print("state repeated 3 times") # break evaluate = Checkers.evaluate2 if cnt > 25: evaluate = Checkers.endGame if player == START_PLAYER: cont, reset = game.minimaxPlay(player,
class GUI: def __init__(self) -> None: super().__init__() self.game = Checkers(CHECKER_SIZE) self.history = [self.game.getBoard()] self.historyPtr = 0 self.maxDepth = MAX_DEPTH self.player = STARTING_PLAYER if self.player == Checkers.WHITE and GAME_MODE == Mode.SINGLE_PLAYER: if USED_ALGORITHM == Algorithm.MINIMAX: self.game.minimaxPlay(1 - self.player, maxDepth=self.maxDepth, evaluate=EVALUATION_FUNCTION, enablePrint=False) elif USED_ALGORITHM == Algorithm.RANDOM: self.game.randomPlay(1 - self.player, enablePrint=False) self.history = [self.game.getBoard()] self.lastX = None self.lastY = None self.willCapture = False self.cnt = 0 self.btn = [[None] * self.game.size for _ in range(self.game.size)] frm_board = tk.Frame(master=window) frm_board.pack(fill=tk.BOTH, expand=True) for i in range(self.game.size): frm_board.columnconfigure(i, weight=1, minsize=IMG_SIZE) frm_board.rowconfigure(i, weight=1, minsize=IMG_SIZE) for j in range(self.game.size): frame = tk.Frame(master=frm_board) frame.grid(row=i, column=j, sticky="nsew") self.btn[i][j] = tk.Button(master=frame, width=IMG_SIZE, height=IMG_SIZE, relief=tk.FLAT) self.btn[i][j].bind("<Button-1>", self.click) self.btn[i][j].pack(expand=True, fill=tk.BOTH) frm_options = tk.Frame(master=window) frm_options.pack(expand=True) btn_undo = tk.Button(master=frm_options, command=self.undo, text="Undo") btn_undo.pack(side=tk.LEFT, padx=5, pady=5) btn_redo = tk.Button(master=frm_options, command=self.redo, text="Redo") btn_redo.pack(side=tk.LEFT, padx=5, pady=5) frm_counter = tk.Frame(master=window) frm_counter.pack(expand=True) self.lbl_counter = tk.Label(master=frm_counter) self.lbl_counter.pack() self.update() nextPositions = [move[0] for move in self.game.nextMoves(self.player)] self.highlight(nextPositions) window.mainloop() def update(self): for i in range(self.game.size): f = i % 2 == 1 for j in range(self.game.size): if f: self.btn[i][j]['bg'] = 'gray30' else: self.btn[i][j]['bg'] = 'white' img = blank_img if self.game.board[i][j] == Checkers.BLACK_MAN: img = black_man_img elif self.game.board[i][j] == Checkers.BLACK_KING: img = black_king_img elif self.game.board[i][j] == Checkers.WHITE_MAN: img = white_man_img elif self.game.board[i][j] == Checkers.WHITE_KING: img = white_king_img self.btn[i][j]["image"] = img f = not f self.lbl_counter['text'] = f'Moves without capture: {self.cnt}' window.update() def highlight(self, positions: Positions): for x in range(self.game.size): for y in range(self.game.size): defaultbg = self.btn[x][y].cget('bg') self.btn[x][y].master.config(highlightbackground=defaultbg, highlightthickness=3) for position in positions: x, y = position self.btn[x][y].master.config(highlightbackground="yellow", highlightthickness=3) def click(self, event): info = event.widget.master.grid_info() x, y = info["row"], info["column"] if self.lastX == None or self.lastY == None: moves = self.game.nextMoves(self.player) found = (x, y) in [move[0] for move in moves] if found: self.lastX = x self.lastY = y normal, capture = self.game.nextPositions(x, y) positions = normal if len(capture) == 0 else capture self.highlight(positions) else: print("Invalid position") return normalPositions, capturePositions = self.game.nextPositions( self.lastX, self.lastY) positions = normalPositions if (len(capturePositions) == 0) else capturePositions if (x, y) not in positions: print("invalid move") if not self.willCapture: self.lastX = None self.lastY = None nextPositions = [ move[0] for move in self.game.nextMoves(self.player) ] self.highlight(nextPositions) return canCapture, removed, _ = self.game.playMove(self.lastX, self.lastY, x, y) self.highlight([]) self.update() self.cnt += 1 self.lastX = None self.lastY = None self.willCapture = False if removed != 0: self.cnt = 0 if canCapture: _, nextCaptures = self.game.nextPositions(x, y) if len(nextCaptures) != 0: self.willCapture = True self.lastX = x self.lastY = y self.highlight(nextCaptures) return if GAME_MODE == Mode.SINGLE_PLAYER: cont, reset = True, False if USED_ALGORITHM == Algorithm.MINIMAX: evaluate = EVALUATION_FUNCTION if self.cnt > 20: evaluate = Checkers.endGame if INCREASE_DEPTH: self.maxDepth = 7 else: evaluate = Checkers.evaluate2 self.maxDepth = MAX_DEPTH cont, reset = self.game.minimaxPlay(1 - self.player, maxDepth=self.maxDepth, evaluate=evaluate, enablePrint=False) elif USED_ALGORITHM == Algorithm.RANDOM: cont, reset = self.game.randomPlay(1 - self.player, enablePrint=False) self.cnt += 1 if not cont: messagebox.showinfo(message="You Won!", title="Checkers") window.destroy() return self.update() if reset: self.cnt = 0 else: self.player = 1 - self.player if self.cnt >= 100: messagebox.showinfo(message="Draw!", title="Checkers") window.destroy() return nextPositions = [move[0] for move in self.game.nextMoves(self.player)] self.highlight(nextPositions) if len(nextPositions) == 0: if GAME_MODE == Mode.SINGLE_PLAYER: messagebox.showinfo(message="You lost!", title="Checkers") else: winner = "BLACK" if self.player == Checkers.WHITE else "WHITE" messagebox.showinfo(message=f"{winner} Player won!", title="Checkers") window.destroy() self.history = self.history[:self.historyPtr + 1] self.history.append(self.game.getBoard()) self.historyPtr += 1 def undo(self): if self.historyPtr > 0 and not self.willCapture: self.historyPtr -= 1 self.game.setBoard(self.history[self.historyPtr]) self.update() self.lastX = self.lastY = None nextPositions = [ move[0] for move in self.game.nextMoves(self.player) ] self.highlight(nextPositions) else: print("Can't undo") def redo(self): if self.historyPtr < len(self.history) - 1 and not self.willCapture: self.historyPtr += 1 self.game.setBoard(self.history[self.historyPtr]) self.update() self.lastX = self.lastY = None nextPositions = [ move[0] for move in self.game.nextMoves(self.player) ] self.highlight(nextPositions) else: print("Can't redo")