Esempio n. 1
0
def test_game():
    game = Game()
    assert game.players[0].name == "Player X"
    assert game.players[1].name == "Player O"

    assert not game.make_move(0)  # player 1

    assert game.is_position_taken(0)
    with pytest.raises(ValueError):
        assert game.is_position_taken(200)

    assert game.current_player == game.players[1]
    assert not game.make_move(4)  # player 2

    assert not game.make_move(1)  # player 1
    assert not game.make_move(5)  # player 2
    assert game.make_move(2)  # player 1
    assert game.get_winner() == game.players[0]
    assert game.is_end_of_game()
    assert not game.is_array_full()

    game2 = Game()

    # Cannot make a move to a position outside the game array limit
    with pytest.raises(ValueError):
        game2.make_move(123)

    assert not game2.make_move(0)  # player 1
    assert not game2.make_move(3)  # player 2
    assert not game2.make_move(1)  # player 1
    assert not game2.make_move(4)  # player 2
    assert not game2.make_move(8)  # player 1
    assert game2.make_move(5)  # player 2
    assert game2.get_winner() == game2.players[1]
    assert game.is_end_of_game()
    assert not game.is_array_full()
Esempio n. 2
0
def run_game():
    """
    This function handles the game of the client/server program. The function first
    creates an object of Game which it will use to access the Game board and the
    class data members. Next the function creates sockets and makes connections and
    displays them. It then displays the current round number and validates input
    entered on the client side. If the quit command was entered the program will quit
    and let the server know to quit as well. Otherwise, the position is updated with
    the client's symbol, board is shown and the game is checked if a win occurred and will
    subsequently exit and let the server know to exit as well. Otherwise data is obtained from
    the server; checked if it needs to quit - otherwise make the move on the board for the server
    and check if a win occurred.
    :return:
    """
    player = Game()

    try:
        # learned how to create socket from: https://docs.python.org/3/howto/sockets.html
        # socket object creation
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # allow socket re-use - obtained from assignment PDF
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # handle errors creating sockets
    except socket.error:
        print("Error creating socket! EXITING PROGRAM!!")
        sys.exit(1)

    # if sockets were created successfully continue
    else:

        # handle any socket error exceptions
        try:
            # connect client to the server
            s.connect((HOST, 5500))

            # display successful connection
            print(f"Connected to:  {HOST} on port: {PORT}")
            player.game_rules()

            while True:
                # show current round number
                global ROUND
                print("\n")
                print("#" * 15 + f" ROUND: {ROUND} " + "#" * 15)

                # increment variable for next round
                ROUND += 1

                # prompt for and perform input validation
                client_message = validate_input(player)

                # call function to send data
                send_data(s, client_message)

                # if client chose to quit, shutdown sockets and end program
                if client_message == '/q':
                    s.close()
                    sys.exit(0)

                # update board to reflect player's move and display board
                player.make_move(int(client_message), 'X')
                player.show_board()

                # check if game is over
                player.check_game("  X  ")

                # if the game is over then close sockets and exit program
                if player.game_over:
                    s.close()
                    sys.exit(0)

                print("\nWaiting for opponent's move...")

                # call function to receive data
                server_reply = receive_data(s)

                # if server chose to quit, shutdown sockets and end program
                if server_reply == '/q':
                    s.close()
                    sys.exit(0)

                # update board to reflect opponent's move and display board
                player.make_move(int(server_reply), 'O')
                player.show_board()

                # check if game is over
                player.check_game("  O  ")

                # if the game is over then close sockets and exit program
                if player.game_over:
                    s.close()
                    sys.exit(0)

        # if the socket failed for any reason display error message, close socket, exit program with 1
        # create a tuple to hold the common errors. obtained this from my own Project 1 assignment.
        except (socket.herror, socket.herror, socket.timeout,
                RuntimeError) as error:
            print(
                f"ERROR: Program has failed due to a {type(error).__name__} error!"
            )
            s.close()
            sys.exit(1)
Esempio n. 3
0
def run_game():
    """
        This function handles the game of the client/server program. The function first
        creates an object of Game which it will use to access the Game board and the
        class data members. Next the function creates sockets and makes connections and
        displays them. It then displays the current round number and then obtains the client's
        message. If the client had wanted to quit, then close sockets and end program. Otherwise,
        update client's move and check if game is over via win or draw and display the board. If
        the game is over, then send quit message to client and display output and close server.
        Otherwise get/validate input for the server's move and check if user wanted to quit.
        If the user wanted to quit server, let the client know and then close sockets and end
        program. Otherwise update the server's move on the board, send move to client and then
        check for game being over.
        :return:
        """
    player = Game()

    try:
        # learned how to create socket from: https://docs.python.org/3/howto/sockets.html
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # allow socket re-use - obtained from assignment PDF
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    except socket.error:
        print("Error creating socket! EXITING PROGRAM!!")
        sys.exit(1)

    else:
        # bind the socket
        s.bind((HOST, PORT))

        # listen for connections to server. only allowing one
        s.listen(1)

        # display server host and port
        print(f"Server listening on: {HOST} on port: {PORT}")

        while True:
            # create the connection to the client
            client_connection, client_address = s.accept()

            # verify connection details between server and client
            print(f"Connected by {client_address}")
            player.game_rules()

            # partially inspired from https://www.geeksforgeeks.org/socket-programming-python/
            # continue accepting connections while server code is running
            while True:
                # show current round number
                global ROUND
                print("\n")
                print("#" * 15 + f" ROUND: {ROUND} " + "#" * 15)

                # increment variable for next round number
                ROUND += 1

                print("\nWaiting for opponent's move...")

                try:
                    # call function to receive data from client
                    client_message = receive_data(client_connection)

                except socket.error:
                    print("Unable to receive data on this socket!")
                    sys.exit(1)

                else:

                    # if the client had chosen to quit then close sockets and end program
                    if client_message == '/q':
                        client_connection.close()
                        s.close()
                        sys.exit(0)

                    # otherwise update board to reflect opponents move and print it out
                    player.make_move(int(client_message), 'X')
                    player.show_board()

                    # check if game is over
                    player.check_game("  X  ")

                    # if the game is over then quit and close server
                    if player.game_over:
                        client_connection.close()
                        s.close()
                        sys.exit(0)

                    # otherwise prompt for and perform input validation
                    server_msg = validate_input(player)

                    # if server user had chosen to quit let client know & close sockets and end program
                    if server_msg == '/q':
                        send_data(client_connection, server_msg)
                        client_connection.close()
                        s.close()
                        sys.exit(0)

                    # update board to reflect player's move and print it out
                    player.make_move(int(server_msg), 'O')
                    player.show_board()

                    # check for a win
                    player.check_game("  O  ")

                    try:
                        # send the move over to the opponent
                        send_data(client_connection, server_msg)

                    except socket.error:
                        print("Unable to send data on this socket!")
                        sys.exit(1)

                    # if the game is over then quit and close server
                    if player.game_over:
                        client_connection.close()
                        s.close()
                        sys.exit(0)
Esempio n. 4
0
            game.undo_move(m)
            if next_move_val < min_val:
                min_val = next_move_val
                best_move = m
                if next_move_val < 0:
                    break
    if i == 0:
        return best_move

    return max_val if i % 2 == 0 else min_val


if (x_first):
    print("valid moves are ", game.valid_moves)
    move = int(input("player one(X), make first move: "))
    game.make_move(move)

while not game.is_over():
    if game.player == X:
        print("valid moves are ", game.valid_moves)
        move = int(input("please make move: "))
    else:
        move = minimax(game, 0)
        print("computer is now making move ", move)
    game.make_move(move)
    print(game)

if game.winner_exists():
    print("You win!" if game.get_winner() == X else "You lose!")
else:
    print("player one and two ties")
Esempio n. 5
0
get_random_valid_move = lambda g: random.choice(list(g.valid_moves.keys()))
get_best_move = lambda q, valid_moves: next(e for e in map(
    lambda e: e[0],
    sorted(list(enumerate(q[0])), reverse=True, key=lambda e: e[1]))
                                            if e in valid_moves)

avg_losses = []
losses = 0
counter = 0
import time
start = time.time()
for epoch in range(epochs):
    x_first = random.random() < .5
    game = Game(X if x_first else O)
    if x_first:
        game.make_move(get_random_valid_move(game))

    state = t.Tensor(game.board.reshape(1, -1))
    y_turn = True
    while True:
        if y_turn:
            q = model(state)
            valid_moves = game.valid_moves.keys()
            if random.random() < epsilon:
                move = get_random_valid_move(game)
            else:
                move = get_best_move(q, valid_moves)

            game.make_move(move)
            board_to_str = lambda b: ''.join(map(lambda s: str(s), b))