Beispiel #1
0
 def __init__(self):
     self.observers = []
     self.players = {}
     self.rp = ResourcePool(100)
     self.rp.position = Vector2D(0, 0)
     self.width = 80.0  #48.0
     self.height = 48.0  #80.0
     self.buildings = {}
     self.team = None
     self.endTime = None
     self.gameOver = False
     self.attackOk = True
     self.lightOn = True
    def __init__(self,player_id,team,serverIP,serverPort):
                '''State: Players,Buildings, Time, Resourse Pool'''
                LoopingThread.__init__(self)               
		
		self.players 	= {}
		self.buildings 	= {}
		self.TimeLeft = 15*60 
		self.width = 80.0
		self.height = 48.0
		self.view =None
		self.GameOver =False
		self.playerID =player_id
		
		self.player = None
		self.action = 0
		self.attemptedAction = 0
		self.lastAction = 0
		self.ActionTimeout = 1
		
		self.team =team
		self.otherTeam = 2 if self.team==1 else  1 
		self.scores =[0,0]
		self.IsServer = False
		self.ResourcePool = ResourcePool()
		self.client = UDPClient(self)
		self.serverIP =serverIP
		self.serverPort = serverPort
                self.Tick = 0
                self.Position = (0,0)
                self.lastUpdate = 0
                self.controller = None
Beispiel #3
0
 def __init__(self):
     self.observers = []
     self.players = {}
     self.rp = ResourcePool(100)
     self.rp.position = Vector2D(0, 0)
     self.width = 48.0
     self.height = 80.0
     self.buildings = {}
     self.team = None
Beispiel #4
0
 def __init__(self):
     self.observers = []
     self.players = {}
     self.rp = ResourcePool(100)
     self.rp.position = Vector2D(0, 0)
     self.width = 80.0#48.0
     self.height = 48.0#80.0
     self.buildings = {}
     self.team = None
     self.endTime = None
     self.gameOver = False
     self.attackOk = True
     self.lightOn = True
 def __init__(self):
         '''State: Players,Buildings, Time, Resourse Pool'''
         self.players    = {}
         self.buildings  = {}
         self.TimeLeft = 0 
         self.TrueTimeLeft = 0  
         self.Tick = 0         
         self.scores =[0,0]     
         self.GameOver =False
         self.GameStarted =False
         self.width = 80.0
         self.height = 48.0
         self.view =None
         self.team =None
         self.actions =None
         self.IsServer = True
         self.ResourcePool = ResourcePool()
Beispiel #6
0
class Environment(pb.Cacheable, pb.RemoteCache):
    def __init__(self):
        self.observers = []
        self.players = {}
        self.rp = ResourcePool(100)
        self.rp.position = Vector2D(0, 0)
        self.width = 80.0#48.0
        self.height = 48.0#80.0
        self.buildings = {}
        self.team = None
        self.endTime = None
        self.gameOver = False
        self.attackOk = True
        self.lightOn = True

    def resetGame(self):
        #pass
        self.buildings = {}
        for p in self.players:
            self.players[p].reset()

    def _turnOnLight(self):
        self.lightOn = True

    def observe_blinkLight(self, player):
        if player.self:
            print "blinky"
            self.lightOn = False
            reactor.callLater(.2, self._turnOnLight)

    def startGame(self):
        # I'm not sure that this is best way to do this,
        # but by using absolute times, coordination is
        # simpler
        self.observe_startGame(latencyEstimate=0)
        reactor.callLater(GAME_DURATION, self.endGame)
        for o in self.observers:
            o.callRemote('startGame')

    def observe_startGame(self, latencyEstimate=PRESUMED_LATENCY):
        print("start")
        self.observe_updateTimeRemaining(GAME_DURATION, 0)
        self.resetGame()
        self.gameOver = False

    def setPreGame(self):
        for o in self.observers: o.callRemote('blinkLight')
        self.observe_setPreGame()
        for o in self.observers: o.callRemote('setPreGame')

    def observe_setPreGame(self):
        self.endTime = None
        self.gameOver = False


    def updateTimeRemaining(self, timeRemaining):
        self.observe_updateTimeRemaining(timeRemaining, latencyEstimate=0)
        for o in self.observers: o.callRemote('updateTimeRemaining')

    def observe_updateTimeRemaining(self, timeRemaining, latencyEstimate=PRESUMED_LATENCY):
        self.endTime = int(time.time()) + timeRemaining - latencyEstimate


    def endGame(self):
        self.observe_endGame()
        for o in self.observers: o.callRemote('endGame')

    def observe_endGame(self):
        self.gameOver = True
        self.endTime = int(time.time())

    def createPlayer(self, team):
        player = Player()
        player.team = team

        # I have no idea if this is being set somewhere else
        #if self.team == None:
        #    self.team = team

        playerId = id(player)
        self.players[playerId] = player
        for o in self.observers: o.callRemote('createPlayer', playerId, player)
        #player.sounds = self.sounds
        return player

    def observe_createPlayer(self, playerId, player):
        self.players[playerId] = player

    def removePlayer(self, player):
        pid = id(player)
        del self.players[pid]
        for o in self.observers: o.callRemote('removePlayer', pid)
    def observe_removePlayer(self, pid):
        del self.players[pid]

    def createBuilding(self, team, position):
        if (self.rp.position - position) < 6:
            return None
        for b in self.buildings.itervalues():
            if (team == b.team) and (b.position - position) < 6:
                return None
        building = Building()
        building.team = team
        building.position = position
        bid = id(building)
        self.buildings[bid] = building
        building.onDestroyed.addCallback(self.destroyBuilding)
        for o in self.observers: o.callRemote('createBuilding', bid, building)
        return building

    def observe_createBuilding(self, bid, building):
        self.buildings[bid] = building

    def destroyBuilding(self, building):
        bid = id(building)
        del self.buildings[bid]
        for o in self.observers: o.callRemote('destroyBuilding', bid)
    def observe_destroyBuilding(self, bid):
        del self.buildings[bid]

    def attack(self, player):
        #if self.attackOk:
        self.attackOk = False
        reactor.callLater(1.5, self.makeAttackOk)
        distance = 3
        player.attack()
        for p in self.players.itervalues():
            if (p.team != player.team) and (p.position - player.position) < distance:
                p.hit()
        for b in self.buildings.values():
            if (b.position - player.position) < distance:
                b.hit()

    def makeAttackOk(self):
        self.attackOk = True

    def startAttacking(self, player):
#        if player.action == None:
        player.setAction("Attacking", LoopingCall(self.attack, player))
        player.action.start(1.5, now=self.attackOk)
        self.attackOk = False

        #self.attack(player)


    def startBuilding(self, player):
        hadNoBuilding = not player.building
        if hadNoBuilding:
            newBuildingPosition = player.position

            newBuildingPosition.x = newBuildingPosition.x - 2 #TODO this will likely have to change to x for the phone

            building = self.createBuilding(player.team, newBuildingPosition)
            if building:
                player.updatePosition(player.position, building)
            else:
                return
        if player.building == self.rp:
            action = "Mining"
            hadNoBuilding = False
        else:
            action = "Building"
        player.setAction(action, LoopingCall(player.building.build, player))
        player.action.start(2, now=hadNoBuilding)

    def finishAction(self, player):
        if player.action:
            player.action.stop()
            player.setAction(None, None)

    def startUpgrading(self, player):
        player.startAcceptUpgrade()
        for b in self.buildings.itervalues():
            if b.isPolyFactory() and (b.team == player.team) and (b.position - player.position) < 3 and not b.upgrading:
                b.upgrading = player
                player.upgradingAt = b

    def finishUpgrading(self, player):
        if player.upgradingAt:
            player.upgradingAt.upgrading = None
            player.upgradingAt = None

    def updatePlayerPosition(self, player, position):
        building = None
        for b in self.buildings.itervalues():
            if (player.team == b.team) and (b.position - position) < 3:
                building = b
                break
        if not building:
            if (self.rp.position - position) < 3:
                building = self.rp
        player.updatePosition(position, building)

        for b in self.buildings.itervalues():
            if b.isTrap() and (b.team != player.team) and ((b.position - player.position) < 1):
                player.trapped()
                b.explode()
                break

    def isVisible(self, entity):
        # Spectators see all
        if not self.team:
            return True
        # See objects on your team
        if self.team == entity.team:
            return True
        # Object in range of my sentries
        for b in self.buildings.itervalues():
            if b.isSentry() and (b.team == self.team) and (entity.position - b.position) < 13.75:
                return True
        # object in range of a scanning player
        for p in self.players.itervalues():
            if (self.team == p.team):
                if (entity.position - p.position) < p.getScanRadius() * 12.35:
                    return True
        return False

    def paint(self, view):
        for b in self.buildings.itervalues():
            # TODO save the view to get images
            b.images = view.images.images
            if self.isVisible(b) or b.explosion:
                b.paint(view, view.screenCoord(b.position), b.team == self.team)
        self.rp.paint(view, view.screenCoord(self.rp.position))
        for p in self.players.itervalues():
            if p.self:
                view.setCenter(p.position)
            if p.self and p.building:
                p.building.drawToolTip(view, "Build", p.team)
            p.paint(view, view.screenCoord(p.position), self.team == p.team, self.isVisible(p))

        # Draw the score:
        #TODO color appropriately
        font = pygame.font.Font("data/Deutsch.ttf", 35)
        #font = pygame.font.Font(None, 45)
        text = font.render(str(self.calculateScore(self.team)), True, (0,255,255))
        text = pygame.transform.rotate(text, 270)
        textrect = text.get_rect(right =735, bottom = 410)
        view.screen.blit(text,textrect)

        text = font.render(str(self.calculateScore(self.getOpponentTeam())), True, (255, 0, 255))
        text = pygame.transform.rotate(text, 270)
        textrect = text.get_rect(right = 775, bottom = 410)
        view.screen.blit(text,textrect)


        # ======================================================================
        #Draw the time remaining
        minRemaining = 15
        secRemaining = 0
        if self.endTime:
            secRemaining = max(self.endTime - int(time.time()), 0)
            minRemaining = secRemaining / 60
            secRemaining = secRemaining % 60

        secStr = str(secRemaining)
        if secRemaining <= 9: secStr = "0" + secStr

        minStr = str(minRemaining)
        if minRemaining <= 9: minStr = "0" + minStr

        font = pygame.font.Font("data/Deutsch.ttf", 35)
        text = font.render(minStr + ":" + secStr, True, (255, 255, 255))
        text = pygame.transform.rotate(text, 270)
        textrect = text.get_rect(left = 15, bottom = 410)
        view.screen.blit(text,textrect)

        # ======================================================================
        # draw end game message, as appropriate
        if self.gameOver:
            endGameMessage = ""
            if self.team:
                scoreDifference = self.calculateScore(self.team) > self.calculateScore(self.getOpponentTeam())
                if scoreDifference > 0:
                    endGameMessage = "YOU WIN!"
                elif scoreDifference < 0:
                    endGameMessage = "YOU LOSE!"
                else:
                  endGameMessage = "DRAW!"

            else:
                scoreDifference = self.calculateScore(1) - self.calculateScore(2)
                if scoreDifference > 0:
                    endGameMessage = "RED WINS!"
                elif scoreDifference < 0:
                    endGameMessage = "BLUE WINS!"
                else:
                    endGameMessage = "DRAW!"


            font = pygame.font.Font("data/Deutsch.ttf", 70)
            #font = pygame.font.Font(None, 45)
            text = font.render(endGameMessage, True, (255,255,255))
            text = pygame.transform.rotate(text, 270)
            textrect = text.get_rect(centery =240, centerx = 350)
            view.screen.blit(text,textrect)

        # ======================================================================
        # draw draw white square for photo sensor

        sqrSz = 75

        if not self.team == None:
            sensRect = pygame.Rect(0, 0, sqrSz + 5, sqrSz + 10)
            sensRect.right = 800
            sensRect.centery = 240
            pygame.draw.rect(view.screen, (0,0,0), sensRect)

            if self.lightOn:
                sensRect = pygame.Rect(0,0,sqrSz,sqrSz)
                sensRect.right = 800
                sensRect.centery = 240
                pygame.draw.rect(view.screen, (255,255,255), sensRect)


    # pb.Cacheable stuff
    def getStateToCacheAndObserveFor(self, perspective, observer):
        self.observers.append(observer)
        state = pb.Cacheable.getStateToCopyFor(self, perspective).copy()
        del state['observers']
        return state

    def stoppedObserving(self, perspective, observer):
        self.observers.remove(observer)

    def switchTeams(self, player):
        self.team = self.getOpponentTeam()
        player.switchTeams()

    def getOpponentTeam(self):
        if self.team == 1:
            return 2
        else:
            return 1

    def calculateScore(self, team):
        #print "score =================================="
        if team == None:
            team = self.team
#        print "=== Our Team: " + str(team)
        score = 0;
        for playerId in self.players:
            #score = score + 100
            player = self.players[playerId]
            #print "player team: " + str(player.team)
            if player.team == team:
                score = score + player.sides
                score = score + player.resources

        for buildingId in self.buildings:
            #score = score + 10000
            building = self.buildings[buildingId]
            #print "bildg team: " + str(building.team)
            if building.team == team:
                score = score + building.sides
                score = score + building.resources

        return score * 1000;
Beispiel #7
0
class Environment(pb.Cacheable, pb.RemoteCache):
    def __init__(self):
        self.observers = []
        self.players = {}
        self.rp = ResourcePool(100)
        self.rp.position = Vector2D(0, 0)
        self.width = 80.0  #48.0
        self.height = 48.0  #80.0
        self.buildings = {}
        self.team = None
        self.endTime = None
        self.gameOver = False
        self.attackOk = True
        self.lightOn = True

    def resetGame(self):
        #pass
        self.buildings = {}
        for p in self.players:
            self.players[p].reset()

    def _turnOnLight(self):
        self.lightOn = True

    def observe_blinkLight(self, player=None):
        #if player.self:
        print "blinky"
        self.lightOn = False
        reactor.callLater(.4, self._turnOnLight)

    def startGame(self):
        # I'm not sure that this is best way to do this,
        # but by using absolute times, coordination is
        # simpler
        self.observe_startGame(latencyEstimate=0)
        reactor.callLater(GAME_DURATION, self.endGame)
        for o in self.observers:
            o.callRemote('startGame')

    def observe_startGame(self, latencyEstimate=PRESUMED_LATENCY):
        print("start")
        self.observe_updateTimeRemaining(GAME_DURATION, 0)
        self.resetGame()
        self.gameOver = False

    def setPreGame(self):
        for o in self.observers:
            o.callRemote('blinkLight')
        self.observe_setPreGame()
        for o in self.observers:
            o.callRemote('setPreGame')

    def observe_setPreGame(self):
        self.endTime = None
        self.gameOver = False

    def updateTimeRemaining(self, timeRemaining):
        self.observe_updateTimeRemaining(timeRemaining, latencyEstimate=0)
        for o in self.observers:
            o.callRemote('updateTimeRemaining')

    def observe_updateTimeRemaining(self,
                                    timeRemaining,
                                    latencyEstimate=PRESUMED_LATENCY):
        self.endTime = int(time.time()) + timeRemaining - latencyEstimate

    def endGame(self):
        self.observe_endGame()
        for o in self.observers:
            o.callRemote('endGame')

    def observe_endGame(self):
        self.gameOver = True
        self.endTime = int(time.time())

    def createPlayer(self, team):
        player = Player()
        player.team = team

        # I have no idea if this is being set somewhere else
        #if self.team == None:
        #    self.team = team

        playerId = id(player)
        self.players[playerId] = player
        for o in self.observers:
            o.callRemote('createPlayer', playerId, player)
        #player.sounds = self.sounds
        return player

    def observe_createPlayer(self, playerId, player):
        self.players[playerId] = player

    def removePlayer(self, player):
        pid = id(player)
        del self.players[pid]
        for o in self.observers:
            o.callRemote('removePlayer', pid)

    def observe_removePlayer(self, pid):
        del self.players[pid]

    def createBuilding(self, team, position):
        if (self.rp.position - position) < 6:
            return None
        for b in self.buildings.itervalues():
            if (team == b.team) and (b.position - position) < 6:
                return None
        building = Building()
        building.team = team
        building.position = position
        bid = id(building)
        self.buildings[bid] = building
        building.onDestroyed.addCallback(self.destroyBuilding)
        for o in self.observers:
            o.callRemote('createBuilding', bid, building)
        return building

    def observe_createBuilding(self, bid, building):
        self.buildings[bid] = building

    def destroyBuilding(self, building):
        bid = id(building)
        del self.buildings[bid]
        for o in self.observers:
            o.callRemote('destroyBuilding', bid)

    def observe_destroyBuilding(self, bid):
        del self.buildings[bid]

    def attack(self, player):
        #if self.attackOk:
        self.attackOk = False
        reactor.callLater(1.5, self.makeAttackOk)
        distance = 3
        player.attack()
        for p in self.players.itervalues():
            if (p.team !=
                    player.team) and (p.position - player.position) < distance:
                p.hit()
        for b in self.buildings.values():
            if (b.position - player.position) < distance:
                b.hit()

    def makeAttackOk(self):
        self.attackOk = True

    def startAttacking(self, player):
        #        if player.action == None:
        player.setAction("Attacking", LoopingCall(self.attack, player))
        player.action.start(1.5, now=self.attackOk)
        self.attackOk = False

        #self.attack(player)

    def startBuilding(self, player):
        hadNoBuilding = not player.building
        if hadNoBuilding:
            newBuildingPosition = player.position

            newBuildingPosition.x = newBuildingPosition.x - 2  #TODO this will likely have to change to x for the phone

            building = self.createBuilding(player.team, newBuildingPosition)
            if building:
                player.updatePosition(player.position, building)
            else:
                return
        if player.building == self.rp:
            action = "Mining"
            hadNoBuilding = False
        else:
            action = "Building"
        player.setAction(action, LoopingCall(player.building.build, player))
        player.action.start(2, now=hadNoBuilding)

    def finishAction(self, player):
        if player.action:
            player.action.stop()
            player.setAction(None, None)

    def startUpgrading(self, player):
        player.startAcceptUpgrade()
        for b in self.buildings.itervalues():
            if b.isPolyFactory() and (b.team == player.team) and (
                    b.position - player.position) < 3 and not b.upgrading:
                b.upgrading = player
                player.upgradingAt = b

    def finishUpgrading(self, player):
        if player.upgradingAt:
            player.upgradingAt.upgrading = None
            player.upgradingAt = None

    def updatePlayerPosition(self, player, position):
        building = None
        for b in self.buildings.itervalues():
            if (player.team == b.team) and (b.position - position) < 3:
                building = b
                break
        if not building:
            if (self.rp.position - position) < 3:
                building = self.rp
        player.updatePosition(position, building)

        for b in self.buildings.itervalues():
            if b.isTrap() and (b.team != player.team) and (
                (b.position - player.position) < 1):
                player.trapped()
                b.explode()
                break

    def isVisible(self, entity):
        # Spectators see all
        if not self.team:
            return True
        # See objects on your team
        if self.team == entity.team:
            return True
        # Object in range of my sentries
        for b in self.buildings.itervalues():
            if b.isSentry() and (b.team == self.team) and (entity.position -
                                                           b.position) < 13.75:
                return True
        # object in range of a scanning player
        for p in self.players.itervalues():
            if (self.team == p.team):
                if (entity.position - p.position) < p.getScanRadius() * 12.35:
                    return True
        return False

    def paint(self, view):
        for b in self.buildings.itervalues():
            # TODO save the view to get images
            b.images = view.images.images
            if self.isVisible(b) or b.explosion:
                b.paint(view, view.screenCoord(b.position),
                        b.team == self.team)
        self.rp.paint(view, view.screenCoord(self.rp.position))
        for p in self.players.itervalues():
            if p.self:
                view.setCenter(p.position)
            if p.self and p.building:
                p.building.drawToolTip(view, "Build", p.team)
            p.paint(view, view.screenCoord(p.position), self.team == p.team,
                    self.isVisible(p))

        # Draw the score:
        #TODO color appropriately
        font = pygame.font.Font("data/Deutsch.ttf", 35)
        #font = pygame.font.Font(None, 45)
        text = font.render(str(self.calculateScore(self.team)), True,
                           (0, 255, 255))
        text = pygame.transform.rotate(text, 270)
        textrect = text.get_rect(right=735, bottom=410)
        view.screen.blit(text, textrect)

        text = font.render(str(self.calculateScore(self.getOpponentTeam())),
                           True, (255, 0, 255))
        text = pygame.transform.rotate(text, 270)
        textrect = text.get_rect(right=775, bottom=410)
        view.screen.blit(text, textrect)

        # ======================================================================
        #Draw the time remaining
        minRemaining = 15
        secRemaining = 0
        if self.endTime:
            secRemaining = max(self.endTime - int(time.time()), 0)
            minRemaining = secRemaining / 60
            secRemaining = secRemaining % 60

        secStr = str(secRemaining)
        if secRemaining <= 9: secStr = "0" + secStr

        minStr = str(minRemaining)
        if minRemaining <= 9: minStr = "0" + minStr

        font = pygame.font.Font("data/Deutsch.ttf", 35)
        text = font.render(minStr + ":" + secStr, True, (255, 255, 255))
        text = pygame.transform.rotate(text, 270)
        textrect = text.get_rect(left=15, bottom=410)
        view.screen.blit(text, textrect)

        # ======================================================================
        # draw end game message, as appropriate
        if self.gameOver:
            endGameMessage = ""
            if self.team:
                scoreDifference = self.calculateScore(
                    self.team) > self.calculateScore(self.getOpponentTeam())
                if scoreDifference > 0:
                    endGameMessage = "YOU WIN!"
                elif scoreDifference < 0:
                    endGameMessage = "YOU LOSE!"
                else:
                    endGameMessage = "DRAW!"

            else:
                scoreDifference = self.calculateScore(1) - self.calculateScore(
                    2)
                if scoreDifference > 0:
                    endGameMessage = "RED WINS!"
                elif scoreDifference < 0:
                    endGameMessage = "BLUE WINS!"
                else:
                    endGameMessage = "DRAW!"

            font = pygame.font.Font("data/Deutsch.ttf", 70)
            #font = pygame.font.Font(None, 45)
            text = font.render(endGameMessage, True, (255, 255, 255))
            text = pygame.transform.rotate(text, 270)
            textrect = text.get_rect(centery=240, centerx=350)
            view.screen.blit(text, textrect)

        # ======================================================================
        # draw draw white square for photo sensor

        sqrSz = 75

        if not self.team == None:
            sensRect = pygame.Rect(0, 0, sqrSz + 5, sqrSz + 10)
            sensRect.right = 800
            sensRect.centery = 240
            pygame.draw.rect(view.screen, (0, 0, 0), sensRect)

            if self.lightOn:
                sensRect = pygame.Rect(0, 0, sqrSz, sqrSz)
                sensRect.right = 800
                sensRect.centery = 240
                pygame.draw.rect(view.screen, (255, 255, 255), sensRect)

    # pb.Cacheable stuff
    def getStateToCacheAndObserveFor(self, perspective, observer):
        self.observers.append(observer)
        state = pb.Cacheable.getStateToCopyFor(self, perspective).copy()
        del state['observers']
        return state

    def stoppedObserving(self, perspective, observer):
        self.observers.remove(observer)

    def switchTeams(self, player):
        self.team = self.getOpponentTeam()
        player.switchTeams()

    def getOpponentTeam(self):
        if self.team == 1:
            return 2
        else:
            return 1

    def calculateScore(self, team):
        #print "score =================================="
        if team == None:
            team = self.team


#        print "=== Our Team: " + str(team)
        score = 0
        for playerId in self.players:
            #score = score + 100
            player = self.players[playerId]
            #print "player team: " + str(player.team)
            if player.team == team:
                score = score + player.sides
                score = score + player.resources

        for buildingId in self.buildings:
            #score = score + 10000
            building = self.buildings[buildingId]
            #print "bildg team: " + str(building.team)
            if building.team == team:
                score = score + building.sides
                score = score + building.resources

        return score * 1000
class Environment(): #in an MVC system , this would be a controller
        ''' The environment class contains the state of the game. The server has the master version, the clients have slave versions (updated through the network) '''
        NEXT_PLAYER_ID=1
        NEXT_BUILDING_ID=1
        FPS=30
        ATTACK_DISTANCE =3
        BUILDING_DISTANCE =6
        GAME_DURATION = 10#15 seconds #15 * 60 # 15 minutes
    
        def __init__(self):
                '''State: Players,Buildings, Time, Resourse Pool'''
                self.players    = {}
                self.buildings  = {}
                self.TimeLeft = 0 
                self.TrueTimeLeft = 0  
                self.Tick = 0         
                self.scores =[0,0]     
                self.GameOver =False
                self.GameStarted =False
                self.width = 80.0
                self.height = 48.0
                self.view =None
                self.team =None
                self.actions =None
                self.IsServer = True
                self.ResourcePool = ResourcePool()
                
        #Helper Functions
        def createPlayer(self, player_id,team):
                '''add a player to the given team'''
                player = Player()
                player.team = team

                playerId = id(player)
                player.player_id = player_id
                #player.player_id = Environment.NEXT_PLAYER_ID
                #Environment.NEXT_PLAYER_ID = Environment.NEXT_PLAYER_ID + 1
        
                self.players[playerId] = player        
                return player

        def createBuilding(self, team,pos):
                '''add a building to the given team'''
                building = Building()
                building.team = team
                building.position =pos
                bid = id(building)
                building.building_id = Environment.NEXT_BUILDING_ID
                Environment.NEXT_BUILDING_ID = Environment.NEXT_BUILDING_ID + 1
                self.buildings[bid] = building
                
        
                return building

        
        def StartGame(self):
                self.Tick=0
                self.GameStarted=True
                self.GameOver = False
                self.TrueTimeLeft=Environment.GAME_DURATION
                self.TimeLeft = int(self.TrueTimeLeft)
                for playerId in self.players:
                     self.players[playerId].sides=3
                     self.players[playerId].resources=0
                     
                self.buildings.clear()

                
        def updateTime(self):
                self.Tick += 1.0/Environment.FPS
                if(self.GameStarted):
                        self.TrueTimeLeft-=1.0/Environment.FPS
                        self.TimeLeft = int(self.TrueTimeLeft)  
                        if(     self.TrueTimeLeft<=0):
                            self.GameOver =True
                            self.TrueTimeLeft =0


        def updatePositions(self):
                for playerId in self.players:
                     self.players[playerId].updatePosition( 1.0/Environment.FPS)

        def Update(self):
                
                startTime = time.time()
                self.updateTime()
                self.scores =self.calculateScores()
                self.updatePositions()
                if(self.actions<>None):
                        self.processNewState()
                self.writeStateToServer()
                self.view.paint(self.Tick)
                for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                                pygame.quit()
                                #sys.exit()
                        if event.type == pygame.KEYDOWN:
                                if event.key==pygame.K_s:
                                        self.StartGame()
                #print time.time()-startTime
                                        
                        
        def processNewState(self):
            
                for action in self.actions:
                    found= False
                    for playerId in self.players:
                        if(self.players[playerId].player_id)==int(action[0]):
                            self.players[playerId].action=int(action[2])
                            pos = action[3].split(',')
                            self.players[playerId].targetPosition = Vector2D(float(pos[0]),float(pos[1]))
                            found =True
                            break

                    if(not found):
                        self.createPlayer(int(action[0]),int(action[1]))
                     

                for playerId in self.players:
                        
                        player = self.players[playerId]
                        

                        if(player.action == Player.ATTACK): #ATTACK
                                self.handleAttack(player)

                        elif(player.action == Player.BUILD): #building
                                self.handleBuild(player)

                        elif(player.action == Player.UPGRADE): #building
                                self.handleUpgrade(player)

                        elif(player.action == Player.SCAN): #building
                                self.handleScan(player)

                        elif(player.action == Player.IDLE):
                                self.handleIdle(player)
                                              
                        for b in self.buildings.itervalues():
                             if   (b.getPosition() - player.getPosition()).length < b.size and b.isTrap() and b.team<>player.team:         
                                        b.explode(player,self.Tick)   
        

        def handleAttack(self,player):
                if(player.sides>=3):
                        player.performAttack(self.Tick)  
                        for p in self.players.itervalues():
                                if (p.team != player.team) and (p.getPosition() - player.getPosition()).length < Environment.ATTACK_DISTANCE:
                                        p.hit(self.Tick)
                        for b in self.buildings.itervalues():
                                if (b.team != player.team) and (b.getPosition() - player.getPosition()).length < Environment.ATTACK_DISTANCE:
                                        b.hit(self.Tick)

        def handleBuild(self,player):
                ACTION = "BUILD"
                if((self.ResourcePool.getPosition()-player.getPosition()).length< self.ResourcePool.size):
                        ACTION ="MINE"
                else:
                        for b in self.buildings.itervalues():
                                
                                if(b.team == player.team and b.isPolyFactory() and b.resources == 5 and (b.getPosition()- player.getPosition()).length <b.size):
                                        ACTION ="MINE"
                                        break      
                if( ACTION =="MINE"):
                        player.performBuild(self.Tick)  
                        player.mine(self.Tick)
                                         
                else:
                        if(player.resources>0):
                                BUILDING =None
                                for b in self.buildings.itervalues():
                                        if   (b.getPosition() - player.getPosition()).length < b.size:
                                                BUILDING =b
                                                break
                                if BUILDING ==None :
                                        self.createBuilding(  player.team, player.getPosition())                       
                                        player.resources-=1 

                                elif BUILDING.team ==player.team:
                                        player.performBuild(self.Tick) 
                                        BUILDING.build(player,self.Tick) 
        
        def handleUpgrade(self,player):
                allowedUpgradeLoc = False
                if((self.ResourcePool.getPosition()-player.getPosition()).length< self.ResourcePool.size):
                        allowedUpgradeLoc=True
                else:
                        for b in self.buildings.itervalues():
                                if(b.team == player.team and b.isPolyFactory() and b.resources == 5 and (b.getPosition()- player.getPosition()).length <b.size): 
                                        allowedUpgradeLoc=True
                                        break
                if(allowedUpgradeLoc):
                       player.upgrade(self.Tick) 

        def handleScan(self,player):
             player.scan(self.Tick)    

        def handleIdle(self,player):

             pass  

        def start(self):
                '''controls the environment by initiating the looping calls'''
                self.TrueTimeLeft=Environment.GAME_DURATION
                self.TimeLeft = int(self.TrueTimeLeft)
                self.view.start('Server')
                if os.path.exists(SERVERDATA):
                        os.remove(SERVERDATA)
                self._renderCall = LoopingCall(self.Update)
                self._renderCall.start(1.0/Environment.FPS)

                self._readCall = LoopingCall( self.readStateFromServer)
                self._readCall.start(1.0/Environment.FPS) 
                


        def calculateScores(self):
        
                score=[0,0]
                for team in range(1,3):
                    for playerId in self.players:

                            player = self.players[playerId]

                            if player.team == team:
                                score[team-1] += player.sides
                                score[team-1] += player.resources

                    for buildingId in self.buildings:
                            building = self.buildings[buildingId]
                            if building.team == team:
                                score[team-1]  += building.sides
                                score[team-1]  += building.resources
                    score[team-1] *= 1000
                return score ;


        #FUNCTIONS FOR NETWORKING
        def writeStateToServer(self):
                string =self.Serialize()
                
                serv_db = shelve.open(SERVERDATA)
                
                try:
                        serv_db['data']= { 'time': str(time.time()), 'string': string }                      
                finally:
                        serv_db.close()
                
                for p in self.players:
                        if( len(self.players[p].animations) >10):
                                self.players[p].animations = self.players[p].animations[1:]
                                      
        def readStateFromServer(self):

                client_db = shelve.open(CLIENTDATA)
                try:
                        self.actions =[]
                        for key in client_db:
                                self.actions.append(client_db[key]['string'].split('$'))
                        
                finally:
                        client_db.close()

        def TransmitStateUDP(self):
                for c in self.clients.itervalues():
                        sock = socket.socket( socket.AF_INET,  socket.SOCK_DGRAM ) # UDP
                        sock.sendto( MESSAGE, (c[0], c[1]) )

        def ReceiveStatesUDP(self):
                for c in self.clients.itervalues():
                        sock = socket.socket( socket.AF_INET,  socket.SOCK_DGRAM ) # UDP
                        sock.sendto( MESSAGE, (c[0], c[1]) )
                        
        def cSerialize(self): #deprecated
                s=pickle.dumps(self.players)+'$'+pickle.dumps(self.buildings)+'$'+\
                pickle.dumps(self.ResourcePool)+'$'+pickle.dumps(self.scores)+'$'+str(self.TimeLeft)+'$'+str(self.Tick)+'$'+str(self.GameOver)  
                
                #print len(s),s         
                return s
        
        def Serialize(self):
                s=''
                for p in self.players.itervalues():
                        s+=str(p.player_id)+'&'
                        s+=str(p.team)+'&'
                        s+=str(p.sides)+'&'
                        s+=str(p.resources)+'&'
                        s+=str(p.partialResources)+'&'
                        s+=str(p.targetPosition.x)+'^'+str(p.targetPosition.y)+'&'
                        for a in p.animations:
                                s+=str(a[0])+'#'+str(a[1])+'#'+str(a[2])+'^'
                        s+='&'
                        s+=str(p.action)+'@'
                s+='$'
                for b in self.buildings.itervalues():
                        s+=str(b.building_id)+'&'
                        s+=str(b.team)+'&'
                        s+=str(b.sides)+'&'
                        s+=str(b.resources)+'&'
                        s+=str(b.partialResources)+'&'
                        s+=str(b.position.x)+'^'+str(b.position.y)+'&'
                        for a in b.animations:
                                s+=str(a[0])+'#'+str(a[1])+'#'+str(a[2])+'^'
                        s+='@'
                s+='$'
                
                s+=str(self.scores[0])+'^'+str(self.scores[1])+'$'
                s+=str(self.TimeLeft)+'$'
                s+=str(self.GameOver)

                return s
Beispiel #9
0
class Environment(pb.Cacheable, pb.RemoteCache):
    def __init__(self):
        self.observers = []
        self.players = {}
        self.rp = ResourcePool(100)
        self.rp.position = Vector2D(0, 0)
        self.width = 48.0
        self.height = 80.0
        self.buildings = {}
        self.team = None

    def createPlayer(self, team):
        player = Player()
        player.team = team
        playerId = id(player)
        self.players[playerId] = player
        for o in self.observers: o.callRemote('createPlayer', playerId, player)
        return player
    def observe_createPlayer(self, playerId, player):
        self.players[playerId] = player

    def removePlayer(self, player):
        pid = id(player)
        del self.players[pid]
        for o in self.observers: o.callRemote('removePlayer', pid)
    def observe_removePlayer(self, pid):
        del self.players[pid]

    def createBuilding(self, team, position):
        if (self.rp.position - position) < 6:
            return None
        for b in self.buildings.itervalues():
            if (team == b.team) and (b.position - position) < 6:
                return None
        building = Building()
        building.team = team
        building.position = position
        bid = id(building)
        self.buildings[bid] = building
        building.onDestroyed.addCallback(self.destroyBuilding)
        for o in self.observers: o.callRemote('createBuilding', bid, building)
        return building
    def observe_createBuilding(self, bid, building):
        self.buildings[bid] = building

    def destroyBuilding(self, building):
        bid = id(building)
        del self.buildings[bid]
        for o in self.observers: o.callRemote('destroyBuilding', bid)
    def observe_destroyBuilding(self, bid):
        del self.buildings[bid]

    def attack(self, player):
        distance = 3
        player.attack()
        for p in self.players.itervalues():
            if (p.team != player.team) and (p.position - player.position) < distance:
                p.hit()
        for b in self.buildings.values():
            if (b.position - player.position) < distance:
                b.hit()

    def startAttacking(self, player):
        player.setAction("Attacking", LoopingCall(self.attack, player))
        player.action.start(2, now=False)

    def startBuilding(self, player):
        if not player.building:
            building = self.createBuilding(player.team, player.position)
            if building:
                player.updatePosition(player.position, building)
            else:
                return
        if player.building == self.rp:
            action = "Mining"
        else:
            action = "Building"
        player.setAction(action, LoopingCall(player.building.build, player))
        player.action.start(2, now=False)

    def finishAction(self, player):
        if player.action:
            player.action.stop()
            player.setAction(None, None)

    def startUpgrading(self, player):
        for b in self.buildings.itervalues():
            if b.isPolyFactory() and (b.team == player.team) and (b.position - player.position) < 3 and not b.upgrading:
                b.upgrading = player
                player.upgradingAt = b

    def finishUpgrading(self, player):
        if player.upgradingAt:
            player.upgradingAt.upgrading = None
            player.upgradingAt = None

    def updatePlayerPosition(self, player, position):
        building = None
        for b in self.buildings.itervalues():
            if (player.team == b.team) and (b.position - position) < 3:
                building = b
                break
        if not building:
            if (self.rp.position - position) < 3:
                building = self.rp
        player.updatePosition(position, building)

        for b in self.buildings.itervalues():
            if b.isTrap() and (b.team != player.team) and ((b.position - player.position) < 1):
                player.trapped()
                b.explode()
                break

    def isVisible(self, entity):
        # Spectators see all
        if not self.team:
            return True
        # See objects on your team
        if self.team == entity.team:
            return True
        # Object in range of my sentries
        for b in self.buildings.itervalues():
            if b.isSentry() and (b.team == self.team) and (entity.position - b.position) < 13.75:
                return True
        # object in range of a scanning player
        for p in self.players.itervalues():
            if (self.team == p.team):
                if (entity.position - p.position) < p.getScanRadius() * 12.35:
                    return True
        return False

    def paint(self, view):
        for b in self.buildings.itervalues():
            # TODO save the view to get images
            b.images = view.images.images
            if self.isVisible(b) or b.explosion:
                b.paint(view, view.screenCoord(b.position), b.team == self.team)
        self.rp.paint(view, view.screenCoord(self.rp.position))
        for p in self.players.itervalues():
            if p.self and p.building:
                p.building.drawToolTip(view, "Build", p.team)
            p.paint(view, view.screenCoord(p.position), self.team == p.team, self.isVisible(p))

    # pb.Cacheable stuff
    def getStateToCacheAndObserveFor(self, perspective, observer):
        self.observers.append(observer)
        state = pb.Cacheable.getStateToCopyFor(self, perspective).copy()
        del state['observers']
        return state

    def stoppedObserving(self, perspective, observer):
        self.observers.remove(observer)
class Environment(LoopingThread): #in an MVC system , this would be a controller
    ''' The environment class contains the state of the game. The server has the master version, the clients have slave versions (updated through the network) '''
    ATTACK_RADIUS = 3
    SCAN_RADIUS = 3
    FPS=30
    

    def __init__(self,player_id,team,serverIP,serverPort):
                '''State: Players,Buildings, Time, Resourse Pool'''
                LoopingThread.__init__(self)               
		
		self.players 	= {}
		self.buildings 	= {}
		self.TimeLeft = 15*60 
		self.width = 80.0
		self.height = 48.0
		self.view =None
		self.GameOver =False
		self.playerID =player_id
		
		self.player = None
		self.action = 0
		self.attemptedAction = 0
		self.lastAction = 0
		self.ActionTimeout = 1
		
		self.team =team
		self.otherTeam = 2 if self.team==1 else  1 
		self.scores =[0,0]
		self.IsServer = False
		self.ResourcePool = ResourcePool()
		self.client = UDPClient(self)
		self.serverIP =serverIP
		self.serverPort = serverPort
                self.Tick = 0
                self.Position = (0,0)
                self.lastUpdate = 0
                self.controller = None


    def createPlayer(self, player_id,team):
                '''add a player to the given team'''
                player = Player()
                player.team = team

                playerId = id(player)
                player.player_id = player_id
               
                self.players[playerId] = player
        
                return player

    def createBuilding(self, team,pos):
                '''add a building to the given team'''
                building = Building()
                building.team = team
                building.position =pos
                bid = id(building)
                building.building_id = 0
                self.buildings[bid] = building
                
        
                return building
            
    def readGestures(self):
        self.controller._handleInput()
        if(self.player<>None):
            #print self.player.action
            if(self.player.action == Player.ATTACK): #ATTACK
                                    self.handleAttack()

            elif(self.player.action == Player.BUILD): #building
                                    self.handleBuild()

            elif(self.player.action == Player.UPGRADE): #building
                                    self.handleUpgrade()

            elif(self.player.action == Player.SCAN): #building
                                    self.handleScan()

            elif(self.player.action == Player.IDLE):
                                    self.handleIdle()



    def handleAttack(self):
                if(self.player.sides>=3):
                        self.player.performAttack(self.Tick)  
                       
    def handleBuild(self):
                ACTION = "BUILD"
                if((self.ResourcePool.getPosition()-self.player.getPosition()).length< self.ResourcePool.size):
                        ACTION ="MINE"
                else:
                        for b in self.buildings.itervalues():
                                
                                if(b.team == self.player.team and b.isPolyFactory() and b.resources == 5 and (b.getPosition()- player.getPosition()).length <b.size):
                                        ACTION ="MINE"
                                        break      
                if( ACTION =="MINE"):
                        self.player.performBuild(self.Tick)  
                        
                                         
                else:
                        if(self.player.resources>0):
                                BUILDING =None
                                for b in self.buildings.itervalues():
                                        if   (b.getPosition() - self.player.getPosition()).length < b.size:
                                                BUILDING =b
                                                break
                                

                                if BUILDING.team ==self.player.team:
                                        self.player.performBuild(self.Tick) 
        
    def handleUpgrade(self):
                allowedUpgradeLoc = False
                if((self.ResourcePool.getPosition()-self.player.getPosition()).length< self.ResourcePool.size):
                        allowedUpgradeLoc=True
                else:
                        for b in self.buildings.itervalues():
                                if(b.team == self.player.team and b.isPolyFactory() and b.resources == 5 and (b.getPosition()- self.player.getPosition()).length <b.size): 
                                        allowedUpgradeLoc=True
                                        break
                if(allowedUpgradeLoc):
                       self.player.upgrade(self.Tick) 

    def handleScan(self):
             self.player.scan(self.Tick)    

    def handleIdle(self):

             pass  
      
    def updateTime(self):
		self.Tick+= 1.0/Environment.FPS
		#if( self.TimeLeft<=0):
		#    self.GameOver =True
            
    def task(self):
                
		#self.deSerialize()
		self.readGestures()
		self.updateTime()
		self.updatePositions()
		self.makeRequest()
		self.view.paint(self.Tick )
                for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                                self.Exit()
                        
    def Exit(self):
        self.shutdown()
        pygame.quit()

       
    def makeRequest(self):
        #print self.action
        
        self.client.MakeRequest(self.playerID,self.team,self.action,self.Position)
        
        self.action = 0
    
    def updatePositions(self):
            for playerId in self.players:
                     
                     if self.players[playerId].player_id <> self.playerID:
                         
                         self.players[playerId].updatePosition( 1.0/Environment.FPS)
                     
    def start(self):
		'''controls the environment by initiating the looping calls'''

		self.lastUpdate =time.time()
		self.view.start('client-'+str(self.playerID))
		self.client.start(self.serverIP,int(self.serverPort),self.playerID)
		
                #if os.path.exists(CLIENTLOCALDATA.split('.')[0]+str(self.playerID)+'.'+CLIENTLOCALDATA.split('.')[1]):		
                #    os.remove(CLIENTLOCALDATA.split('.')[0]+str(self.playerID)+'.'+CLIENTLOCALDATA.split('.')[1])

		self.setInterval(1.0/Environment.FPS)
		self.run()
		#self._renderCall = LoopingCall(self.Update) 
		#self._requestCall = LoopingCall(self.makeRequest) 
		#self._renderCall.start(1.0/Environment.FPS)	
		#self._requestCall.start(1.0/Environment.FPS)	


	#FUNCTIONS FOR NETWORKING
	
    def deSerialize(self,state):
       
        try:
                
            '''
                assume the following message structure
                players$buildings$resourcepool$scores$timeleft$gameover

                    players->player1@player2@..@playern
                        player1->id&Team&sides&resources&partialResources&pos_x^pos_y&anim1^anim2^anim3&action
            '''
            if(state<>None):
                
                t = state.split('$')
                
                if(len(t)>0):
                    
                    players =  t[0].split('@') #update players
                    
                    players.remove('')
                    for p in players:
                          
                        found =False
                        pkey = 0
                        player = p.split('&')

                        pId     = int(player[0])
                        pTeam   = int (player[1])
                        pSides  = int(player[2])
                        pResources  = int(player[3])
                        pPartialResources = int(player[4])
                        pPosition = Vector2D( (float(player[5].split('^')[0]),(float(player[5].split('^')[1]))))
                        AnimationList = player[6].split('^')
                        AnimationList.remove('')
                        pAnimations=[]
                        for a in AnimationList:
                            a = a.split('#')
                            pAnimations.append( (int(a[0]),bool(a[1]),float(a[2])))
                        pAction = int(player[7])
                        
                        for ep in self.players.itervalues():
                            if ep.player_id == pId:
                                found = True
                                pkey = id(ep)
                                break
                        if found:
                            
                            self.players[pkey].sides = pSides
                            self.players[pkey].resources = pResources
                            self.players[pkey].partialResources = pPartialResources
                            
                            
                            
                            if pId == self.playerID:
                                
                                self.players[pkey].position = Vector2D(self.Position)
                                
                                self.players[pkey].action = self.action
                            else:
                                self.players[pkey].animations.extend(pAnimations)
                                self.players[pkey].targetPosition = pPosition
                                self.players[pkey].action = pAction
                        else:
                            
                            newplayer = self.createPlayer(pId,pTeam)
                            if(pId == self.playerID):
                                self.player=newplayer
                            newplayer.targetPosition=pPosition
                            newplayer.sides = pSides
                            newplayer.resources = pResources
                            newplayer.partialResources = pPartialResources
                            newplayer.animations.extend(pAnimations)
                            newplayer.action = pAction

                    '''
                    assume the following message structure
                    players$buildings$resourcepool$scores$timeleft$gameover

                        buildings->buildings@buildings@..@buildings
                            buildings->id&Team&sides&resources&partialResources&pos_x^pos_y&anim1^anim2^anim3
                    '''
                 

                if(t[1]<>''):
                    
                    buildings  =  t[1].split('@')
                    
                    self.buildings.clear()
                    for b in buildings:
                        building = b.split('&')
                        bId = int(building[0])
                        bTeam = int(building[1])
                        bSides  = int(building[2])
                        bResources  = int(building[3])
                        bPartialResources = int(building[4])
                        AnimationList = building[6].split('^')
                        
                        AnimationList.remove('')
                        bAnimations=[]
                        for a in AnimationList:
                            a = a.split('#')
                            bAnimations.append( (int(a[0]),bool(a[1]),float(a[2])))
                            
                        bPosition = Vector2D( (float(building[5].split('^')[0]),(float(building[5].split('^')[1]))))

                        newbuilding = self.createBuilding(bTeam,bPosition)
                        newbuilding.building_id = bId
                        newbuilding.sides = bSides
                        newbuilding.resources = bResources
                        newbuilding.animations.extend(bAnimations)
                if(t[2]<>''):
                    self.scores =(int(t[2].split('^')[0]),int(t[2].split('^')[1]))
                if(t[3]<>''):
                    self.TimeLeft =int(t[3])
                if(t[4]<>''): 
                    self.GameOver = not bool(t[4])
                   
              
        except:
            print "Unexpected error:", sys.exc_info()[0]
Beispiel #11
0
class Environment(pb.Cacheable, pb.RemoteCache):
    
    # This is very confusing, and I blame Sean:
    # Players have more than one ID, but the original one is automatically generated by some super
    # class and isn't nicely indexed
    NEXT_PLAYER_ID = 0  # will need to do something more sophisticated ultimately...
    PLAYER_ID_2_FIDUCIAL_ID = {} # Allow player ids to get as big as however...
    # allow players to select their fiducial index
    
    def __init__(self):
        self.observers = []
        self.players = {}
        self.rp = ResourcePool(100)
        self.rp.position = Vector2D(0, 0)
        self.width = 80.0#48.0
        self.height = 48.0#80.0
        self.buildings = {}
        self.team = None
        self.endTime = None
        self.gameOver = False
        self.attackOk = True
        self.lightOn = True

    def resetGame(self):
        #pass
        self.buildings = {}
        for p in self.players:
            self.players[p].reset()

    def _turnOnLight(self):
        self.lightOn = True

    def observe_blinkLight(self, player):
        if player.self:
            #pass
            #print "blinky"
            self.lightOn = False
            reactor.callLater(.2, self._turnOnLight)
            

    def startGame(self):
        self.observe_startGame(latencyEstimate=0)
        reactor.callLater(GAME_DURATION, self.endGame)
        for o in self.observers:
            o.callRemote('startGame')

    def observe_startGame(self, latencyEstimate=PRESUMED_LATENCY):
        print("start")
        self.observe_updateTimeRemaining(GAME_DURATION, 0)
        self.resetGame()
        self.gameOver = False

    def setPreGame(self):
        #for o in self.observers: o.callRemote('blinkLight')
        self.observe_setPreGame()
        for o in self.observers: o.callRemote('setPreGame')

    def observe_setPreGame(self):
        self.endTime = None
        self.gameOver = False


    def updateTimeRemaining(self, timeRemaining):
        self.observe_updateTimeRemaining(timeRemaining, latencyEstimate=0)
        for o in self.observers: o.callRemote('updateTimeRemaining')

    def observe_updateTimeRemaining(self, timeRemaining, latencyEstimate=PRESUMED_LATENCY):
        self.endTime = int(time.time()) + timeRemaining - latencyEstimate


    def endGame(self):
        self.observe_endGame()
        for o in self.observers: o.callRemote('endGame')

    def observe_endGame(self):
        self.gameOver = True
        self.endTime = int(time.time())

    def createPlayer(self, team):
        player = Player()
        player.team = team
       

        # I have no idea if this is being set somewhere else
        #if self.team == None:
        #    self.team = team

        playerId = id(player)
        
        player.player_id = Environment.NEXT_PLAYER_ID
        Environment.NEXT_PLAYER_ID = Environment.NEXT_PLAYER_ID + 1
        
        self.players[playerId] = player
        for o in self.observers: o.callRemote('createPlayer', playerId, player)
        #player.sounds = self.sounds
        return player

    def observe_createPlayer(self, playerId, player):
        self.players[playerId] = player

    def removePlayer(self, player):
        pid = id(player)
        del self.players[pid]
        for o in self.observers: o.callRemote('removePlayer', pid)
    def observe_removePlayer(self, pid):
        del self.players[pid]

    def createBuilding(self, team, position):
        if (self.rp.position - position) < 6:
            return None
        for b in self.buildings.itervalues():
            if (team == b.team) and (b.position - position) < 6:
                return None
        building = Building()
        building.team = team
        building.position = position
        bid = id(building)
        self.buildings[bid] = building
        building.onDestroyed.addCallback(self.destroyBuilding)
        for o in self.observers: o.callRemote('createBuilding', bid, building)
        return building

    def observe_createBuilding(self, bid, building):
        self.buildings[bid] = building

    def destroyBuilding(self, building):
        bid = id(building)
        del self.buildings[bid]
        for o in self.observers: o.callRemote('destroyBuilding', bid)
    def observe_destroyBuilding(self, bid):
        del self.buildings[bid]

    def attack(self, player):
        #if self.attackOk:
        self.attackOk = False
        reactor.callLater(1.5, self.makeAttackOk)
        distance = 3
        player.attack()
        for p in self.players.itervalues():
            if (p.team != player.team) and (p.position - player.position) < distance:
                p.hit()
        for b in self.buildings.values():
            if b.team != player.team and (b.position - player.position) < distance:
                b.hit()

    def makeAttackOk(self):
        self.attackOk = True

    def startAttacking(self, player):
        if player.sides >= 3:
            print str(player) + " is attacking"
    #        if player.action == None:
            player.setAction("Attacking", LoopingCall(self.attack, player))
            player.action.start(1.5, now=self.attackOk)
            self.attackOk = False
        else:
            print str(player) + " is not allowed to attack"

        #self.attack(player)


    def startBuilding(self, player):
        hadNoBuilding = not player.building
       
        if hadNoBuilding:
            
            newBuildingPosition = player.position
	    
            newBuildingPosition.x = newBuildingPosition.x - 2 #TODO this will likely have to change to x for the phone

            building = self.createBuilding(player.team, newBuildingPosition)
            if building:
                player.updatePosition(player.position, building)
            else:
                return
        if player.building == self.rp:
            action = "Mining"
            
            hadNoBuilding = False
	    player.setAction(action, LoopingCall(player.building.build, player))
            player.action.start(2, now=hadNoBuilding)
	elif player.building.isPolyFactory() and player.building.sides == 5 and player.building.resources == 5:
	    action = "Mining"
            
            hadNoBuilding = False
	    player.setAction(action, LoopingCall(self.rp.build, player))
            player.action.start(2, now=hadNoBuilding)
        else:
            action = "Building"
            player.setAction(action, LoopingCall(player.building.build, player))
            player.action.start(2, now=hadNoBuilding)
        print str(player) + " is " + action
        


    def finishAction(self, player):
        if player.action:
            player.action.stop()
            player.setAction(None, None)

    def startUpgrading(self, player):
        if (player.sides == player.resources) and (player.sides<7) and (player.building == self.rp or player.building.isPolyFactory() ):
		player.startAcceptUpgrade()
        '''for b in self.buildings.itervalues():
            if b.isPolyFactory() and (b.team == player.team) and (b.position - player.position) < 3 :
                #b.upgrading = player
                #player.upgradingAt = b
		player.startAcceptUpgrade()

	'''

    def finishUpgrading(self, player):
        if player.upgradingAt:
            player.upgradingAt.upgrading = None
            player.upgradingAt = None

    def updatePlayerPositionByIndex(self, playerIdx, position):
        #if playerIdx < len(self.players):
        for player in self.players.itervalues():
            if player.player_id == playerIdx:
                self.updatePlayerPosition(player, position)

        
    def updatePlayerPosition(self, player, position):
        building = None
	#print self.rp.position ,position
        for b in self.buildings.itervalues():
            if (player.team == b.team) and (b.position - position) < 3:
                building = b
                break
        if not building:
            if (self.rp.position - position) < 8:
                building = self.rp
        player.updatePosition(position, building)

        for b in self.buildings.itervalues():
            if b.isTrap() and (b.team != player.team) and ((b.position - player.position) < 1 and player.sides>=3):
                player.trapped()
                b.explode()
                break

    def isVisible(self, entity):
        # Spectators see all
        if not self.team:
            return True
        # See objects on your team
        if self.team == entity.team:
            return True
        # Object in range of my sentries
        for b in self.buildings.itervalues():
            if b.isSentry() and (b.team == self.team) and (entity.position - b.position) < 13.75:
                return True
        # object in range of a scanning player
        for p in self.players.itervalues():
            if (self.team == p.team):
                if (entity.position - p.position) < p.getScanRadius() * 5:
                    return True
        return False

    def paint(self, view):
        for b in self.buildings.itervalues():
            # TODO save the view to get images
            b.images = view.images.images
            if self.isVisible(b) or b.explosion:
                if self.team is None:
                    b.paint(view, view.screenCoord(b.position/2), b.team == self.team)
                else:
                    b.paint(view, view.screenCoord(b.position), b.team == self.team)
                
        self.rp.paint(view, view.screenCoord(self.rp.position))
        for p in self.players.itervalues():
            if p.self:
                view.setCenter(p.position)
                # Draw player id
		font = pygame.font.Font("data/Deutsch.ttf", 20)
		text = font.render("Player:" + str(p.player_id), True, (180, 180, 125))
		
		textrect = text.get_rect(left = 700, top = 20)
		view.screen.blit(text,textrect)
            if p.self and p.building:
                p.building.drawToolTip(view, "Build", p.team)
            if self.team is None:
                p.paint(view, view.screenCoord(p.position/2), self.team == p.team, self.isVisible(p))
            else:
                p.paint(view, view.screenCoord(p.position), self.team == p.team, self.isVisible(p))
            #p.paint(view, view.screenCoord(p.position), self.team == p.team, self.isVisible(p))

        # Draw the score:
        #TODO color appropriately
        
        if self.team is None:
            thisTeam = 1
            otherTeam = 2
        else:
            thisTeam = self.team
            otherTeam = self.getOpponentTeam()
        if not self.team:
		font = pygame.font.Font("data/Deutsch.ttf", 70)
		#font = pygame.font.Font(None, 45)
		fontColors = [(255, 0, 0), (0,255,255)]
		text = font.render(str(self.calculateScore(thisTeam)), True, fontColors[thisTeam-1])
		#text = pygame.transform.rotate(text, 270)
		textrect = text.get_rect(right =1400, top = 40)
		view.screen.blit(text,textrect)

		text = font.render(str(self.calculateScore(otherTeam)), True, fontColors[otherTeam-1])
		#text = pygame.transform.rotate(text, 270)
		textrect = text.get_rect(right =1400, top = 160)
	else:
		font = pygame.font.Font("data/Deutsch.ttf", 35)
		#font = pygame.font.Font(None, 45)
		fontColors = [(255, 0, 0), (0,255,255)]
		text = font.render(str(self.calculateScore(thisTeam)), True, fontColors[thisTeam-1])
		text = pygame.transform.rotate(text, 270)
		textrect = text.get_rect(right =735, bottom = 410)
		view.screen.blit(text,textrect)

		text = font.render(str(self.calculateScore(otherTeam)), True, fontColors[otherTeam-1])
		text = pygame.transform.rotate(text, 270)
		textrect = text.get_rect(right = 775, bottom = 410)
	view.screen.blit(text,textrect)
	

	
	
        # ======================================================================
        #Draw the time remaining
        minRemaining = 15
        secRemaining = 0
        if self.endTime:
            secRemaining = max(self.endTime - int(time.time()), 0)
            minRemaining = secRemaining / 60
            secRemaining = secRemaining % 60

        secStr = str(secRemaining)
        if secRemaining <= 9: secStr = "0" + secStr

        minStr = str(minRemaining)
        if minRemaining <= 9: minStr = "0" + minStr

        
        
	if not self.team:
	    font = pygame.font.Font("data/Deutsch.ttf", 70)
            text = font.render(minStr + ":" + secStr, True, (255, 255, 255))
	    text = pygame.transform.rotate(text, 0)
            textrect = text.get_rect(left = 15, top = 40)
	else:
            font = pygame.font.Font("data/Deutsch.ttf", 35)
            text = font.render(minStr + ":" + secStr, True, (255, 255, 255))
	    text = pygame.transform.rotate(text, 270)
  
	    textrect = text.get_rect(left = 15, bottom = 410)

        view.screen.blit(text,textrect)

        # ======================================================================
        # draw end game message, as appropriate
        if self.gameOver:
            endGameMessage = ""
            if self.team:
                scoreDifference = self.calculateScore(self.team) > self.calculateScore(self.getOpponentTeam())
                if scoreDifference > 0:
                    endGameMessage = "YOU WIN!"
                elif scoreDifference < 0:
                    endGameMessage = "YOU LOSE!"
                else:
                  endGameMessage = "DRAW!"

            else:
                scoreDifference = self.calculateScore(1) - self.calculateScore(2)
                if scoreDifference > 0:
                    endGameMessage = "RED WINS!"
                elif scoreDifference < 0:
                    endGameMessage = "BLUE WINS!"
                else:
                    endGameMessage = "DRAW!"



            
	    if not self.team:
		    font = pygame.font.Font("data/Deutsch.ttf", 140)
		    #font = pygame.font.Font(None, 45)
		    text = font.render(endGameMessage, True, (255,255,255))
		    textrect = text.get_rect(centery =600, centerx = 800)
	    else:
		    font = pygame.font.Font("data/Deutsch.ttf", 70)
		    #font = pygame.font.Font(None, 45)
		    text = font.render(endGameMessage, True, (255,255,255))
		    text = pygame.transform.rotate(text, 270)
		    textrect = text.get_rect(centery =240, centerx = 350)  
	    
            view.screen.blit(text,textrect)

        # ======================================================================
        # draw draw white square for photo sensor
	# DEPRECATED, white square no longer needed for tracking.

        sqrSz = 75
        if False: #not self.team == None:
            sensRect = pygame.Rect(0, 0, sqrSz + 5, sqrSz + 10)
            sensRect.right = 800
            sensRect.centery = 240
            pygame.draw.rect(view.screen, (0,0,0), sensRect)

            if self.lightOn:
                sensRect = pygame.Rect(0,0,sqrSz,sqrSz)
                sensRect.right = 800
                sensRect.centery = 240
                pygame.draw.rect(view.screen, (255,255,255), sensRect)


    # pb.Cacheable stuff
    def getStateToCacheAndObserveFor(self, perspective, observer):
        self.observers.append(observer)
        state = pb.Cacheable.getStateToCopyFor(self, perspective).copy()
        del state['observers']
        return state

    def stoppedObserving(self, perspective, observer):
        self.observers.remove(observer)

    def switchTeams(self, player):
        self.team = self.getOpponentTeam()
        player.switchTeams()

    def getOpponentTeam(self):
        if self.team == 1:
            return 2
        else:
            return 1

    def calculateScore(self, team):
        #print "score =================================="
        if team == None:
            team = self.team
#        print "=== Our Team: " + str(team)
        score = 0;
        for playerId in self.players:
            #score = score + 100
            player = self.players[playerId]
            #print "player team: " + str(player.team)
            if player.team == team:
                score = score + player.sides
                score = score + player.resources

        for buildingId in self.buildings:
            #score = score + 10000
            building = self.buildings[buildingId]
            #print "bildg team: " + str(building.team)
            if building.team == team:
                score = score + building.sides
                score = score + building.resources

        return score * 1000;