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; };