示例#1
0
function recalculateTarget() { //this is all our example logic
    var candidate_ball = null; //first we don't have candidate to eat
    var candidate_distance = 0;
    var my_ball = client.balls[ client.my_balls[0] ]; //we get our first ball. We don't care if there more then one, its just example.
    if(!my_ball) return; //if our ball not spawned yet then we abort. We will come back here in 100ms later

    for(var ball_id in client.balls) { //we go through all balls we know about
        var ball = client.balls[ball_id];
        if(ball.virus) continue; //if ball is a virus (green non edible thing) then we skip it
        if(!ball.visible) continue; //if ball is not on our screen (field of view) then we skip it
        if(ball.mine) continue; //if ball is our ball - then we skip it
        if(ball.isMyFriend()) continue; //this is my friend, ignore him (implemented by custom property)
        if(ball.size/my_ball.size > 0.5) continue; //if ball is bigger than 50% of our size - then we skip it
        var distance = getDistanceBetweenBalls(ball, my_ball); //we calculate distances between our ball and candidate
        if(candidate_ball && distance > candidate_distance) continue; //if we do have some candidate and distance to it smaller, than distance to this ball, we skip it

        candidate_ball = ball; //we found new candidate and we record him
        candidate_distance = getDistanceBetweenBalls(ball, my_ball); //we record distance to him to compare it with other balls
    }
    if(!candidate_ball) return; //if we didn't find any candidate, we abort. We will come back here in 100ms later

    client.log('closest ' + candidate_ball + ', distance ' + candidate_distance);
    client.moveTo(candidate_ball.x, candidate_ball.y); //we send move command to move to food's coordinates
}
const onTick = () => {
  if (roundsToSkip > 0) {
    roundsToSkip -= 1;
    return;
  }
  const startTime = Date.now();
  const state = getCurrentState();
  if (!_.isObject(state)) {
    if (_.isNumber(prevScore)) {
      console.log("---------------Dead, reward: " + (-prevScore) + "--------------");
      agent.learn(-prevScore);
      //clear experience
      agent.exp = []; // experience
      agent.expi = 0; // where to insert
      agent.t = 0;
    }
    prevScore = null;
    return;
  }
  const reward = _.isNumber(prevScore) ? state.score - prevScore : null;
  if (_.isNumber(reward)) {
    //agent.learn(reward);
  }

  const velocity = _.isObject(prevPos) ? new Vec(state.me.pAvg.x - prevPos.x, state.me.pAvg.y - prevPos.x) : new Vec(0,0);
  const prevPos = state.me.pAvg;
  let action;
  let xPot = 0;
  let yPot = 0;
  _.forEach(state.sensorDetections, (sd, i) => {
    const s = sensors[i].normalizeClone();
    if (sd.targetType === targetTypes.CELL) {
      if (sd.targetSize < state.me.size) {
        xPot += sd.targetSize/(sd.dist * sd.dist) * s.x;
        yPot += sd.targetSize/(sd.dist * sd.dist) * s.y;
      } else {
        xPot -= sd.targetSize/(sd.dist * sd.dist) * s.x;
        yPot -= sd.targetSize/(sd.dist * sd.dist) * s.y;
      }
    } else if (sd.targetType === targetTypes.VIRUS && sd.targetSize + 50 < state.me.totalSize && state.me.totalBalls === 1) {
        xPot -= sd.targetSize/(sd.dist * sd.dist) * s.x;
        yPot -= sd.targetSize/(sd.dist * sd.dist) * s.y;
    }
  });
  let wDist = state.me.pAvg.x - map.minX;
  if (wDist < 500) {
    xPot -= 5/(wDist * wDist);
  }
  wDist = map.maxX - state.me.pAvg.x;
  if (wDist < 500) {
    xPot += 5/(wDist * wDist);
  }

  wDist = state.me.pAvg.y - map.minY;
  if (wDist < 500) {
    yPot -= 5/(wDist * wDist);
  }
  wDist = map.maxY - state.me.pAvg.y;
  if (wDist < 500) {
    yPot += 30/(wDist * wDist);
  }

  if (Math.abs(xPot) > Math.abs(yPot)) {
    if (xPot > 0) {
      action = actionTypes.LEFT;
    } else {
      action = actionTypes.RIGHT;
    }
  } else {
    if (yPot > 0) {
      action = actionTypes.DOWN;
    } else {
      action = actionTypes.UP;
    }
  }
  let moveTo;
  if (Math.abs(xPot) < 0.0001 && Math.abs(yPot) < 0.0001) {
    roundsToSkip = 10;
    action = 3 - Math.floor(Math.random() * 4);
  }

  if (Math.random() > prob) {
    action = 3 - Math.floor(Math.random() * 4);
    roundsToSkip = 0;
  }

  //const action = agent.act(serialize(state, velocity));
  if (action === actionTypes.UP) {
    moveTo = new Vec(state.me.pAvg.x, state.me.pAvg.y + 500);
  } else if (action === actionTypes.RIGHT) {
    moveTo = new Vec(state.me.pAvg.x + 500, state.me.pAvg.y);
  } else if (action === actionTypes.DOWN) {
    moveTo = new Vec(state.me.pAvg.x, state.me.pAvg.y - 500);
  } else if (action === actionTypes.LEFT) {
    moveTo = new Vec(state.me.pAvg.x - 500, state.me.pAvg.y);
  }
  client.moveTo(moveTo.x, moveTo.y);
  const closest = _.min(state.sensorDetections, (sd) => sd.dist);
  console.log({
    action: action,
    reward: reward,
    time: Date.now() - startTime,
    dist: closest.dist
  });
  prevScore = state.score;
};