Exemple #1
0
 def test_getStateVars2(self):
     simulatedError = 0.01
     simWidth = 550.0
     simHeight = 357.0
     ballPos = (1/3 * simWidth,1/6 * simHeight)
     c = (simWidth /2.0,simHeight/2.0)
     a1 = agent.agent((1/3 * simWidth,1/6 * simHeight),simulatedError,"Keeper",ballPos)
     a2 = agent.agent((2/3 * simWidth,1/7 * simHeight),simulatedError,"Keeper",ballPos)
     a3 = agent.agent((2/5 * simWidth,6/7 * simHeight),simulatedError,"Keeper",ballPos)
     keepers = [a1,a2,a3]
     t1 = agent.agent((1/2 * simWidth,5/12 * simHeight),simulatedError,"Taker",ballPos)
     t2 = agent.agent((2/5 * simWidth,7/12 * simHeight),simulatedError,"Taker",ballPos)
     takers = [t1,t2]
     testOut = getStateVarsKeepers(keepers, takers, c)
     actualOut = [kUtil.getDist((550/3, 59.5), c),
                  kUtil.getDist((550/3 * 2, 51), c),
                  kUtil.getDist((220, 306), c),
                  kUtil.getDist((275, 148.75), c),
                  kUtil.getDist((220, 208.25), c),
                  kUtil.getDist((550/3,59.5), (550/3*2, 51)),
                  kUtil.getDist((550/3,59.5), (220,306)),
                  kUtil.getDist((550/3,59.5), (275, 148.75)),
                  kUtil.getDist((550/3,59.5), (220, 208.25)),
                  min( kUtil.getDist((550/3*2,51), (220, 208.25)), kUtil.getDist((550/3*2,51), (275, 148.75)) ),
                  min( kUtil.getDist((220,306), (220, 208.25)), kUtil.getDist((220,306), (275, 148.75)) ),
                  max(kUtil.cosTheta((550/3*2, 51), (550/3,59.5), (275,148.75)), 
                      kUtil.cosTheta((550/3*2, 51), (550/3,59.5), (220,208.25))),
                  max(kUtil.cosTheta((220,306), (550/3,59.5), (275,148.75)), 
                      kUtil.cosTheta((220,306), (550/3,59.5), (220,208.25))),
                  ]
     for i in range(len(testOut)):
         self.assertAlmostEqual(testOut[i], actualOut[i], 1,"Failed on index: %d" % i)
Exemple #2
0
    def decisionFlowChart (self):
        if (self.agentType == "taker"):
            #taker closest to ball will go to ball.
            #state variables 7 and 8 contain the distances from T1 to K1 and T2 to K2 respectively
            if (self.stateVariables[7] < self.stateVariables[8] ):
                #taker 1 is closer
                closerTaker = 0
            else:
                closerTaker = 1
            takerActual = sorted(self.takerArray)
            if (self.agentListIndex == takerActual[closerTaker].agentListIndex):
                #you're the closer taker so go for the ball
                self.goToBall()
            else:
                #you're the farther taker, so go and block pass to the closer keeper
                keeperActual = sorted(self.keeperArray)
                cos2 = kUtil.cosTheta(self.noisy_pos, keeperActual[0].noisy_pos, keeperActual[1].noisy_pos)
                cos3 = kUtil.cosTheta(self.noisy_pos, keeperActual[0].noisy_pos, keeperActual[2].noisy_pos)
                if cos2 > cos3:
                    #block keeper 2
                    self.blockPass(1)
                else:
                    self.blockPass(2)

        else:
            #the agent is a keeper
            if(self.inPosession == False):
                #deterministic stuff happens here
                self.receive()
            else:#TODO
                #THIS IS WHERE THE INTELLIGENT AGENT CODE MAKES DECISION
                #since this is the hand coded extension, I'm just going to hard code some stuff
                #q learning and Sarsa should hopefully do better
                
                if self.isInTraining:
                    self.oldState = self.stateApprox(self.stateVariables)
                    self.myAction = True
                    self.action = self.getAction(self.oldState)
                    keeperActual = sorted(self.keeperArray)
                    if self.action == "HoldBall":
                        self.holdBall()
                    elif self.action == "PassN":
                        self.passBall(1)
                    else:
                        self.passBall(2)
                else:
                    self.action = self.computeActionFromQValues(self.stateApprox(self.stateVariables))
                    keeperActual = sorted(self.keeperArray)
                    if self.action == "HoldBall":
                        self.holdBall()
                    elif self.action == "PassN":
                        self.passBall(1)
                    else:
                        self.passBall(2)
                '''
Exemple #3
0
 def __getOpen(self):
     """
     This function implements a hand coded procedure to go and place individual agents
     in an optimal position to receive a pass. The code for this function is 
     based heavily on "Algorithm 2 GetOpen:Hand-coded", which is the pseudo-code
     for the getOpen function used by some other researchers and was published 
     here:
     http://www.cs.utexas.edu/users/pstone/Papers/bib2html-links/LNAI09-kalyanakrishnan-1.pdf
     
     Only keeper who are not trying to go after the ball should call this method.
     The decision for who goes after the ball or gets open is deterministic. 
     
     :returns: nothing
     """
     #note: safety constant is cos(18.4) degrees
     safetyConstant = 0.94887601164449654493424118056447
     curMax = float("-inf")
     argMax = self.getOpenPoints[12] #default case
     if self.worldRef.fieldBall.trueBallDirection == (0.0, 0.0):
         predictedBallPos = self.noisyBallPos
     else:
         predictedBallPos = self.onReceiveDecision[1]
     for point in self.getOpenPoints:
         safety = max(kUtil.cosTheta(point, predictedBallPos, self.takerArray[0].get_noisy_pos()),
                      kUtil.cosTheta(point, predictedBallPos, self.takerArray[1].get_noisy_pos()))
         if (safety > safetyConstant):
             #angle is too narrow, a taker can easily steal
             continue
         
         #if you're at this point, then then point is a safe point to consider
         teamCongestion = 0.0
         oppCongestion = 0.0
         totalCongestion = 0.0
         value = 0.0
         for i in range(len(self.keeperArray)):
             if i != self.agentListIndex:
                 teamCongestion += 1.0 / (kUtil.getDist(self.keeperArray[i].get_noisy_pos(), point))
         for i in range(len(self.takerArray)):
             oppCongestion += 1.0 / (kUtil.getDist(self.takerArray[i].get_noisy_pos(), point))
         totalCongestion = teamCongestion + oppCongestion
         value = -1.0 * totalCongestion
         if (value > curMax):
             curMax = value
             argMax = point
     #At this point, just run towards argMax at max speed
     minDist = min(self.maxPlayerSpeed, kUtil.getDist(self.__noisy_pos, argMax))
     self.worldRef.moveAttempt(self, (kUtil.getVector(self.__noisy_pos, argMax), minDist) )
Exemple #4
0
    def decisionFlowChart (self, message = None):
        """
        This function will control the movement of keepers and takers. It controls 
        movement by calling on all the private movement functions that are in defined
        in this agent class
        """
        if (self.getAgentType() == "taker"):
            takerActual = sorted(self.takerArray)
            if (self.agentListIndex == takerActual[0].agentListIndex):
                #you're the closer taker so go for the ball
                self.__goToBall()
            else:
                #you're the farther taker, so go and block pass to the closer keeper
                """
                #this is the code where the 2nd taker is stupid. 
                keeperActual = sorted(self.keeperArray)
                cos2 = kUtil.cosTheta(self.get_noisy_pos(), keeperActual[0].get_noisy_pos(), keeperActual[1].get_noisy_pos())
                cos3 = kUtil.cosTheta(self.get_noisy_pos(), keeperActual[0].get_noisy_pos(), keeperActual[2].get_noisy_pos())
                if cos2 > cos3:
                    #block keeper 2
                    self.__blockPass(1)
                else:
                    self.__blockPass(2)
                """
                #this is the code where the 2nd keeper is smarter and acts as if he understands positioning better
                                #this is the code where the 2nd taker is stupid. 
                keeperActual = sorted(self.keeperArray)
                cos2 = kUtil.cosTheta(takerActual[0].get_noisy_pos(), keeperActual[0].get_noisy_pos(), keeperActual[1].get_noisy_pos())
                cos3 = kUtil.cosTheta(takerActual[0].get_noisy_pos(), keeperActual[0].get_noisy_pos(), keeperActual[2].get_noisy_pos())
                if cos2 > cos3:
                    #if cos2 is bigger, then the taker going for the ball is also kinda blocking a pass to keeper 1. At least
                    #he's doing a better job blocking K1 than K2, so go block K2
                    self.__blockPass(2)
                else:
                    #otherwise, go block K1
                    self.__blockPass(1)

        else:
            #the agent is a keeper
            if(self.inPosession == False):
                #deterministic stuff happens here
                self.__receive()
            else:
                self._decisionFunction()
Exemple #5
0
 def getOpen(self, respectivePos):
     keeper = self
     stepIncrease = 5
     maximum = -9999
     #the threshold is compared to cosTheta. so 0 means the windows has to be at least 90 degrees. 
     #1.0 is most flexible value as it's saying the angle has to be at least 0
     threshold = 0.9
     maxPoint = None
     tempmaximum = -9999
     tempmaxPoint = None
     playersToIterate = []
     for isKeeper in self.keeperArray:
         if isKeeper != self:
             playersToIterate.append(isKeeper)
     for taker in self.takerArray:
         playersToIterate.append(taker)
             
     pointsToIterate = [(self.true_pos[0],self.true_pos[1]+stepIncrease),
                         (self.true_pos[0]+stepIncrease,self.true_pos[1]),
                         (self.true_pos[0]+stepIncrease,self.true_pos[1]+stepIncrease),
                         (self.true_pos[0]-stepIncrease,self.true_pos[1]-stepIncrease),
                         (self.true_pos[0]-stepIncrease,self.true_pos[1]),
                         (self.true_pos[0],self.true_pos[1]-stepIncrease),
                         (self.true_pos[0]-stepIncrease,self.true_pos[1]+stepIncrease),
                         (self.true_pos[0]+stepIncrease,self.true_pos[1]-stepIncrease),]
         
     for point in pointsToIterate:
         if kUtil.cosTheta(point, respectivePos, self.takerArray[0].true_pos)>threshold and kUtil.cosTheta(point, respectivePos, self.takerArray[1].true_pos)>threshold:
             spar = 0
             for player in playersToIterate:
                 spar += kUtil.getDist(player.true_pos, point)
                 
             if spar>tempmaximum:
                 tempmaximum = spar
                 tempmaxPoint = point
             continue
         else:
             spar = 0
             for player in playersToIterate:
                 spar += kUtil.getDist(player.true_pos, point)
                 
             if spar>maximum:
                 maximum = spar
                 maxPoint = point
         
     if maxPoint == None:
         #print("no open position available for agent #", self.agentListIndex + 1)
         maxPoint = tempmaxPoint
             
     #return (kUtil.getVector(keeper.true_pos, maxPoint),stepIncrease)
     self.worldRef.moveAttempt(self, (kUtil.getVector(keeper.true_pos, maxPoint), self.maxPlayerSpeed))
Exemple #6
0
 def calc_receive_ball_moving(self):
     #make sure that you're only doing this if
     for i in range(len(self.keeperArray)):
         if self.keeperArray[i].inPosession == True:
             rDecision = (i, self.keeperArray[i].true_pos)
             return
     for i in range(len(self.takerArray)):
         if self.takerArray[i].inPosession == True:
             return
         
     TA = kUtil.addVectorToPoint(self.fieldBall.trueBallPos, self.fieldBall.trueBallDirection)
     TB = self.fieldBall.trueBallPos
     minTime = 99999.0
     argmin = None
     bestPerpIntersect = None
     for i in range(len(self.keeperArray)):
         TC = self.keeperArray[i].true_pos
         if (kUtil.cosTheta(TA, TB, TC)) < 0:
             #print("Keeper " , i, " can't get to ball: the cosTheta is negetive.")
             #it's impossible for this keeper to get the ball
             continue
         else:
             pd = kUtil.getPerpDist(TA, TB, TC)
             pt = pd/self.maxPlayerSpeed
             normalVector = kUtil.getNormalVector(TA, TB, TC)
             perpIntersect = kUtil.addVectorToPoint(TC, normalVector)
             bd = kUtil.getDist(TB, perpIntersect)
             bt = bd/self.maxBallSpeed
             if pt > bt:
                 #keeper wont' be able be able to get to ball in time
                 #print("player ", i+1, "can't reach ball as pt:",pt," and bt: ",bt)
                 continue
             else:
                 #keeper CAN get to ball. can it get there soonest though?
                 #save the fastest keeper
                 if (pt < minTime):
                     minTime = pt
                     argmin = i
                     bestPerpIntersect = perpIntersect
     #at this point, if a keeper can get to the ball, the fastest and it's intercept are saved
     if (argmin != None):
         rDecision = [argmin, self.calcOptimal(self.keeperArray, argmin, bestPerpIntersect)]
         for i in range(len(self.keeperArray)):
             self.keeperArray[i].receiveDecision(rDecision)
         for i in range(len(self.takerArray)):
             self.takerArray[i].receiveDecision(rDecision)
     else:
         print("no argmin found. game about to crash for sure")
def __getCosAngle(agent1, agent2, agent3):
    return kUtil.cosTheta(agent1.get_noisy_pos(), agent2.get_noisy_pos(), agent3.get_noisy_pos())
Exemple #8
0
def getCosAngle(agent1, agent2, agent3):
    return kUtil.cosTheta(agent1.noisy_pos, agent2.noisy_pos, agent3.noisy_pos)
Exemple #9
0
def __calc_receive_ball_moving(worldRef, inputDirection, possessingKeeperIndex):
    """
    This function is a private function meant to assist calc_receive. This function 
    will go and calculate the receive decision for the special case where the 
    ball is moving. The receive decision is a tuple that simply contains the 
    index of the keeper that should run towards the ball, and the coordinate 
    that the keeper should run to. 
    If the ball is moving, then calc_receieve will find an intersection point
    along the balls projected path that the selected keeper can run to. 
    The intercept point is selected such that the 
    selected keeper will run a short distance, be far away from the takers, 
    and also be far away from out of bounds.  
    
    .. note::
        This is a private function that the user shouldn't worry about calling.
        Only the calc_receieve function of this method will use this function.
        And only the simulator class should call the calc_receive function. 
    
    :param worldRef: a reference to the simulator class which is calling this function
    :param inputDirection: the current direction the ball is moving.
    :param possessingKeeperIndex: the index of the keeper who currently has possession
        
    :type worldRef: keepAway
    :type inputDirection: tuple of floats
    :type possessingKeeperIndex: integer
    
    :returns: tuple, where first element is the index of the keeper picked to run towards
        the ball. The simulator will use this index to look up the index of the keeper 
        in its self.keeperArray. The 2nd element is the intersection coordinate
    :rtype: tuple where first element is integer, second element is tuple. 2nd element
        tuple contains integers

    """
    #TA is a point that the ball is heading to in the next time step      
    TA = kUtil.addVectorToPoint(worldRef.fieldBall.trueBallPos, inputDirection)
    #TB is the current ball position, and for angle calculations, it will be the vertex
    TB = worldRef.fieldBall.trueBallPos
    minTime = float("inf")
    argmin = None
    bestPerpIntersect = None
    #the purpose of this for loop is to find which keeper should go to the ball. 
    for i in range(len(worldRef.keeperArray)):
        #TC is the position of the keeper who's figuring out if he should goToBall(), or getOpen()
        TC = worldRef.keeperTruePosArray[i]
        if (kUtil.cosTheta(TA, TB, TC)) < 0:
            #print "Keeper " , i, " can't get to ball: the cosTheta is negetive."
            #it's impossible for this keeper to get the ball
            continue 
        else:
            pd = kUtil.getPerpDist(TA, TB, TC)
            pt = pd/worldRef.maxPlayerSpeed
            normalVector = kUtil.getNormalVector(TA, TB, TC)
            perpIntersect = kUtil.addVectorToPoint(TC, normalVector)
            bd = kUtil.getDist(TB, perpIntersect)
            bt = bd/worldRef.maxBallSpeed
            if pt > bt:
                #keeper wont' be able be able to get to ball in time
                #print "player ", i+1, "can't reach ball as pt:",pt," and bt: ",bt 
                continue
            else:
                #keeper CAN get to ball. can it get there soonest though?
                #save the fastest keeper
                if (pt < minTime and i !=  possessingKeeperIndex):
                    minTime = pt
                    argmin = i
                    bestPerpIntersect = perpIntersect
    #at this point, if a keeper can get to the ball, 
    #the fastest and it's intercept are saved
    if (argmin != None):
        rDecision = [argmin, __calcOptimal(worldRef, worldRef.keeperArray, argmin, bestPerpIntersect)]
        return rDecision
    else:
		rDecision = [1 , worldRef.get_field_center()]
		#print("no argmin found. game about to end for sure.")
		return rDecision