def __init__(self, server_addr = DEFAULT_ADDR): # run network connections in it's own thread thread.start_new_thread(self.network_loop, server_addr) # store all of the connections so they can be responded to self.customers = dict() self.order_database = [] # create and run the gui self.GUI = Display(self) self.GUI.mainloop()
def __init__(self): self.curr_player = X # whose turn is it? # the computer players self.learning_player = LearningPlayer(O) self.perfect_player = PerfectPlayer(O) self.computer_player = self.learning_player self.game = Game() # new game/board # run the gui self.gui = Display(self) self.gui.mainloop()
class Controller: def __init__(self): self.curr_player = X # whose turn is it? # the computer players self.learning_player = LearningPlayer(O) self.perfect_player = PerfectPlayer(O) self.computer_player = self.learning_player self.game = Game() # new game/board # run the gui self.gui = Display(self) self.gui.mainloop() # reset the game def reset(self): self.curr_player = X self.game = Game() if self.computer_player.get_player() == X: self.get_computer_move() # X goes first # Called by the GUI so this means a human moved. Update the game and get the computer's move def make_move(self, x, y): # check that the move is valid if self.get_position(x,y) == EMPTY and self.game.set_position(self.curr_player, x, y): self.switch_player() # other players turn now winner = self.game_over() # was there a winner? # game isn't over so get the computer player's move if not winner: self.get_computer_move() # get the move from the computer def get_computer_move(self): move = self.computer_player.make_move(self.game.board) # the computer's move # convert from 1D to 2D y = move/SIZE x = move%SIZE self.game.set_position(self.curr_player, x, y) # update the game board self.gui.update_button(x, y) # update the GUI self.game_over() # check if the game is over self.switch_player() # other players turn now # this is the fun stuff! Have the machine learn from the observed behavior def learn(self): print '\n\nLearning\n\n' # Ideally we want it to learn until it gets every move right, but at somepoint we have to stop learning for i in range(20000): self.learning_player.learn_all_known_boards() # see how many moves the machine got right and how many it got wrong print 'Pass', i, 'correct_moves:', self.learning_player.passed_moves, 'incorrect moves:', self.learning_player.failed_moves if not self.learning_player.failed_moves: # got every move right! num_passes = i break print '\n\nIt took', i, 'iterations but I learned all of the moves!\n\n' def forget(self): self.learning_player.forget() print '\n\nI just forgot how to play\n\n' def get_position(self, x, y): return self.game.get_position(x, y) # has somebody won? if not, was there a tie? def game_over(self): winner = self.game.has_winner() if winner: # somebody won self.gui.game_over(winner) return True elif self.game.is_full(): # board is full -> tie self.gui.game_over(None) return True return False # game is not over # set what player the computer player is (X or O) def set_player(self, player): self.learning_player.set_player(-1*STRINGS[player]) self.perfect_player.set_player(-1*STRINGS[player]) # switch between whose turn it is def switch_player(self): if self.curr_player == X: self.curr_player = O else: self.curr_player = X # set the type of computer player (learning or perfect) def set_comp_type(self, comp_type): if comp_type == 'Perfect': self.computer_player = self.perfect_player else: self.computer_player = self.learning_player
class Server: # DEFAULT_ADDR = (gethostbyname(gethostname()), 5555) DEFAULT_ADDR = ('127.0.0.1', 5555) def __init__(self, server_addr = DEFAULT_ADDR): # run network connections in it's own thread thread.start_new_thread(self.network_loop, server_addr) # store all of the connections so they can be responded to self.customers = dict() self.order_database = [] # create and run the gui self.GUI = Display(self) self.GUI.mainloop() def network_loop(self, name, port): server_addr = (name, port) server_socket = socket(AF_INET, SOCK_STREAM) # create a socket try: # attemps to bind to user specified address... server_socket.bind(server_addr) except: # ...if it was invalid just use default address print '[WARN]: Could not bind to address', server_addr, 'using default address', self.DEFAULT_ADDR server_addr = self.DEFAULT_ADDR server_socket.bind(server_addr) server_socket.listen(1) # listen for connections print "Server is ready for clients to connect at:", server_addr while 1: connection_socket, addr = server_socket.accept() # accept connection thread.start_new_thread(self.service_client, (connection_socket, addr)) # create a new thread to service a client def service_client(self, connection_socket, addr): request_message = connection_socket.recv(2048) # read the data from the client print 'recieved request:', request_message, 'from:', addr if request_message != '': # Respond to a query of the data base by sending the most recent orders # query format: qry <optional name> if request_message.split()[0] == 'qry': if len(request_message.split()): # if they provided a name pass that as an arg response = self.query_response(' '.join(request_message.split()[1:])) else: # just a general query response = self.query_response() if response == '': # if there were no results return an empty response connection_socket.send('emt') else: connection_socket.send('qry;' + response) else: # recieve an order connection_socket.send('rcv') # let the client know that its order was recieved # parse the message user, name, order, price = self.parse_request(request_message) # store the customer's information for later contact self.customers[user] = connection_socket # update the GUI self.GUI.takeOrder(user, name, order, price) ################################################################################################################################# # parse the request. The request format is defined as such: # # # # [ # # # # <order name> <{optional}with [side]> <{optional}Add [topping]>, <{optional}Add [topping]>, ...., <{optional}Add [topping]> # # # # <order name> <{optional}with [side]> <{optional}Add [topping]>, <{optional}Add [topping]>, ...., <{optional}Add [topping]> # # . # # . # # . # # # # Price: <price> # # # # Name: <name> # # # # Bowdoin I.D.: <i.d.> # # # # ] # ################################################################################################################################# def parse_request(self, request): # split it into its constituent parts request = request.split('\n\n') # these fields are garuanteed price = request[-4].split('Price: ')[1] name = request[-3].split('Name: ')[1] user = request[-2].split('Bowdoin I.D.: ')[1] # this is the order part of the message request = request[1:-4] self.store_in_database(name, request) # store the order # parse the order order = '' for item in request: # each item in the order item = item.split() # split into words ####################################################################################################### # loop through all the words and format the sides and toppings to be easily seen separately like such # # # # <name> # # <side> # # <topping> # ####################################################################################################### word_index = 0 while word_index < len(item): if item[word_index] == 'with' or item[word_index] == 'Add': item.insert(word_index, '\n\t') word_index += 1 word_index += 1 # join it back into one string order += ' '.join(item) + '\n' return user, name, order, price # track the orders in a database (just a list of names and items) def store_in_database(self, name, request): for item in request: self.order_database.append((name, item)) # respond to a query with the most recent orders in the database for the name provided # if there is no name then just give the most recent orders by anyone def query_response(self, name=None): MAX_RESPONSE_SIZE = 30 # TODO test this value curr_response_size = 0 response = '' # reversed because we want the most recent for index in reversed(range(len(self.order_database))): if curr_response_size >= MAX_RESPONSE_SIZE: break # b/c don't want to send too much data this_item = self.order_database[index] # format the response: name:item;name:item;.... for ease of parsing in the clients if not name or this_item[0] == name: response += this_item[0] + ':' + this_item[1] + ';' curr_response_size += 1 return response # send a message to a customer. We only need to do this once so then the connection can be closed def send_msg(self, customer_id, response): if customer_id in self.customers.keys(): print 'sending', response, 'to', self.customers[customer_id] self.customers[customer_id].send(response) self.customers[customer_id].close() del self.customers[customer_id]