コード例 #1
0
    def update(self, game):
        if (self.currentTick == game.current_tick):
            return

        self.currentTick = game.current_tick
        currentPointIx = 0
        found = False
        # в штатной ситуации цикл завершается на второй итерации
        for tp in self.trajectoryPoints:
            if (tp.tick == self.currentTick):
                found = True
                break
            currentPointIx += 1

        if (found == False):
            # список пуст или произошла невообразимо кошмарная ошибка, исправление которой
            # начнется с очистки списка
            #self.trajectoryPoints.clear()
            self.recalculateTrajectory(game)
        else:
            self.trajectoryPoints = self.trajectoryPoints[currentPointIx:]
            currentPt = self.trajectoryPoints[0]
            realPos = Vector3D(game.ball.x, game.ball.y, game.ball.z)
            predictedPos = Vector3D(currentPt.x, currentPt.y, currentPt.z)
            delta = (realPos - predictedPos).len()
            if (delta > ALLOWED_POSITION_DIVERGENCE):
                # перестраиваем прогноз заново, с текущего состояния
                #self.trajectoryPoints.clear()
                self.recalculateTrajectory(game)
            self.fillTrajectory()
コード例 #2
0
def getStrikePoint(game): # (game: Game)
  '''
  dstDelta = miscInfo.gameRules.ROBOT_MIN_RADIUS + \
             miscInfo.gameRules.BALL_RADIUS - \
             0.20 # в лучших традициях подбирается экспертным путем ((
  '''
  dstDelta = miscInfo.touchDst2d - 0.1
  
  if ( game.ball.z < miscInfo.aimPoint.z ):
    pt2 = Vector3D(game.ball.x, game.ball.y, game.ball.z)
    pt1 = miscInfo.aimPoint
  else:
    pt2 = miscInfo.aimPoint
    pt1 = Vector3D(game.ball.x, game.ball.y, game.ball.z)

  kx = pt2.x - pt1.x
  ky = pt2.y - pt1.y
  kz = pt2.z - pt1.z

  ts = ( (dstDelta ** 2) /
         ( kx**2 + ky**2 + kz**2 ) ) ** 0.5

  xs = kx * ts + game.ball.x
  ys = ky * ts + game.ball.y
  zs = kz * ts + game.ball.z
  
  #print(pt2.z, pt1.z)

  #print(dstDelta, miscInfo.aimPoint.x, miscInfo.aimPoint.y, miscInfo.aimPoint.z, \
       #kx,ky,kz,ts, sep = '\n' )

  #if ( game.current_tick == 5 ):
    #return None

  return Vector3D(xs, ys, zs)
コード例 #3
0
    def predictedBall(self, ball, ticks=1):
        # предсказывает положение (и скорость мяча на ticks вперед)
        newBall = copy.copy(ball)
        # здесь было дробление тика, и я специально его оставляю в виде комментария
        # чтобы оно напоминало, что эта штука неэффективна
        '''
    tick_split = 10
    dt = self.tik / tick_split
    '''
        for i in range(1, ticks + 1):
            #for i in range(1, (ticks * tick_split + 1)):
            ballPt = Vector3D(newBall.x, newBall.y, newBall.z)
            dst, norm = self.distanceToArena(ballPt)
            penetration = self.rules.BALL_RADIUS - dst
            #if (ticks == 8):
            #pdb.set_trace()
            if (penetration > 0):
                ballPt += norm * penetration
                ballVelocity = Vector3D(newBall.velocity_x, newBall.velocity_y,
                                        newBall.velocity_z)
                vlcModule = ballVelocity.scalarMul(norm)
                if (vlcModule < 0):
                    ballVelocity -= norm * (
                        1.0 + self.rules.BALL_ARENA_E) * vlcModule
                    newBall.velocity_x = ballVelocity.x
                    newBall.velocity_y = ballVelocity.y
                    newBall.velocity_z = ballVelocity.z

                newBall.x = ballPt.x + newBall.velocity_x * self.tik
                newBall.y = ballPt.y + newBall.velocity_y * self.tik - \
                            self.rules.GRAVITY * self.tik**2 / 2
                newBall.z = ballPt.z + newBall.velocity_z * self.tik
            else:
                newBall.x += newBall.velocity_x * self.tik
                newBall.y += newBall.velocity_y * self.tik - \
                             self.rules.GRAVITY * self.tik**2 / 2
                newBall.z += newBall.velocity_z * self.tik
                newBall.velocity_y -= self.rules.GRAVITY * self.tik
        return newBall
コード例 #4
0
    def getAimPoint(self, game):
        # точка в воротах противника, траектория полета мяча к которой
        # из его текущего положения максимально удалена от роботов противника

        # TODO пока используется сильно упрощенный вариант

        enemyBots = []

        for bot in game.robots:
            if (bot.is_teammate == False and bot.z > game.ball.z):
                enemyBots.append(bot)

        ballRVec = Vector3D(game.ball.x, game.ball.y, game.ball.z)

        # базовые значения - работают, если на пути роботов противника нет
        px = 0  # obviously
        py = self.rules.arena.goal_height / 2
        pz = self.rules.arena.depth / 2  # и не меняется
        return Vector3D(px, py, pz)

        topY = self.rules.arena.goal_height - self.rules.BALL_RADIUS
        bottomY = self.rules.BALL_RADIUS

        rightX = self.rules.arena.goal_width / 2 - self.rules.BALL_RADIUS
        leftX = -rightX

        vects = [[Vector3D(px, py, pz) - ballRVec, 0.0],
                 [Vector3D(rightX, topY, pz) - ballRVec, 0.0],
                 [Vector3D(leftX, topY, pz) - ballRVec, 0.0],
                 [Vector3D(rightX, bottomY, pz) - ballRVec, 0.0],
                 [Vector3D(leftX, bottomY, pz) - ballRVec, 0.0]]

        def elemVal(elem):
            return elem[1]

        for bot in enemyBots:
            botVec = Vector3D(bot.x, bot.y, bot.z) - ballRVec
            for v in vects:
                projection = botVec.projectOn(v[0])
                v[1] = (projection - botVec).len()
            vects.sort(key=elemVal)
            try:
                vects.pop()
                vects.pop()
            except IndexError:
                pass

        return vects[0][0]
コード例 #5
0
    def getStrikePoint(self, game):  # (game: Game)
        dstDelta = self.rules.ROBOT_MIN_RADIUS + \
                   self.rules.BALL_RADIUS - \
                   0.15 # в лучших традициях подбирается экспертным путем ((
        aimPoint = self.getAimPoint(game)

        if (game.ball.z < aimPoint.z):
            pt2 = Vector3D(game.ball.x, game.ball.y, game.ball.z)
            pt1 = aimPoint
        else:
            pt2 = aimPoint
            pt1 = Vector3D(game.ball.x, game.ball.y, game.ball.z)

        kx = pt2.x - pt1.x
        ky = pt2.y - pt1.y
        kz = pt2.z - pt1.z

        ts = ((dstDelta**2) / (kx**2 + ky**2 + kz**2))**0.5

        xs = kx * ts + game.ball.x
        ys = ky * ts + game.ball.y
        zs = kz * ts + game.ball.z

        return Vector3D(xs, ys, zs)
コード例 #6
0
def getDefencePoint(rules):
  # точка стояния защитника в воротах
  px = 0 # obviously
  py = robot.radius
  pz = 0.0 - rules.arena.depth / 2
  return Vector3D(px, py, pz)
コード例 #7
0
def doDefend(me, game, action):
  prTrajectory = ballPred.getPredictedTrajectory()
  # если все спокойно, стоять в центре ворот
  waitPt = Vector2D(0.0,
                   -(miscInfo.gameRules.arena.depth / 2.0) - 1.5 )

  defAreaWidth = miscInfo.gameRules.arena.goal_width
  defAreaDepth = 13.0 # эмпирически, как и всегда ((
  defAreaZeroZ = - (miscInfo.gameRules.arena.depth / 2.0)
  defAreaZ = defAreaZeroZ + defAreaDepth

  interceptionPoint = None
  goodHeight = miscInfo.gameRules.BALL_RADIUS + \
               miscInfo.gameRules.ROBOT_MIN_RADIUS - 0.5
  # max BALL CENTER height при которой до мяча еще дотянется робот
  maxRH = miscInfo.reachableZ + \
          miscInfo.gameRules.ROBOT_MIN_RADIUS + \
          miscInfo.gameRules.BALL_RADIUS

  lineCrossX = None

  # если мяч в ближайшее время попадает на площадку перед воротами
  for b in prTrajectory:
    if ( b.z < (- miscInfo.gameRules.arena.depth / 2) - \
         miscInfo.gameRules.BALL_RADIUS ):
      lineCrossX = b.x
      break
    if ( abs(b.x) < defAreaWidth / 2 and
         b.z < defAreaZ ):
      #ballNearGoal = True
      #print(game.current_tick, ' detected')
      ticksLeft = b.tick - game.current_tick
      bPt = Vector2D(b.x, b.z)
      ticksNeed = botControl.approxTimeToPoint(bPt, game, me)
      #if (ticksNeed < 0):
        #pdb.set_trace()
      ticksNeedToJump, v0 = \
        botControl.calculateJump(b.y - \
                                 miscInfo.gameRules.BALL_RADIUS - \
                                 miscInfo.gameRules.ROBOT_MIN_RADIUS)
      if (ticksNeedToJump == 0 and
          interceptionPoint == None):
        interceptionPoint = b
        #break
      '''
      if (ticksNeed + ticksNeedToJump < ticksLeft):
        if (interceptionPoint == None):
          interceptionPoint = b
        else:
          if (b.y < interceptionPoint.y):
            interceptionPoint = b
      '''

  # TODO REMOVE
  '''
  readyPt = copy.copy(waitPt)
  if (goalAlert == True):
    readyPt.x = lineCrossX
    print('cross', lineCrossX)
  botControl.botToPointAndStop(readyPt, me, action)

  return
  '''

  #if (lineCrossX != None and interceptionPoint == None):
    #print(game.current_tick, ' F**K, GOAL IMMINENT')

  # прочие случаи
  if (me.z > game.ball.z or 
      interceptionPoint == None ):
    botControl.botToPointAndStop(waitPt, me, action)
  
  if ( interceptionPoint != None ):
    tgtPt = Vector2D(interceptionPoint.x, interceptionPoint.z - 1.0)
    ticksLeft = interceptionPoint.tick - game.current_tick
    ticksNeedToRoll = botControl.approxTimeToPoint(tgtPt, game, me)
    h = min(interceptionPoint.y, miscInfo.reachableZ)
    ticksNeedToJump, v0 = \
      botControl.calculateJump(h)

    #print(game.current_tick, ticksNeedToJump, ticksNeedToRoll, ticksLeft)
    if ( ticksLeft - ticksNeedToRoll <= 0 ):
      botControl.botToPoint(tgtPt, me, action)
      #botControl.botToPointAndStop(tgtPt, me, action)
    else:
      readyPt = copy.copy(waitPt)
      if (lineCrossX != None):
        readyPt.x = lineCrossX
      botControl.botToPointAndStop(readyPt, me, action)
      #botControl.botToPointAndStop(waitPt, me, action)
    '''
    if ( ticksLeft - ticksNeedToJump <= 0 and
         me.touch == True ):
      action.jump_speed = v0
    '''
    botControl.doDecideJump(prTrajectory, game, me, action)
    
    kickBall = ( Vector3D(game.ball.x, game.ball.y, game.ball.z) - \
                 Vector3D(me.x, me.y, me.z) ).len() <= \
               ( miscInfo.gameRules.ROBOT_MAX_RADIUS + \
                 miscInfo.gameRules.BALL_RADIUS ) and \
               me.z < game.ball.z    
    if ( kickBall ):
      action.jump_speed = miscInfo.gameRules.ROBOT_MAX_JUMP_SPEED
    return
コード例 #8
0
def getAimPoint(rules):
  # точка в центре ворот противника, куда целится робод
  px = 0 # obviously
  py = rules.arena.goal_height / 2
  pz = rules.arena.depth / 2
  return Vector3D(px, py, pz)
コード例 #9
0
def doAttack(bot, game, action):

  botVec = Vector2D(bot.x, bot.z)
  ballVec = Vector2D(game.ball.x, game.ball.z)

  # если мяч позади нас, отрабатываем возвращение
  if (bot.z > game.ball.z):
    botControl.pursueBall(bot, game, action)
    return

  prTrajectory = ballPred.getPredictedTrajectory()

  # da cannon shootz!
  enemyBotsVecs = [Vector3D(b.x, b.y, b.z) for b in game.robots if b.is_teammate == False]
  minEnemyDst = min([(Vector3D(game.ball.x, game.ball.y, game.ball.z) - \
                      v).len() for v in enemyBotsVecs])
  
  kickBall = ( bot.z < game.ball.z and
               ( Vector3D(game.ball.x, game.ball.y, game.ball.z) - \
                 Vector3D(bot.x, bot.y, bot.z) ).len() <= \
               ( miscInfo.gameRules.ROBOT_MAX_RADIUS + \
                 miscInfo.gameRules.BALL_RADIUS ) and
               minEnemyDst < 6.0)
  '''
  kickBall = ( bot.z > miscInfo.gameRules.arena.depth / 2 - \
                       miscInfo.gameRules.arena.corner_radius and
               abs(bot.x) < miscInfo.gameRules.arena.goal_width / 2 and
               ( Vector3D(game.ball.x, game.ball.y, game.ball.z) - \
                 Vector3D(bot.x, bot.y, bot.z) ).len() <= \
               ( miscInfo.gameRules.ROBOT_MAX_RADIUS + \
                 miscInfo.gameRules.BALL_RADIUS ) and
               bot.z < game.ball.z and
               game.ball.z - bot.z > 2.0 and
               abs(bot.x - game.ball.x) < 1.0 )
  '''
  
  
  if ( kickBall ):
    #pdb.set_trace()
    action.jump_speed = miscInfo.gameRules.ROBOT_MAX_JUMP_SPEED

  # частный случай - робот вблизи мяча, который катится (не прыгает)
  flatTrajectory = True
  for b in prTrajectory[:30]:
    if ( b.y > miscInfo.gameRules.BALL_RADIUS + 1 ):
      flatTrajectory = False
      break
  if ( flatTrajectory == True and
       (botVec - ballVec).len() < miscInfo.touchDst2d * 2 ):
    # точка удара по мячу
    gateToBallVec = ballVec - \
                    Vector2D(0.0, miscInfo.gameRules.arena.depth / 2 - \
                             miscInfo.gameRules.BALL_RADIUS)
    ballVelocVec = Vector2D(game.ball.velocity_x, game.ball.velocity_z)
    '''
    correctionVec = ( gateToBallVec.normalize() + \
                      ballVelocVec.normalize() * 0.3 ).normalize() * \
                      ( miscInfo.touchDst2d * 0.9 )
    tgtPt = ballVec + correctionVec
    '''
    tgtPt = ballVec + gateToBallVec.normalize() * miscInfo.touchDst2d * 0.5
    botControl.botToPoint(tgtPt, bot, action)
    
    
    return
  

  # общий случай - мяч где-то летает
  ballInterceptionPos = None

  ptsCount = len(prTrajectory)

  for i in range(1, ptsCount - 1):
    if (prTrajectory[i].y < prTrajectory[i-1].y and
        prTrajectory[i].y < prTrajectory[i+1].y):
      ballInterceptionPos = prTrajectory[i]
      break

  if (ballInterceptionPos == None):
    return

  # точка удара по мячу
  ballVelocVec = Vector2D(game.ball.velocity_x, game.ball.velocity_z)
  ballToGateVec = Vector2D(0.0, miscInfo.gameRules.arena.depth / 2 - \
                           miscInfo.gameRules.BALL_RADIUS) - \
                  ballVec
  if ( ballVelocVec.scalarProjectOn(ballToGateVec) <= 0 ):
    correctionVec = ( (Vector2D(0,0) - ballToGateVec).normalize() + \
                      ballVelocVec.normalize() ).normalize() * \
                      ( miscInfo.touchDst2d / 2 )
  else:
    # чет я не уверен
    correctionVec = ( (Vector2D(0,0) - ballToGateVec).normalize() * 2.0 + \
                      ballVelocVec.normalize() ).normalize() * \
                      ( miscInfo.touchDst2d / 2)

  intcptPt = Vector2D(ballInterceptionPos.x + correctionVec.x,
                      ballInterceptionPos.z + correctionVec.z)

  #
  # t = 5 ticks, s = 0.35, v = 8.3
  # t = 10 ticks, s = 1.4, v = 16.6
  
  readyPt = Vector2D(ballInterceptionPos.x, ballInterceptionPos.z) + \
            (Vector2D(0,0) - ballToGateVec).normalize() * \
            (1.0 + miscInfo.touchDst2d)
  if (ballInterceptionPos.tick - game.current_tick > 10):
    botControl.botToPointAndStop(readyPt, bot, action)
  else:
    botControl.botToPoint(intcptPt, bot, action)
コード例 #10
0
    def nextCollision(self, ball):
        # роботов не учитываем, только стены
        # TODO пока не учитываются ворота и все изгибы
        rules = self.rules
        #print('ball.y', ball.y)

        # пользуясь симметрией арены по X и Z, будем считать в рамках одной
        # четверти арены, для чего приведем координаты и скорости

        # TODO не требует ли это вдумчивого рефакторинга?
        #ball = copy.copy(inBall) # TODO REMOVE?
        #print('befor', ball.x,ball.velocity_x)

        signX = 1.0
        if (ball.x < 0):
            signX = -1.0
        signZ = 1.0
        if (ball.z < 0):
            signZ = -1.0

        ball.x = abs(ball.x)
        ball.z = abs(ball.z)
        ball.velocity_x = ball.velocity_x * signX
        ball.velocity_z = ball.velocity_z * signZ

        #print('aftar',ball.x,ball.velocity_x, signX)
        '''
    итого имеем возможные времена пересечения интересующих нас линий:
    txWall
    ty (обрабатывает и пол, и потолок в плоской их части)

    по осям - отражения НЕ происходит!!!
    txAxis
    tzAxis
    '''
        # по X
        xMax = rules.arena.width - rules.BALL_RADIUS
        try:
            txWall = xMax / ball.velocity_x
            #if (tx < 0):
            #print('nextCollision() tx calculation error')
        except ZeroDivisionError:
            txWall = -1

        xMin = 0.0
        try:
            txAxis = xMin / ball.velocity_x
        except ZeroDivisionError:
            txAxis = -1

        # по Z
        zMax = rules.arena.depth - rules.BALL_RADIUS
        zMin = -rules.arena.depth + rules.BALL_RADIUS
        try:
            tz1 = zMin / ball.velocity_z
            tz2 = zMax / ball.velocity_z
            tz = max([tz1, tz2])
            if (tz < 0):
                print('nextCollision() tz calculation error')
        except ZeroDivisionError:
            tz = -1

        # по Y
        if (ball.y - self.rules.BALL_RADIUS <= AXIS_VELOCITY_THRESHOLD
                and abs(ball.velocity_y) <= AXIS_VELOCITY_THRESHOLD):
            # мяч лежит на полу (или катится по полу)
            ty = -1
            #print('vel_y',ball.velocity_y)
        else:
            # есть смысл что-то считать
            yMax = rules.arena.height - rules.BALL_RADIUS
            yMin = rules.BALL_RADIUS
            tys1 = solveSquareEquation(rules.GRAVITY / 2, -ball.velocity_y,
                                       yMin - ball.y)
            tys2 = solveSquareEquation(rules.GRAVITY / 2, -ball.velocity_y,
                                       yMax - ball.y)

            tys1.extend(tys2)
            try:
                ty = min([e for e in tys1 if e > ALLOWED_CALCULATIONS_ERROR])
            except ValueError:
                print('nextCollision() ty calculation error')
                ty = -1

        # в плоскости XY при столкновении с нижним радиусом
        brcX = (rules.arena.width / 2 - rules.arena.bottom_radius)
        # bottom radius center x
        brcY = rules.arena.bottom_radius
        radius = rules.arena.bottom_radius - rules.BALL_RADIUS
        ct4 = rules.GRAVITY**2 / 4
        ct3 = -rules.GRAVITY * ball.velocity_y
        ct2 = rules.GRAVITY * brcY - \
              rules.GRAVITY * ball.y + \
              ball.velocity_x ** 2 + \
              ball.velocity_y ** 2
        ct = - 2 * ball.velocity_x * brcX + \
             2 * ball.velocity_x * ball.x - \
             2 * ball.velocity_y * brcY + \
             2 * ball.velocity_y * ball.y
        c = - radius ** 2 + \
            brcX ** 2 - \
            2 * brcX * ball.x + \
            ball.x ** 2 + \
            brcY ** 2 - \
            2 * brcY * ball.y + \
            ball.y ** 2
        txys = solvePower4Equation(ct4, ct3, ct2, ct, c)
        txys = [ttc for ttc in txys if ttc > ALLOWED_CALCULATIONS_ERROR]
        xyBallStates = [self.predictedBallWoColls(ball, ttc) for ttc in txys]
        print(txys)
        filteredTxys = []
        for i in range(len(txys)):

            if (xyBallStates[i].x > brcX and xyBallStates[i].y < brcY):
                filteredTxys.append(txys[i])

                b = xyBallStates[i]
                print('state', b.x, b.y, b.z)
        #txys = filteredTxys
        try:
            txy = min(filteredTxys)
        except ValueError:
            txy = -1

        try:
            timeToColl = min([e for e in [txWall, ty, tz, txy] if e > 0])
        except ValueError:
            # не можем посчитать ни одну коллизию - сильно похоже на то, что мяч
            # просто лежит на полу
            #print('nextCollision() collision time calculation error: assuming ball is not moving')

            #print([tx, ty, tz])
            #print(ball.x, ball.y, ball.z)
            #print(ball.velocity_x, ball.velocity_y, ball.velocity_z)
            newBall = copy.copy(ball)
            #print(newBall.y)
            #newBall.velocity_y = 0.0
            return (1.0, newBall)
        #print('t', timeToColl)

        #b = ball
        #print('b', b.x, b.velocity_x)
        newBall = self.predictedBallWoColls(ball, timeToColl)
        #b = newBall
        #print('nb', b.x, b.velocity_x)

        # пересчитать скорости в newBall
        # для чего сначала получить нормаль к поверхности
        if (timeToColl == txWall):
            print('onxW')
            newBall.velocity_x = -0.7 * newBall.velocity_x
            # по Z и Y - без изменений
        elif (timeToColl == tz):
            print('onz')
            newBall.velocity_z = -0.7 * newBall.velocity_z
            # по Y и X - без изменений
        elif (timeToColl == txy):
            print('onxy')
            bVel = Vector3D(newBall.velocity_x, newBall.velocity_y,
                            newBall.velocity_z)
            normal = Vector3D(ball.x - brcX, ball.y - brcY, 0)
            bVelNorm = bVel.projectOn(normal)
            bVelOrto = bVel - bVelNorm
            bVelNorm = Vector3D(0.0, 0.0, 0.0) - bVelNorm * rules.BALL_ARENA_E
            bVel = bVelNorm + bVelOrto

            newBall.velocity_x = bVel.x
            newBall.velocity_y = bVel.y
            newBall.velocity_z = bVel.z

        else:  #( timeToColl == ty):
            print('ony')
            newBall.velocity_y = -0.7 * newBall.velocity_y
            # по Z и X - без изменений

        # не забываем обратно поменять знак
        newBall.x = newBall.x * signX
        newBall.z = newBall.z * signZ
        newBall.velocity_x = newBall.velocity_x * signX
        newBall.velocity_z = newBall.velocity_z * signZ

        #print('new vel_y',newBall.velocity_y)

        return (timeToColl, newBall)
コード例 #11
0
def distanceBetweenCenters(entity1, entity2):
    # расстояние между роботом и мячом (или двумя роботами)
    rVec1 = Vector3D(entity1.x, entity1.y, entity1.z)
    rVec2 = Vector3D(entity2.x, entity2.y, entity2.z)
    return (rVec2 - rVec1).len()
コード例 #12
0
    def distanceToArenaQuarter(self, point):
        arena = self.rules.arena

        # element for comparison
        def dstCompEl(e):
            return e[0]

        # Ground
        dst = distanceToPlane(point, Vector3D(0, 0, 0), Vector3D(0, 1, 0))
        # Ceiling
        dst = min(dst,
                  distanceToPlane(point, Vector3D(0, arena.height, 0),
                                  Vector3D(0, -1, 0)),
                  key=dstCompEl)
        # X side
        dst = min(dst,
                  distanceToPlane(point, Vector3D(self.halfWidth, 0, 0),
                                  Vector3D(-1, 0, 0)),
                  key=dstCompEl)
        # Z side, goal area
        dst = min(dst,
                  distanceToPlane(
                      point, Vector3D(0, 0, self.halfDepth + arena.goal_depth),
                      Vector3D(0, 0, -1)),
                  key=dstCompEl)
        # Z side
        v = Vector2D(point.x, point.y) - \
            Vector2D(arena.goal_width / 2 - arena.goal_top_radius,
                     arena.goal_height - arena.goal_top_radius)
        if (point.x >= arena.goal_width / 2 + arena.goal_side_radius
                or point.y >= arena.goal_height + arena.goal_side_radius or
            (v.x > 0 and v.z > 0
             and v.len() >= arena.goal_top_radius + arena.goal_side_radius)):
            dst = min(dst,
                      distanceToPlane(point, Vector3D(0, 0, self.halfDepth),
                                      Vector3D(0, 0, -1)),
                      key=dstCompEl)
        # Goal X side and Ceiling
        if (point.z >= self.halfDepth + arena.goal_side_radius):
            # X side
            dst = min(dst,
                      distanceToPlane(point, Vector3D(self.halfWidth, 0, 0),
                                      Vector3D(-1, 0, 0)),
                      key=dstCompEl)
            # Y side
            dst = min(dst,
                      distanceToPlane(point, Vector3D(0, arena.goal_height, 0),
                                      Vector3D(0, -1, 0)),
                      key=dstCompEl)
        # Goal back corners
        if (point.z > self.halfDepth + arena.goal_depth - arena.bottom_radius):
            dst = min(dst,
                      distanceToSphereInner(
                          point,
                          Vector3D(
                              clamp(point.x,
                                    arena.bottom_radius - self.halfWidth,
                                    self.halfWidth - arena.bottom_radius),
                              clamp(point.y, arena.bottom_radius,
                                    arena.goal_height - arena.goal_top_radius),
                              self.halfDepth + arena.goal_depth -
                              arena.bottom_radius), arena.bottom_radius),
                      key=dstCompEl)
        # Corner
        if (point.x > self.halfWidth - arena.corner_radius
                and point.z > self.halfDepth - arena.corner_radius):
            dst = min(dst,
                      distanceToSphereInner(
                          point,
                          Vector3D(self.halfWidth - arena.corner_radius,
                                   point.y,
                                   self.halfDepth - arena.corner_radius),
                          arena.corner_radius),
                      key=dstCompEl)
        # Goal outer corner
        if (point.z < self.halfDepth + arena.goal_side_radius):
            # X side
            if (point.x < self.halfWidth + arena.goal_side_radius):
                dst = min(dst,
                          distanceToSphereOuter(
                              point,
                              Vector3D(self.halfWidth + arena.goal_side_radius,
                                       point.y, self.halfDepth +
                                       arena.goal_side_radius),
                              arena.goal_side_radius),
                          key=dstCompEl)
            # Ceiling
            if (point.y < arena.goal_height + arena.goal_side_radius):
                dst = min(dst,
                          distanceToSphereOuter(
                              point,
                              Vector3D(
                                  point.x,
                                  arena.goal_height + arena.goal_side_radius,
                                  self.halfDepth + arena.goal_side_radius),
                              arena.goal_side_radius),
                          key=dstCompEl)
            # Top corner
            o = Vector2D(self.halfWidth - arena.goal_top_radius,
                         arena.goal_height - arena.goal_top_radius)
            v = Vector2D(point.x, point.y) - o
            if (v.x > 0 and v.z > 0):
                o = o + v.normalize() * (arena.goal_top_radius +
                                         arena.goal_side_radius)
                dst = min(dst,
                          distanceToSphereOuter(
                              point,
                              Vector3D(o.x, o.z, self.halfDepth +
                                       arena.goal_side_radius),
                              arena.goal_side_radius),
                          key=dstCompEl)
        # Goal inside top corners
        if (point.z > self.halfDepth + arena.goal_side_radius
                and point.y > arena.goal_height - arena.goal_top_radius):
            # X side
            if (point.x > self.halfWidth - arena.goal_top_radius):
                dst = min(dst,
                          distanceToSphereInner(
                              point,
                              Vector3D(
                                  self.halfWidth - arena.goal_top_radius,
                                  arena.goal_height - arena.goal_top_radius,
                                  point.z), arena.goal_top_radius),
                          key=dstCompEl)
            # Z side
            if (point.z >
                    self.halfDepth + arena.goal_depth - arena.goal_top_radius):
                dst = min(dst,
                          distanceToSphereInner(
                              point,
                              Vector3D(
                                  point.x,
                                  arena.goal_height - arena.goal_top_radius,
                                  self.halfDepth + arena.goal_depth -
                                  arena.goal_top_radius),
                              arena.goal_top_radius),
                          key=dstCompEl)
        # Bottom corners
        if (point.y < arena.bottom_radius):
            # X side
            if (point.x > self.halfWidth - arena.bottom_radius):
                dst = min(dst,
                          distanceToSphereInner(
                              point,
                              Vector3D(self.halfWidth - arena.bottom_radius,
                                       arena.bottom_radius, point.z),
                              arena.bottom_radius),
                          key=dstCompEl)
            # Z side
            if (point.z > self.halfDepth - arena.bottom_radius
                    and point.x >= self.halfWidth + arena.goal_side_radius):
                dst = min(dst,
                          distanceToSphereInner(
                              point,
                              Vector3D(point.x, arena.bottom_radius,
                                       self.halfDepth - arena.bottom_radius),
                              arena.bottom_radius),
                          key=dstCompEl)
            # Z side (goal)
            if (point.z >
                    self.halfDepth + arena.goal_depth - arena.bottom_radius):
                dst = min(dst,
                          distanceToSphereInner(
                              point,
                              Vector3D(
                                  point.x, arena.bottom_radius,
                                  self.halfDepth + arena.goal_depth -
                                  arena.bottom_radius), arena.bottom_radius),
                          key=dstCompEl)
            # Goal outer corner
            o = Vector2D(self.halfWidth + arena.goal_side_radius,
                         self.halfDepth + arena.goal_side_radius)
            v = Vector2D(point.x, point.z) - o
            if (v.x < 0 and v.z < 0 and
                    v.len() < arena.goal_side_radius + arena.bottom_radius):
                o = o + v.normalize() * (arena.goal_side_radius +
                                         arena.bottom_radius)
                dst = min(dst,
                          distanceToSphereInner(
                              point, Vector3D(o.x, arena.bottom_radius, o.z),
                              arena.bottom_radius),
                          key=dstCompEl)
            # X side (goal)
            if (point.z >= self.halfDepth + arena.goal_side_radius
                    and point.x > self.halfWidth - arena.bottom_radius):
                dst = min(dst,
                          distanceToSphereInner(
                              point,
                              Vector3D(self.halfWidth - arena.bottom_radius,
                                       arena.bottom_radius, point.z),
                              arena.bottom_radius),
                          key=dstCompEl)
            # Corner
            if (point.x > self.halfWidth - arena.corner_radius
                    and point.z > self.halfDepth - arena.corner_radius):
                corner_o = Vector2D(self.halfWidth - arena.corner_radius,
                                    self.halfDepth - arena.corner_radius)
                n = Vector2D(point.x, point.z) - corner_o
                dist = n.len()
                if (dist > arena.corner_radius - arena.bottom_radius):
                    n = n / dist
                    o2 = corner_o + n * (arena.corner_radius -
                                         arena.bottom_radius)
                    dst = min(dst,
                              distanceToSphereInner(
                                  point,
                                  Vector3D(o2.x, arena.bottom_radius, o2.z),
                                  arena.bottom_radius),
                              key=dstCompEl)
        # Ceiling corners
        if (point.y > arena.height - arena.top_radius):
            # X side
            if (point.x > self.halfWidth - arena.top_radius):
                dst = min(dst,
                          distanceToSphereInner(
                              point,
                              Vector3D(self.halfWidth - arena.top_radius,
                                       arena.height - arena.top_radius,
                                       point.z), arena.top_radius),
                          key=dstCompEl)
            # Z side
            if (point.z > self.halfDepth - arena.top_radius):
                dst = min(dst,
                          distanceToSphereInner(
                              point,
                              Vector3D(point.x,
                                       arena.height - arena.top_radius,
                                       self.halfDepth - arena.top_radius),
                              arena.top_radius),
                          key=dstCompEl)
            # Corner
            if (point.x > self.halfWidth - arena.corner_radius
                    and point.z > self.halfDepth - arena.corner_radius):
                corner_o = Vector2D(self.halfWidth - arena.corner_radius,
                                    self.halfDepth - arena.corner_radius)
                dv = Vector2D(point.x, point.z) - corner_o
                if (dv.len() > arena.corner_radius - arena.top_radius):
                    n = dv.normalize()
                    o2 = corner_o + n * (arena.corner_radius -
                                         arena.top_radius)
                    dst = min(dst,
                              distanceToSphereInner(
                                  point,
                                  Vector3D(o2.x,
                                           arena.height - arena.top_radius,
                                           o2.z), arena.top_radius),
                              key=dstCompEl)
        return dst
コード例 #13
0
#traced = list(range(45, 196))
#traced.extend(list(range(370, 469)))

for e in gameLog[1:]:
    ball = ballFromLog(e['ball'])
    gameStub = GameStub()
    gameStub.ball = ball
    gameStub.current_tick = e['current_tick']

    trajectory = ballPred.getPredictedTrajectory()

    found = False
    for b in trajectory:
        if (b.tick == e['current_tick']):
            found = True
            delta = (Vector3D(b.x, b.y, b.z) -
                     Vector3D(ball.x, ball.y, ball.z)).len()
            break

    if (found == False):
        print('tick', e['current_tick'], 'NOT FOUND')
    if (delta > ALLOWED_POSITION_DIVERGENCE):
        print(e['current_tick'], 'LARGE DIVERGENCE')
    if (e['current_tick'] in traced):
        print(e['current_tick'], 'DELTA', delta)
    ballPred.update(gameStub)

# total calculs!
'''
  ballPred.update(gameStub)
  ticks = e['current_tick'] - basicMoment['current_tick']