def getData(socket, callback):
    try:
        # compute the length of the message (4 byte, little-endian)
        recstr = socket.recv(4)
        while len(recstr) < 4:
            recstr += socket.recv(4 - len(recstr))
        assert len(recstr) == 4
        lenstr = ["{:02x}".format(ord(char)) for char in recstr]
        lenstr.reverse()
        length = int(''.join(lenstr), 16)
        
        # receive message into buffer
        data = socket.recv(length)
        received = len(data)
        buff = []
        while received < length:
            buff.append(data)
            data = socket.recv(length - received)
            received += len(data)
        else:
            assert received == length
            if buff:
                buff.append(data)
                data = ''.join(buff)
        return data
    except sock.timeout:
        trap("Socket operation (receive) timed out")
        return None
    except sock.error as err: # fix this
        if err.errno == 10054: # The connection has been reset.
            callback.connectionLost(err)
        else:
            printrap("WARNING - socket error on receive: " + str(err)) # fix this
            raise err
Example #2
0
    def gameStatus(self, status, playerStatus, players, passengers):
        """
        Called to send an update message to this A.I.  We do NOT have to send a response.

        status -- The status message.
        playerStatus -- The player this status is about. THIS MAY NOT BE YOU.
        players -- The status of all players.
        passengers -- The status of all passengers.

        """

        # bugbug - Framework.cs updates the object's in this object's Players,
        # Passengers, and Companies lists. This works fine as long as this app
        # is single threaded. However, if you create worker thread(s) or
        # respond to multiple status messages simultaneously then you need to
        # split these out and synchronize access to the saved list objects.

        try:
            # bugbug - we return if not us because the below code is only for
            # when we need a new path or our limo hits a bus stop. If you want
            # to act on other players arriving at bus stops, you need to
            # remove this. But make sure you use self.me, not playerStatus for
            # the Player you are updating (particularly to determine what tile
            # to start your path from).
            if playerStatus != self.me:
                return

            ptDest = None
            pickup = []
            if    status == "UPDATE":
                return
            elif ((status == "PASSENGER_NO_ACTION" or
                  status == "NO_PATH") and playerStatus == self.me):
                if playerStatus.limo.passenger is None:
                    pickup = self.allPickups(self.me, passengers, players)
                    ptDest = pickup[0].lobby.busStop
                else:
                    ptDest = playerStatus.limo.passenger.destination.busStop
            elif (status == "PASSENGER_DELIVERED" or
                  status == "PASSENGER_ABANDONED"):
                pickup = self.allPickups(self.me, passengers, players)
                ptDest = pickup[0].lobby.busStop
            elif  status == "PASSENGER_REFUSED":
                pickup = self.allPickups(self.me, passengers, players)
                ptDest = pickup[0].lobby
            elif (status == "PASSENGER_DELIVERED_AND_PICKED_UP" or
                  status == "PASSENGER_PICKED_UP"):
                pickup = self.allPickups(self.me, passengers, players)
                ptDest = self.me.limo.passenger.destination.busStop
            else:
                raise TypeError("unknown status %r", status)

            # get the path from where we are to the dest.
            path = self.calculatePathPlus1(self.me, ptDest)
            
            sendOrders(self, "move", path, pickup)
        except Exception as e:
            traceback.print_exc()
            printrap ("somefin' bad, foo'!")
            raise e
Example #3
0
def calc_path(self, status, playerStatus, players, passengers, data, **kwargs):
        try:
            # bugbug - we return if not us because the below code is only for
            # when we need a new path or our limo hits a bus stop. If you want
            # to act on other players arriving at bus stops, you need to
            # remove this. But make sure you use self.me, not playerStatus for
            # the Player you are updating (particularly to determine what tile
            # to start your path from).
            if playerStatus != self.me:
                return

            ptDest = None
            pickup = []
            if    status == "UPDATE":
                return
            elif (status == "PASSENGER_NO_ACTION" or
                  status == "NO_PATH"):
                if playerStatus.limo.passenger is None:
                    pickup = self.allPickups(playerStatus, passengers)
                    ptDest = pickup[0].lobby.busStop
                else:
                    ptDest = playerStatus.limo.passenger.destination.busStop
            elif (status == "PASSENGER_DELIVERED" or
                  status == "PASSENGER_ABANDONED"):
                pickup = self.allPickups(playerStatus, passengers)
                ptDest = pickup[0].lobby.busStop
            elif  status == "PASSENGER_REFUSED":
                ptDest = random.choice(filter(lambda c: c != playerStatus.limo.passenger.destination,
                    self.companies)).busStop
            elif (status == "PASSENGER_DELIVERED_AND_PICKED_UP" or
                  status == "PASSENGER_PICKED_UP"):
                pickup = self.allPickups(playerStatus, passengers)
                ptDest = playerStatus.limo.passenger.destination.busStop
            else:
                raise TypeError("unknown status %r", status)

            # get the path from where we are to the dest.
            path = self.calculatePathPlus1(playerStatus, ptDest)
            return ("move", path, pickup)
        except Exception as e:
            printrap ("somefin' bad, foo'!")
            raise e
 def sendMessage(self, message):
     # compute the length of the message (4 byte, little-endian)
     length = len(message)
     hexlen = "{:08x}".format(length)
     assert len(hexlen) == 8 # length should not be more than 4 bytes
     chrstr = [chr(int(hexlen[i:i+2], 16)) for i in range(0, 8, 2)]
     chrstr.reverse()
     retlen = ''.join(chrstr)
     try:
         #send the length
         self.socket.send(retlen) # fix this
         
         # send the message
         ret = self.socket.send(message)
         while ret < length:
             ret += self.socket.send(message[ret:])
         assert ret == length
     except sock.timeout: # fix this
         printrap("Socket operation (send) timed out")
         self.sendMessage(message)
Example #5
0
 def incomingMessage(self, message):
     try:
         startTime = time.clock()            
         # get the XML - we assume we always get a valid message from the server.
         xml = ET.XML(message)
         name = xml.tag
         if name == 'start-position':
             players = api.player.playersFromXML(xml.find("players"))
             guid = xml.find("players").get("your-guid")
             start = self._brain.setup( api.board.GameMap(xml.find("map")), 
                                        [p for p in players if p.guid == guid][0], 
                                        players, _getPoints(xml.find("points")), 
                                        xml.get("game-start").lower() == "true" )
             print("Starting robot at: %s" % start)
             doc = ET.Element('start-position', start.getAttributes())
             self.client.sendMessage(ET.tostring(doc))
         elif name == 'turn':
             turnOn = int(xml.get('turn'))
             print("turn %i request starting" % turnOn)
             allPlayers = api.player.playersFromXML(xml.find('players'))
             guid = xml.find('players').get('your-guid')
             turn = self._brain.turn( api.board.GameMap(xml.find("map")), 
                                      [p for p in allPlayers if p.guid == guid][0], 
                                      allPlayers, 
                                      api.player.cardsFromXML(xml.find('cards')) )
             print("Turn: %i - %s" % (turnOn, turn))
             docTurn = turn.getXML()
             docTurn.set("turn", str(turnOn))
             print("turn %i replying" % turnOn)
             self.client.sendMessage(ET.tostring(docTurn))
         else:
             printrap("ERROR: bad message (XML) from server - root node %r" % name)
         turnTime = time.clock() - startTime
         prefix = '' if turnTime < .8 else "WARNING - "
         prefix = "!DANGER! - " if turnTime >= 1 else prefix
         print(prefix + "turn took %r seconds" % turnTime)
     except Exception as e:
         traceback.print_exc()
         printrap("Error on incoming message.  Exception: %r" % e)
    def incomingMessage(self, message):
        try:
            startTime = time.clock()
            # get the XML - we assume we always get a valid message from the server.
            xml = ET.XML(message)

            name = xml.tag
            if name == "setup":
                print("Received setup message")
                # TODO: logging
                players = api.units.playersFromXml(xml.find("players"))
                companies = api.map.companiesFromXml(xml.find("companies"))
                passengers = api.units.passengersFromXml(xml.find("passengers"), companies)
                map = api.map.Map(xml.find("map"), companies)
                self.guid = xml.attrib["my-guid"]
                me2 = [p for p in players if p.guid == self.guid][0]

                self._brain.setup(map, me2, players, companies, passengers, self.client)

                ###self.client.sendMessage(ET.tostring(doc))
            elif name == "status":
                # may be here because re-started and got this message before
                # the re-send of setup
                if self.guid is None or len(self.guid) == 0:
                    trap()
                    return

                status = xml.attrib["status"]
                attr = xml.attrib["player-guid"]
                guid = attr if attr is not None else self.guid

                brain = self._brain

                if self.lock.acquire(False):
                    try:
                        api.units.updatePlayersFromXml(brain.players, brain.passengers, xml.find("players"))
                        api.units.updatePassengersFromXml(brain.passengers, brain.companies, xml.find("passengers"))
                        # update my path & pick-up
                        playerStatus = [p for p in brain.players if p.guid == guid][0]
                        elem = xml.find("path")
                        # bugprint('framework.py: path element ->', ET.tostring(elem))
                        if elem is not None and elem.text is not None:
                            path = [item.strip() for item in elem.text.split(";") if len(item.strip()) > 0]
                            del playerStatus.limo.path[:]
                            for stepOn in path:
                                pos = stepOn.index(",")
                                playerStatus.limo.path.append((int(stepOn[:pos]), int(stepOn[pos + 1 :])))

                        elem = xml.find("pick-up")
                        # bugprint('framework.py: pick-up element ->', ET.tostring(elem))
                        if elem is not None and elem.text is not None:
                            names = [item.strip() for item in elem.text.split(";") if len(item) > 0]
                            playerStatus.pickup = [p for p in brain.passengers if p.name in names]

                        # pass in to generate new orders
                        brain.gameStatus(status, playerStatus, brain.players, brain.passengers)
                    # except Exception as e:
                    #    raise e
                    finally:
                        self.lock.release()
                else:
                    # failed to acquire the lock - we're throwing this message away.
                    trap()
                    return
            elif name == "exit":
                print("Received exit message")
                # TODO: logging
                sys.exit(0)
            else:
                printrap("ERROR: bad message (XML) from server - root node %r" % name)

            turnTime = time.clock() - startTime
            prefix = "" if turnTime < 0.8 else "WARNING - "
            prefix = "!DANGER! - " if turnTime >= 1.2 else prefix
            print(prefix + "turn took %r seconds" % turnTime)
            # TODO: logging
        except Exception as e:
            traceback.print_exc()
            printrap("Error on incoming message.  Exception: %r" % e)
        avatar = self._brain.avatar
        if avatar is not None:
            av_el = ET.Element("avatar")
            av_el.text = base64.b64encode(avatar)
            root.append(av_el)
        self.client.sendMessage(ET.tostring(root))


def sendOrders(brain, order, path, pickup):
    """Used to communicate with the server. Do not change this method!"""
    xml = ET.Element(order)
    if len(path) > 0:
        brain.me.limo.path = path  # update our saved Player to match new settings
        sb = [str(point[0]) + "," + str(point[1]) + ";" for point in path]
        elem = ET.Element("path")
        elem.text = "".join(sb)
        xml.append(elem)
    if len(pickup) > 0:
        brain.me.pickup = pickup  # update our saved Player to match new settings
        sb = [psngr.name + ";" for psngr in pickup]
        elem = ET.Element("pick-up")
        elem.text = "".join(sb)
        xml.append(elem)
    brain.client.sendMessage(ET.tostring(xml))


if __name__ == "__main__":
    printrap(sys.argv[0], breakOn=not sys.argv[0].endswith("framework.py"))
    framework = Framework(sys.argv[1:])
    framework._run()
    def incomingMessage(self, message):
        try:
            startTime = time.clock()
            # get the XML - we assume we always get a valid message from the server.
            #print ET.tostring(xml,encoding='utf8', method='xml')

            xml = ET.XML(message)
            name = xml.tag
            printrap("Received message of type: " + name)
            self.guid = xml.get('my-guid')
            hotels = [lib.HotelChain(hotel) for hotel in xml.find('hotels')]
            map = lib.GameMap(element=xml.find('map'), hotelChains=hotels) # need to handle the actual column/rows
            players = [lib.Player(player) for player in xml.find('players')]
            #fix stock pointers to right place...

            #pdb.set_trace()
            me = None
            msgid = xml.get('msg-id')
            reply = None
            for player in players:
                if player.guid == self.guid:
                    me = player
                    print "found matching guid..."
                elif player.name == self.brain.name:
                    me = player
                    print "no matching guid, but found matching name... "

            if name == 'query-card':
                move = self.brain.QuerySpecialPowersBeforeTurn(map, me, hotels, players)
                reply = ET.Element('reply', {'cmd': name, 'msg-id': msgid, 'card': move})

            elif name == 'query-tile-purchase':
                move = self.brain.QueryTileAndPurchase(map, me, hotels, players)
                reply = ET.Element('reply', {'cmd': name, 'msg-id': msgid})
                if move is not None:
                    if move.Tile is not None:
                        reply.set("tile-x", str(move.Tile.x))
                        reply.set("tile-y", str(move.Tile.y))
                    if move.CreatedHotel is not None:
                        reply.set("created-hotel",move.CreatedHotel.name)
                    if move.MergeSurvivor is not None:
                        reply.set("merge-survivor", move.MergeSurvivor.name)
                    if move.Card is not None:
                        reply.set("card", move.Card)

                    trade_string = ''.join(["{}:{};".format(stock.Trade, stock.Get) for stock in move.Trade])
                    if len(trade_string) > 0:
                        reply.set("trade", trade_string)

                    buy_string = ''.join(["{}:{};".format(stock.chain.name, stock.num_shares) for stock in move.Buy])
                    if len(buy_string) > 0:
                        reply.set("buy", buy_string)

            elif name == 'query-tile':
                move = self.brain.QueryTileOnly(map, me, hotels, players)
                reply = ET.Element('reply', {'cmd': name, 'msg-id': msgid})
                if move is not None:
                    if move.Tile is not None:
                        reply.set("tile-x", str(move.Tile.x))
                        reply.set("tile-y", str(move.Tile.y))
                    if move.CreatedHotel is not None:
                        reply.set("created-hotel",move.CreatedHotel.name)
                    if move.MergeSurvivor is not None:
                        reply.set("merge-survivor", move.MergeSurvivor.name)

            elif name == 'query-merge':
                defunct_name = xml.get('defunct')
                survivor_name = xml.get('survivor')
                defunct = next((hotel for hotel in hotels if hotel.name == defunct_name),None)
                survivor = next((hotel for hotel in hotels if hotel.name == survivor_name),None)
                move = self.brain.QueryMergeStock(map, me, hotels, players, survivor, defunct)
                reply = ET.Element('reply', {'cmd': name, 'msg-id': msgid})

                if move is not None:
                    reply.set( "keep",  str(move.Keep))
                    reply.set( "sell",  str(move.Sell))
                    reply.set( "trade", str(move.Trade))

            elif name == 'setup':
                print "\n\n", "----------------------------------", "\n\n"
                self.brain.Setup(map, me, hotels, players)
                reply = ET.Element('ready')

            elif name == 'exit':
                print("Received exit message")
                sys.exit(0)
            else:
                printrap("ERROR: bad message (XML) from server - root node %r" % name)
            self.send_xml(reply)
            turnTime = time.clock() - startTime
            prefix = '' if turnTime < 0.8 else "WARNING - "
            print(prefix + "turn took %r seconds" % turnTime)#Enable this to see turn speed
        except Exception as e:
            traceback.print_exc()
            printrap("Error on incoming message.  Exception: %r" % e)
Example #9
0
    def incomingMessage(self, message):
        try:
            startTime = time.clock()
            # get the XML - we assume we always get a valid message from the server.
            xml = ET.XML(message)

            name = xml.tag
            if name == 'setup':
                players = None
                companies = None
                passengers = None
                stores = None
                powerups = None
                map = None
                print ("Received setup message")
                players = api.units.playersFromXml(xml.find("players"))
                companies = api.map.companiesFromXml(xml.find("companies"))
                passengers = api.units.passengersFromXml(xml.find("passengers"), companies)
                stores = api.map.coffeeFromXml(xml.find("stores"))
                powerups = api.units.powerUpFromXml(xml.find("powerups"), companies, passengers)
                map = api.map.Map(xml.find("map"), companies)
                self.guid = xml.attrib["my-guid"]
                me2 = [p for p in players if p.guid == self.guid][0]

                self.brain.setup(map, me2, players, companies, passengers, self.client, stores, powerups, framework)

                ###self.client.sendMessage(ET.tostring(doc))
            elif name == 'status':
                # may be here because re-started and got this message before
                # the re-send of setup
                if self.guid is None or len(self.guid) == 0:
                    trap()
                    return

                status = xml.attrib["status"]
                attr = xml.attrib["player-guid"]
                guid = attr if attr is not None else self.guid

                brain = self.brain

                if self.lock.acquire(False):
                    try:
                        api.units.updatePlayersFromXml(brain.companies,
                                                       brain.players,
                                                       brain.passengers,
                                                       xml.find("players"))
                        api.units.updatePassengersFromXml(brain.passengers,
                                                          brain.players,
                                                          brain.companies,
                                                          xml.find("passengers"))
                        # update my path & pick-up
                        playerStatus = [p for p in brain.players
                                        if p.guid == guid][0]
                        elem = xml.find("path")
                        #bugprint('framework.py: path element ->', ET.tostring(elem))
                        if elem is not None and elem.text is not None:
                            path = [item.strip() for item in elem.text.split(';')
                                    if len(item.strip()) > 0]
                            del playerStatus.limo.path[:]
                            for stepOn in path:
                                pos = stepOn.index(',')
                                playerStatus.limo.path.append((int(stepOn[:pos]),
                                                               int(stepOn[pos + 1:])))

                        elem = xml.find("pick-up")
                        #bugprint('framework.py: pick-up element ->', ET.tostring(elem))
                        if elem is not None and elem.text is not None:
                            names = [item.strip() for item in elem.text.split(';')
                                     if len(item) > 0]
                            playerStatus.pickup = [p for p in brain.passengers if p.name in names]

                        # pass in to generate new orders
                        brain.gameStatus(status, playerStatus)
                    #except Exception as e:
                    #    raise e
                    finally:
                        self.lock.release()
                else:
                # failed to acquire the lock - we're throwing this message away.
                    trap()
                    return
            elif name == "powerup-status":
                brain = self.brain
                if self.guid is None:
                    return
                if self.lock.acquire(False):
                    try:
                        puStatus = xml.attrib["status"]
                        puGuid = xml.attrib["played-by"] if xml.attrib["played-by"] is not None else self.guid

                        plyrPowerUp = next(g for g in brain.players if g.guid == puGuid)
                        cardPlayed = api.units.powerUpGenerateFlyweight(xml.find("card"), brain.companies,
                                                                        brain.passengers, brain.players)

                        # do we update the card deck?
                        if (cardPlayed == cardLastPlayed or (
                                datetime.datetime.now() > cardLastSendTime + datetime.timedelta(seconds=1))):
                            updateCards(brain, xml.find("cards-deck").findall("card"), brain.powerUpDeck,
                                        brain.powerUpHand)
                            updateCards(brain, xml.find("cards-hand").findall("card"), brain.powerUpHand, None)

                        brain.powerUpStatus(puStatus, plyrPowerUp, cardPlayed)
                    finally:
                        self.lock.release()
                else:
                # failed to acquire the lock - we're throwing this message away.
                    trap()
                    return

            elif name == 'exit':
                print("Received exit message")
                sys.exit(0)
            else:
                printrap("ERROR: bad message (XML) from server - root node %r" % name)

            turnTime = time.clock() - startTime
            prefix = '' if turnTime < 0.8 else "WARNING - "
            prefix = "!DANGER! - " if turnTime >= 1.2 else prefix
            # print(prefix + "turn took %r seconds" % turnTime) Enable this to see turn speed
        except Exception as e:
            traceback.print_exc()
            printrap("Error on incoming message.  Exception: %r" % e)
Example #10
0
    def incomingMessage(self, message):
        try:
            startTime = time.clock()
            # get the XML - we assume we always get a valid message from the server.
            xml = ET.XML(message)

            name = xml.tag
            if name == 'setup':
                print("Received setup message")
                #TODO: logging
                players = api.units.playersFromXml(xml.find("players"))
                companies = api.map.companiesFromXml(xml.find("companies"))
                passengers = api.units.passengersFromXml(
                    xml.find("passengers"), companies)
                map = api.map.Map(xml.find("map"), companies)
                self.guid = xml.attrib["my-guid"]
                me2 = [p for p in players if p.guid == self.guid][0]

                self._brain.setup(map, me2, players, companies, passengers,
                                  self.client)

                ###self.client.sendMessage(ET.tostring(doc))
            elif name == 'status':
                # may be here because re-started and got this message before
                # the re-send of setup
                if self.guid is None or len(self.guid) == 0:
                    trap()
                    return

                status = xml.attrib["status"]
                attr = xml.attrib["player-guid"]
                guid = attr if attr is not None else self.guid

                brain = self._brain

                if self.lock.acquire(False):
                    try:
                        api.units.updatePlayersFromXml(brain.players,
                                                       brain.passengers,
                                                       xml.find("players"))
                        api.units.updatePassengersFromXml(
                            brain.passengers, brain.companies,
                            xml.find("passengers"))
                        # update my path & pick-up
                        playerStatus = [
                            p for p in brain.players if p.guid == guid
                        ][0]
                        elem = xml.find("path")
                        #bugprint('framework.py: path element ->', ET.tostring(elem))
                        if elem is not None and elem.text is not None:
                            path = [
                                item.strip() for item in elem.text.split(';')
                                if len(item.strip()) > 0
                            ]
                            del playerStatus.limo.path[:]
                            for stepOn in path:
                                pos = stepOn.index(',')
                                playerStatus.limo.path.append(
                                    (int(stepOn[:pos]), int(stepOn[pos + 1:])))

                        elem = xml.find("pick-up")
                        #bugprint('framework.py: pick-up element ->', ET.tostring(elem))
                        if elem is not None and elem.text is not None:
                            names = [
                                item.strip() for item in elem.text.split(';')
                                if len(item) > 0
                            ]
                            playerStatus.pickup = [
                                p for p in brain.passengers if p.name in names
                            ]

                        # pass in to generate new orders
                        brain.gameStatus(status, playerStatus, brain.players,
                                         brain.passengers)
                    #except Exception as e:
                    #    raise e
                    finally:
                        self.lock.release()
                else:
                    # failed to acquire the lock - we're throwing this message away.
                    trap()
                    return
            elif name == 'exit':
                print("Received exit message")
                #TODO: logging
                sys.exit(0)
            else:
                printrap(
                    "ERROR: bad message (XML) from server - root node %r" %
                    name)

            turnTime = time.clock() - startTime
            prefix = '' if turnTime < 0.8 else "WARNING - "
            prefix = "!DANGER! - " if turnTime >= 1.2 else prefix
            print(prefix + "turn took %r seconds" % turnTime)
            #TODO: logging
        except Exception as e:
            traceback.print_exc()
            printrap("Error on incoming message.  Exception: %r" % e)
Example #11
0
        avatar = self._brain.avatar
        if avatar is not None:
            av_el = ET.Element('avatar')
            av_el.text = base64.b64encode(avatar)
            root.append(av_el)
        self.client.sendMessage(ET.tostring(root))


def sendOrders(brain, order, path, pickup):
    """Used to communicate with the server. Do not change this method!"""
    xml = ET.Element(order)
    if len(path) > 0:
        brain.me.limo.path = path  # update our saved Player to match new settings
        sb = [str(point[0]) + ',' + str(point[1]) + ';' for point in path]
        elem = ET.Element('path')
        elem.text = ''.join(sb)
        xml.append(elem)
    if len(pickup) > 0:
        brain.me.pickup = pickup  # update our saved Player to match new settings
        sb = [psngr.name + ';' for psngr in pickup]
        elem = ET.Element('pick-up')
        elem.text = ''.join(sb)
        xml.append(elem)
    brain.client.sendMessage(ET.tostring(xml))


if __name__ == '__main__':
    printrap(sys.argv[0], breakOn=not sys.argv[0].endswith("framework.py"))
    framework = Framework(sys.argv[1:])
    framework._run()