Example #1
0
 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
Example #2
0
 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)
Example #3
0
 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()
Example #4
0
 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()
Example #5
0
    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)
Example #6
0
    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")
Example #7
0
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
Example #8
0
 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()
Example #9
0
 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)
Example #10
0
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
Example #11
0
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