Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
    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()
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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]