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)
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)