def __init__(self, battle_order="BLACK"): self.board = Board() self.players = None self.battle_order = battle_order self.turn = 0 self.winner = None # TODO self.game_record = None
def setup_game(self, config, nombre=""): tablero_logico = Board(config["tablero"]["dimension"]) tablero_logico.set_casillas(config["tablero"]["configuracion"]) tablero_logico.update_pieces_counters() self.__video.create_graphic_board(tablero_logico) jugador1 = Player(config["jugadores"][0]["color"],VIRTUAL) jugador2 = Player(config["jugadores"][1]["color"],HUMANO) self.juego = Game(self.__video.board,jugador1,jugador2,write_path=self.__write_path) self.juego.set_turn(jugador1) self.juego.increase_turn_number() if nombre == "mesh": self.juego.set_mesh_game(True) self.__usuario.set_player(jugador2)
def init_game(self, nombre, con_jugadas_posibles=True, nivel=Ai.FACIL): parser = Parser() archivo_juegos = open(os.path.abspath(self.__path_archivo_juegos)) elementos = parser.find_child_element("game_"+str(nombre),archivo_juegos) fichas_iniciales = [] if len(elementos) <= 0 : raise Exception("No se encontraron elementos para el juego: " + nombre + " en el archivo xml: " + self.__path_archivo_juegos) for e in elementos: if e.get_name() == 'features': board_dim = int(e.get_attribute('board')) if e.get_attribute('oponent') == "virtual": #Es un juego de mesh contra Humano jugador1 = Player(BLANCO,HUMANO) jugador2 = Player(NEGRO,VIRTUAL) else: #Es un juego contra la PC if e.get_attribute('white') == "user": jugador1 = Player(BLANCO,HUMANO) jugador2 = Player(NEGRO,PC) else: jugador1 = Player(BLANCO,PC) jugador2 = Player(NEGRO,HUMANO) if e.get_attribute('initiator') == "white": comienza = BLANCO else: comienza = NEGRO elif e.get_name() == 'piece': ficha = {} if e.get_attribute('color') == "black": ficha["color"] = NEGRO else: ficha["color"] = BLANCO ficha["posicion"] = (int(e.get_attribute('pos_f')),int(e.get_attribute('pos_c'))) fichas_iniciales.append(ficha) tablero_logico = Board(board_dim) if nombre == "tutorial1": tablero_logico.save_initial_configuration(fichas_iniciales) else: tablero_logico.set_up(fichas_iniciales) self.__video.create_graphic_board(tablero_logico) self.juego = Game(self.__video.board,jugador1,jugador2,con_jugadas_posibles,nivel,write_path=self.__write_path) if comienza == BLANCO: self.juego.set_turn(jugador1) else: self.juego.set_turn(jugador2) self.juego.increase_turn_number() if nombre == "mesh": self.juego.set_mesh_game(True) self.__usuario.set_player(jugador1) parser.close() archivo_juegos.close()
def __init__(self, window, difficulty_level, player_name, game_mode): self.window = window self.difficulty_level = difficulty_level self.game_mode = game_mode self.board = Board() self.board.draw(window) self.end_game = False self.player = BLACK self.possible_moves = self.get_possible_moves(self.board) self.black_pieces, self.white_pieces = self.board.count_pieces() self.status = Status(window, self.black_pieces, self.white_pieces, player_name) self.last_cord = [None, None] self.update()
def test_print_board(self): board = Board() with patch("sys.stdout", new=StringIO()) as fakeOutput: board.print() formatted_board = (" | | | | | | | \n" + "_ _ _ _ _ _ _ _\n" + " | | | | | | | \n" + "_ _ _ _ _ _ _ _\n" + " | | | | | | | \n" + "_ _ _ _ _ _ _ _\n" + " | | |l|d| | | \n" + "_ _ _ _ _ _ _ _\n" + " | | |d|l| | | \n" + "_ _ _ _ _ _ _ _\n" + " | | | | | | | \n" + "_ _ _ _ _ _ _ _\n" + " | | | | | | | \n" + "_ _ _ _ _ _ _ _\n" + " | | | | | | |") self.assertEqual(fakeOutput.getvalue().rstrip(), formatted_board)
def test_initial_board(self): board = Board() self.assertEqual(len(board.positions), 8) self.assertEqual(len(board.positions[0]), 8) self.assertEqual(board.positions[3][3], "l") self.assertEqual(board.positions[3][4], "d") self.assertEqual(board.positions[4][3], "d") self.assertEqual(board.positions[4][4], "l")
class Othello(object): def __init__(self, battle_order="BLACK"): self.board = Board() self.players = None self.battle_order = battle_order self.turn = 0 self.winner = None # TODO self.game_record = None def skip(self): pass def wait(self): pass def move(self, x, y): next_reversible = [] # ゲームが継続する条件: # 1: ボードにBLANKがある。かつ、どちらのプレイヤーもpassできない。 # TODO ゲーム終了条件: # 2: self.turn == 60 または、プレイヤの連続pass # プレイヤが、オセロを指す。 player = self.players[self.battle_order] hand = player.play(self.board, x, y) # 置ける場所だった場合、listに座標が入って返る。 # プレイヤのリクエストに対して、色が変わる場所のリストを、クライアント側まで返してあげる。 if hand: print(f"{player.name}の手は、({x}, {y})で、リバースする座標は、{hand}です。") # 手を指すことに成功したので、バトルチェンジをし、ターンをインクリメント。 self.change_battle_order() self.turn += 1 next_player = self.players[self.battle_order] # 次のプレイヤが、置ける場所を探索する。 # 戻り値が、空のリストの場合、passフラグを示す。 next_reversible = self.board.positionable(next_player.stone) print(f"{next_player}が、次に置ける手は、{next_reversible}です。") return { "reverse": hand, "next_battle_order": self.battle_order, "next_reversible": next_reversible } def change_battle_order(self): self.battle_order = "WHITE" if self.battle_order == "BLACK" else "BLACK" def init_player(self, players): self.players = players def end_game(self): pass
def init_game(self, nombre, con_jugadas_posibles=True, nivel=Ai.FACIL): parser = Parser() archivo_juegos = open(os.path.abspath(self.__path_archivo_juegos)) elementos = parser.find_child_element("game_" + str(nombre), archivo_juegos) fichas_iniciales = [] if len(elementos) <= 0: raise Exception("No se encontraron elementos para el juego: " + nombre + " en el archivo xml: " + self.__path_archivo_juegos) for e in elementos: if e.get_name() == 'features': board_dim = int(e.get_attribute('board')) if e.get_attribute('oponent') == "virtual": #Es un juego de mesh contra Humano jugador1 = Player(BLANCO, HUMANO) jugador2 = Player(NEGRO, VIRTUAL) else: #Es un juego contra la PC if e.get_attribute('white') == "user": jugador1 = Player(BLANCO, HUMANO) jugador2 = Player(NEGRO, PC) else: jugador1 = Player(BLANCO, PC) jugador2 = Player(NEGRO, HUMANO) if e.get_attribute('initiator') == "white": comienza = BLANCO else: comienza = NEGRO elif e.get_name() == 'piece': ficha = {} if e.get_attribute('color') == "black": ficha["color"] = NEGRO else: ficha["color"] = BLANCO ficha["posicion"] = (int(e.get_attribute('pos_f')), int(e.get_attribute('pos_c'))) fichas_iniciales.append(ficha) tablero_logico = Board(board_dim) if nombre == "tutorial1": tablero_logico.save_initial_configuration(fichas_iniciales) else: tablero_logico.set_up(fichas_iniciales) self.__video.create_graphic_board(tablero_logico) self.juego = Game(self.__video.board, jugador1, jugador2, con_jugadas_posibles, nivel, write_path=self.__write_path) if comienza == BLANCO: self.juego.set_turn(jugador1) else: self.juego.set_turn(jugador2) self.juego.increase_turn_number() if nombre == "mesh": self.juego.set_mesh_game(True) self.__usuario.set_player(jugador1) parser.close() archivo_juegos.close()
def setup_game(self, config, nombre=""): tablero_logico = Board(config["tablero"]["dimension"]) tablero_logico.set_casillas(config["tablero"]["configuracion"]) tablero_logico.update_pieces_counters() self.__video.create_graphic_board(tablero_logico) jugador1 = Player(config["jugadores"][0]["color"], VIRTUAL) jugador2 = Player(config["jugadores"][1]["color"], HUMANO) self.juego = Game(self.__video.board, jugador1, jugador2, write_path=self.__write_path) self.juego.set_turn(jugador1) self.juego.increase_turn_number() if nombre == "mesh": self.juego.set_mesh_game(True) self.__usuario.set_player(jugador2)
class Game: def __init__(self, window, difficulty_level, player_name, game_mode): self.window = window self.difficulty_level = difficulty_level self.game_mode = game_mode self.board = Board() self.board.draw(window) self.end_game = False self.player = BLACK self.possible_moves = self.get_possible_moves(self.board) self.black_pieces, self.white_pieces = self.board.count_pieces() self.status = Status(window, self.black_pieces, self.white_pieces, player_name) self.last_cord = [None, None] self.update() def get_end_game(self): return self.end_game def update(self): self.board.draw(self.window) self.draw_valid_moves(self.possible_moves) self.status.update(self.window, self.black_pieces, self.white_pieces) self.draw_click(self.last_cord) pygame.display.update() def change_turn(self): self.black_pieces, self.white_pieces = self.board.count_pieces() self.player = BLACK if self.player == WHITE else WHITE self.possible_moves = self.get_possible_moves(self.board) def stone_to_flip(self, board, row, column): if board.game_field[row][column] == 0: board.add_piece(row, column, self.player) pieces_to_flip = [] # list of pieces cords that will be fliped if self.player is WHITE: opponent_player = BLACK else: opponent_player = WHITE for xdirection, ydirection in DIRECTIONS: x = row y = column x += xdirection y += ydirection # check if we still on board and if there's a stone of the opponent player if coordinate_on_board( x, y ) and board.game_field[x][y] != 0 and board.game_field[x][ y].color == opponent_player: x += xdirection y += ydirection if not coordinate_on_board(x, y): continue while board.game_field[x][y] != 0 and board.game_field[x][ y].color is opponent_player: x += xdirection y += ydirection if not coordinate_on_board(x, y): break if not coordinate_on_board(x, y): continue if board.game_field[x][y] != 0 and board.game_field[x][ y].color == self.player: while True: x -= xdirection y -= ydirection if x == row and y == column: break pieces_to_flip.append([x, y]) # set the stone to 0 board.add_piece(row, column, 0) # If the list is empty return false if len(pieces_to_flip) == 0: return False else: return pieces_to_flip else: return False def get_possible_moves(self, board): valid_moves = [] for x in range(8): for y in range(8): stones = self.stone_to_flip(board, x, y) if stones is not False: if len(stones) is not 0: valid_moves.append([x, y]) return valid_moves def valid_move(self, row, col): move = [row, col] if move in self.possible_moves: return True else: return False def draw_valid_moves(self, moves): for move in moves: row, col = move pos = ((col * SQUARE_SIZE + SQUARE_SIZE // 2), (row * SQUARE_SIZE + SQUARE_SIZE // 2) + 75) pygame.draw.circle(self.window, HINT_COLOR, pos, RADIUS, 1) def draw_click(self, last_cord): x, y = last_cord if x is not None and y is not None: pos = ((y * SQUARE_SIZE + SQUARE_SIZE // 2), (x * SQUARE_SIZE + SQUARE_SIZE // 2) + 75) pygame.draw.circle(self.window, RED, pos, 5) def make_move(self, board, row, col): self.last_cord = [row, col] if self.valid_move(row, col) == True: stones = self.stone_to_flip(board, row, col) if stones != False: board.add_piece(row, col, self.player) for i in range(len(stones)): coordinate = stones[i] board.add_piece(coordinate[0], coordinate[1], self.player) self.change_turn() self.update() def skip(self): if not self.possible_moves: self.change_turn() self.update() if not self.possible_moves: self.end_game = True self.winner() return 0 print(f'{self.player} plays again!') def play(self, row, col): if self.end_game == False: #should be changed if self.game_mode == 1: if self.player == BLACK: self.make_move(self.board, row, col) self.skip() time.sleep(1) if self.player == WHITE: x, y = self.strategie(self.player, self.board) self.make_move(self.board, x, y) self.skip() else: self.make_move(self.board, row, col) self.skip() else: self.winner() def winner(self): if self.black_pieces > self.white_pieces: print( f'Black wins and the result is: White: {self.white_pieces}, Black: {self.black_pieces}' ) elif self.black_pieces < self.white_pieces: print( f'White wins and the result is: White: {self.white_pieces}, Black: {self.black_pieces}' ) else: print( f'Draw! And the result is: White: {self.white_pieces}, Black: {self.black_pieces}' ) """This section is for ai strategies""" def strategie(self, player, board): if self.difficulty_level == 1: return self.random_move() elif self.difficulty_level == 2: return self.best_weighted_move() elif self.difficulty_level == 3: score, move = self.minimax_alpha_beta(player, board, 4, -100000, 100000) return move #strategie 0 def random_move(self): return random.choice(self.possible_moves) def best_weighted_move(self): coord_best_move = [] best_move = -40 for x, y in self.possible_moves: if REWARD_SQUARES[x][y] >= best_move: best_move = REWARD_SQUARES[x][y] coord_best_move = [x, y] return coord_best_move #strategie 1 def simulate_move(self, board, player, row, col): if self.valid_move(row, col) == True: stones = self.stone_to_flip(board, row, col) if stones != False: board.add_piece(row, col, player) for i in range(len(stones)): coordinate = stones[i] board.add_piece(coordinate[0], coordinate[1], player) def evaluate(self, board, player): opponent = BLACK if player == WHITE else WHITE total = 0 #getting the cordinates of all pieces of a player on the board players_pieces = board.get_pieces(player) opponents_pieces = board.get_pieces(opponent) for piece_cord in players_pieces: total += REWARD_SQUARES[piece_cord[0]][piece_cord[1]] for piece_cord in opponents_pieces: total -= REWARD_SQUARES[piece_cord[0]][piece_cord[1]] return total def minimax_search(self, player, board, depth): opponent = BLACK if player == WHITE else WHITE legal_moves = self.get_possible_moves(board) if not legal_moves: return (self.evaluate(board, player), None) if depth == 0: return (self.evaluate(board, player), None) best_score = -100000 best_move = None for move in legal_moves: x, y = move new_board = copy.deepcopy(board) self.simulate_move(new_board, player, x, y) temp_eval = self.minimax_search(opponent, new_board, depth - 1) temp_score = -temp_eval[0] if temp_score > best_score: best_score = temp_score best_move = move return best_score, best_move def minimax_alpha_beta(self, player, board, depth, alpha, beta): opponent = BLACK if player == WHITE else WHITE legal_moves = self.get_possible_moves(board) if not legal_moves: return (self.evaluate(board, player), None) if depth == 0: return (self.evaluate(board, player), None) best_score = alpha best_move = None for move in legal_moves: x, y = move new_board = copy.deepcopy(board) self.simulate_move(new_board, player, x, y) temp_eval = self.minimax_alpha_beta(opponent, new_board, depth - 1, -beta, -best_score) temp_score = -temp_eval[0] if temp_score > best_score: best_score = temp_score best_move = move if best_score > beta: return best_score, best_move return best_score, best_move
def board_image(board_id: str) -> Response: try: board = Board.from_id(board_id) except ValueError: return make_response("Invalid board", 400) image_size = 800 cell_size = image_size / 8 disc_radius = 0.38 * cell_size move_radius = 0.08 * cell_size cross_width = 0.3 * cell_size body = f"""<?xml version="1.0"?> <svg width="{image_size}" height="{image_size}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%"> <stop offset="0%" style="stop-color: rgb(120,120,120);stop-opacity:1" /> <stop offset="100%" style="stop-color: black;stop-opacity:1" /> </linearGradient> <linearGradient id="grad2" x1="15%" y1="15%" x2="100%" y2="100%"> <stop offset="0%" style="stop-color: white;stop-opacity:1" /> <stop offset="100%" style="stop-color:rgb(150,150,150);stop-opacity:1" /> </linearGradient> </defs> <rect x="0" y="0" width="{image_size}" height="{image_size}" style="fill:green; stroke-width:2; stroke:black" /> """ for i in range(1, 8): offset = int(cell_size * i) body += f"""<line x1="{offset}" y1="0" x2="{offset}" y2="{image_size}" style="stroke:black; stroke-width:2" />\n""" body += f"""<line x1="0" y1="{offset}" x2="{image_size}" y2="{offset}" style="stroke:black; stroke-width:2" />\n""" mistakes = request.args.get("mistakes", "") mistake_indexes: Set[int] = set() for mistake in mistakes.split(","): try: mistake_indexes.add(int(mistake)) except ValueError: pass for index, field in enumerate(board.get_fields()): circle_x = (cell_size / 2) + cell_size * (index % 8) circle_y = (cell_size / 2) + cell_size * (index // 8) move_color = {BLACK: "black", WHITE: "white"}[board.turn] if field == VALID_MOVE: if index in mistake_indexes: cross_min_x = ((cell_size / 2) + cell_size * (index % 8) - (cross_width / 2)) cross_min_y = ((cell_size / 2) + cell_size * (index // 8) - (cross_width / 2)) cross_max_x = cross_min_x + cross_width cross_max_y = cross_min_y + cross_width body += f"""<line x1="{cross_min_x}" y1="{cross_min_y}" x2="{cross_max_x}" y2="{cross_max_y}" style="stroke:red; stroke-width:7" />\n <line x1="{cross_max_x}" y1="{cross_min_y}" x2="{cross_min_x}" y2="{cross_max_y}" style="stroke:red; stroke-width:7" />\n""" continue body += f"""<circle cx="{circle_x}" cy="{circle_y}" r="{move_radius}" fill="{move_color}" />\n""" continue if field == EMPTY: continue if field == BLACK: body += f""" <circle cx="{circle_x}" cy="{circle_y}" r="{disc_radius}" fill="url(#grad1)" /> <circle cx="{circle_x}" cy="{circle_y}" r="{disc_radius}" stroke="#222222" stroke-width="8" fill="none" /> """ continue if field == WHITE: body += f""" <circle cx="{circle_x}" cy="{circle_y}" r="{disc_radius}" fill="url(#grad2)" /> <circle cx="{circle_x}" cy="{circle_y}" r="{disc_radius}" stroke="#DDDDDD" stroke-width="8" fill="none" /> """ body += "</svg>" response = make_response(body) response.content_type = "image/svg+xml" if board_id == "xot": response.headers[ "Cache-Control"] = "no-cache, no-store, must-revalidate" response.headers["Pragma"] = "no-cache" response.headers["Expires"] = "0" return response