Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var api = require('./API.js');
- /* Configuration */
- var verbose = false;
- var avatars = ["▲","◄","▼","►"];
- var icon = {
- target: "x",
- obstacle_unknown: "▒",
- obstacle_wall: "▓",
- unknown: "░",
- empty: " "
- };
- /** FRMEWORK **/
- /* Robot data */
- // Tank object default conditions
- var tank = {
- max_range: 4, // Maximum shooting distance. Long shots can miss moving targets and waste time
- // ezpz GPS
- lidar: { front: 0, back: 0, left: 0, right: 0 },
- o_lidar: { up: 0, down: 0, left: 0, right: 0 }, // lidar information aligned to map's u/d/l/r
- lidar_object: { front: false, back: false, left: false, right: false },
- traveled: { o_up: 0, o_down: 0, o_left: 0, o_right: 0 },
- status: {},
- rotation: 0,
- coords: [0, 0], // 0,0 = top left
- x: 0,
- y: 0
- };
- tank.reset = function(){
- tank.status = {
- turning_around: false,
- shots_fired: tank.status.shots_fired || 0,
- shots_fired_in_a_row: 0,
- ticks: tank.status.ticks || 0,
- tick: { action_done: false },
- directive: { active: false, name: false, direction: false, distance: 0, steps: 0 },
- combat: { active: false, time_since_last_shot: 0,
- chasing: false, chase_remaining: false, chase_target_seen_count: 0, last_shot_range: 0
- }
- };
- tank.expected_lidar = { front: false, back: false, left: false, right: false };
- }
- tank.reset();
- tank.directives = ["explore", "explore_half", "investigate"];
- // Map object default conditions
- var map = Array("");
- var map_mins = [1,1];
- /* Mapping functions */
- function build_map(){
- notice("Updating map.");
- lidars = [tank.lidar.front, tank.lidar.left, tank.lidar.back, tank.lidar.right];
- r = tank.rotation;
- o_up = lidars[(4 - r) % 4];
- o_left = lidars[(5 - r) % 4];
- o_down = lidars[(6 - r) % 4];
- o_right = lidars[(7 - r) % 4];
- tank.o_lidar = {up: o_up, down: o_down, left: o_left, right: o_right };
- y = tank.coords[1];
- x = tank.coords[0];
- h = (o_up > y ? o_up : y) + 1 + (map.length - y -1 > o_down ? map.length - y - 1 : o_down);
- w = (o_left > x ? o_left : x) + 1 + (map[0].length - x - 1 > o_right ? map[0].length - x - 1 : o_right);
- if(map_mins[0] < w) map_mins[0] = w;
- if(map_mins[1] < h) map_mins[1] = h;
- increase_map_if_needed(h, w, o_up, o_down, o_right, o_left);
- ray_trace(o_up, o_down, o_right, o_left);
- }
- function increase_map_if_needed(h, w, o_up, o_down, o_right, o_left){
- if(map.length >= h && map[0].length >= w) return;
- x = tank.coords[0];
- y = tank.coords[1];
- m_height = map.length;
- m_width = map[0].length;
- y_pos = y_neg = x_pos = x_neg = 0;
- if(m_height < h){
- if(y < o_up) y_pos = o_up - y;
- if(y_pos + m_height < h) y_neg = h - y_pos - m_height;
- }
- if(m_width < w){
- if(x < o_left) x_neg = o_left - x;
- if(x_neg + m_width < w) x_pos = w - x_neg - m_width;
- }
- subnotice("Increase internal map size from [" + map[0].length + ", " + map.length +"] to [" + w + ", " + h + "] by adding " +
- "[x+:" + x_pos + ", x-:" + x_neg + ", y+:" + y_pos + ", y-:" + y_neg + "]");
- increase_map(y_pos, y_neg, x_pos, x_neg);
- tank.coords[0] = x + x_neg;
- tank.coords[1] = y + y_pos;
- }
- function increase_map(y_pos, y_neg, x_pos, x_neg){
- // Pad existing rows with additional width and height
- for(var row = 0; row < map.length; row++){
- map[row] = Array(x_neg+1).join(icon.unknown) + map[row] + Array(x_pos+1).join(icon.unknown);
- }
- // Add new rows to the top
- for(var higher = 0; higher < y_pos; higher++){ map.unshift(new_row()); }
- // Add new rows to the bottom
- for(var lower = 0; lower < y_neg; lower++){ map.push(new_row()); }
- }
- function ray_trace(o_up, o_down, o_right, o_left){
- x = tank.coords[0];
- y = tank.coords[1];
- // Redraw our horizontal row
- splice(y, x - o_left, icon_for(x-o_left,y) + empty(o_left) + avatars[tank.rotation] + empty(o_right) + icon_for(x+o_right,y), x+o_right+1);
- // Redraw our verticals
- for(var row_up = y-1; row_up > y-o_up; row_up--){ map[row_up] = map[row_up].substring(0,x) + icon.empty + map[row_up].substring(x+1); }
- splice(y-o_up, x, icon_for(x,y-o_up), x+1);
- for(var row_down = y+1; row_down < y+o_down; row_down++){ map[row_down] = map[row_down].substring(0,x) + icon.empty + map[row_down].substring(x+1); }
- splice(y+o_down, x, icon_for(x,y+o_down), x+1);
- // Identify ahead
- ends = [[x,y-o_up],[x-o_left,y],[x,y+o_down],[x+o_right,y]][tank.rotation];
- splice(ends[1], ends[0], api.identifyTarget() ? icon.target : icon.obstacle_wall, ends[0]+1);
- }
- /* Utility functions */
- function icon_for(x,y){
- v = map[y].substr(x,1);
- if(v == icon.obstacle_wall) return v;
- if(v == icon.target) return v;
- return icon.obstacle_unknown;
- }
- function empty(length){
- return Array(length).join(icon.empty);
- }
- function splice(row, x1, new_text, x2){
- map[row] = map[row].substring(0,x1) + new_text + map[row].substring(x2);
- }
- function new_row(){
- return Array(map_mins[0]+1).join(icon.unknown);
- }
- function warn(msg){ console.log("╞ " + msg); }
- function notice(msg){ if(verbose) console.log("├ " + msg); }
- function subnotice(msg){ if(verbose) console.log("│\t└────\t" + msg); }
- function subsubnotice(msg){ if(verbose) console.log("│\t\t└────\t" + msg); }
- function act(msg){ console.log("▌ " + msg); }
- function alt_subnotice(msg){ if(verbose) console.log("│\t\t"+ msg); }
- function tank_stats(){
- notice("Tank Stats:\tFuel: "+api.currentFuel()+", Target ahead? "+(api.identifyTarget()?"Yes":"No"));
- alt_subnotice("Rotation: "+avatars[tank.rotation]+" ("+tank.rotation+")");
- alt_subnotice("Lidar: ^:"+tank.lidar.front+" v:"+tank.lidar.back+" <:"+tank.lidar.left+" >:"+tank.lidar.right);
- alt_subnotice("Aligned*: "+avatars[0]+":"+o_up+" "+avatars[1]+":" + o_down + " "+avatars[2]+":" + o_left + " "+avatars[3]+":" + o_right);
- alt_subnotice("Expected: ^:"+tank.expected_lidar.front+" v:"+tank.expected_lidar.back+" <:"+tank.expected_lidar.left+" >:"+tank.expected_lidar.right);
- alt_subnotice("Travled: "+avatars[0]+":"+tank.traveled.o_up+" "+avatars[1]+":"+tank.traveled.o_down+" "+avatars[2]+":"+tank.traveled.o_left+" "+avatars[3]+":"+tank.traveled.o_right);
- }
- function map_stats(){
- notice("Map Stats:\tTank "+avatars[tank.rotation]+" @["+tank.coords[0]+", "+
- tank.coords[1]+"], Map size ["+map[0].length+", "+map.length+"] (top left is 0,0)");
- map.forEach(function(row){ alt_subnotice(row); });
- }
- /* Tank functions */
- // Simple Actions
- tank.sense = function(){
- tank.scan();
- if(api.identifyTarget()){
- subnotice("Scanning target: Enemy!")
- tank.status.combat.active = true;
- } else {
- subnotice("Scanning target: Clear.")
- }
- build_map();
- tank.update_coords();
- }
- tank.scan = function(){
- notice("Running lidar scans.");
- tank.lidar.front = api.lidarFront();
- tank.lidar.back = api.lidarBack();
- tank.lidar.left = api.lidarLeft();
- tank.lidar.right = api.lidarRight();
- }
- tank.forward = function(){
- if(api.lidarFront() <= 1 || tank.status.tick.action_done) return;
- act("DRIVING FORWARD");
- if( tank.rotation===0) { tank.coords[1]--; tank.traveled.o_up++; }
- else if(tank.rotation==1) { tank.coords[0]--; tank.traveled.o_left++; }
- else if(tank.rotation==2) { tank.coords[1]++; tank.traveled.o_down++; }
- else if(tank.rotation==3) { tank.coords[0]++; tank.traveled.o_right++; }
- tank.expected_lidar.back = tank.lidar.back + 1;
- tank.expected_lidar.left = tank.expected_lidar_to_front_left();
- tank.expected_lidar.right = tank.expected_lidar_to_front_right();
- api.moveForward();
- tank.status.tick.action_done = true;
- tank.status.shots_fired_in_a_row = 0;
- }
- tank.backward = function(){
- if(api.lidarBack() <= 1 || tank.status.tick.action_done) return;
- act("DRIVING BACKWARD");
- if( tank.rotation===0) { tank.coords[1]++; tank.traveled.o_down++; }
- else if(tank.rotation==1) { tank.coords[0]++; tank.traveled.o_right++; }
- else if(tank.rotation==2) { tank.coords[1]--; tank.traveled.o_up++; }
- else if(tank.rotation==3) { tank.coords[0]--; tank.traveled.o_left++; }
- tank.expected_lidar.back = tank.lidar.back - 1;
- tank.expected_lidar.left = tank.expected_lidar_to_back_left();
- tank.expected_lidar.right = tank.expected_lidar_to_back_right();
- api.moveBackward();
- tank.status.tick.action_done = true;
- tank.status.shots_fired_in_a_row = 0;
- }
- tank.turn_left= function(){
- if(tank.status.tick.action_done) return;
- act("TURNING LEFT");
- tank.rotation++;
- if(tank.rotation > 3) tank.rotation = 0;
- tank.expected_lidar.back = tank.lidar.right;
- tank.expected_lidar.right = tank.lidar.front;
- tank.expected_lidar.left = tank.lidar.back;
- api.turnLeft();
- tank.status.tick.action_done = true;
- tank.status.shots_fired_in_a_row = 0;
- }
- tank.turn_right= function(){
- if(tank.status.tick.action_done) return;
- act("TURNING RIGHT");
- tank.rotation--;
- if(tank.rotation < 0) tank.rotation = 3;
- tank.expected_lidar.back = tank.lidar.left;
- tank.expected_lidar.left = tank.lidar.front;
- tank.expected_lidar.right = tank.lidar.back;
- api.turnRight();
- tank.status.tick.action_done = true;
- tank.status.shots_fired_in_a_row = 0;
- }
- tank.shoot = function(){
- if(tank.status.tick.action_done) return;
- act("FIRING CANON");
- api.fireCannon();
- tank.status.tick.action_done = true;
- tank.status.combat.time_since_last_shot = 0;
- tank.status.shots_fired_in_a_row++;
- tank.status.combat.last_shot_range = tank.lidar.front;
- }
- // Special Actions
- tank.start_turning_around = function(){
- subnotice("Turning around (1/2)");
- tank.status.turning_around = true;
- tank.turn_right();
- };
- tank.finish_turning_around = function(){
- if(!tank.status.turning_around){ warn("Warning! Trying to finish a turn we never started!"); return; }
- subnotice("Still turning around (2/2)");
- tank.status.turning_around = false;
- tank.turn_right();
- };
- tank.turn_towards = function(rotation){
- if(tank.rotation == rotation) return;
- if(rotation !== 0 && rotation != 1 && rotation != 2 && rotation != 3) return;
- subnotice("Turning to from " + avatars[tank.rotation] + " to face " + avatars[rotation]);
- if(tank.rotation === 0){
- if(rotation == 1){ tank.turn_left(); }
- else if(rotation == 2){ tank.start_turning_around(); }
- else{ tank.turn_right(); }
- } else if(tank.rotation == 1){
- if(rotation === 0){ tank.turn_right(); }
- else if(rotation == 2){ tank.turn_left(); }
- else{ tank.start_turning_around(); }
- } else if(tank.rotation == 2){
- if(rotation === 0){ tank.start_turning_around(); }
- else if(rotation == 1){ tank.turn_right(); }
- else{ tank.turn_left(); }
- } else {
- if(rotation === 0){ tank.turn_left(); }
- else if(rotation == 1){ tank.start_turning_around(); }
- else{ tank.turn_right(); }
- }
- };
- tank.turn_towards_closest_unknown_ping = function(){
- r_dist = tank.lidar_object.right == icon.obstacle_wall ? false : tank.lidar.right;
- l_dist = tank.lidar_object.left == icon.obstacle_wall ? false : tank.lidar.left;
- b_dist = tank.lidar_object.back == icon.obstacle_wall ? false : tank.lidar.back;
- if(r_dist == l_dist && l_dist == b_dist && b_dist === false){ subnotice("All pings are known walls."); return; }
- subnotice("Turning towards the closest unidentified ping.");
- opts = [[function(){tank.turn_right()},r_dist], [function(){tank.turn_left()},l_dist],[function(){tank.start_turning_around()},b_dist]];
- opts.sort(function(a,b){
- return (a[1] === false ?
- (b[1] === false ? 0 : 1) :
- (b[1] === false ? -1 : (a[1] > b[1] ? 1 : (a[1] == b[1] ? 0 : -1)))
- );
- });
- return opts[0][0]();
- }
- tank.turn_towards_unexpected_pings = function(){
- dir = tank.unexpected_ping_direction();
- r_dir = tank.relative_to_rotation(dir);
- if(dir===false) return;
- tank.reset();
- tank.status.directive.active = true;
- tank.status.directive.name = "investigate";
- tank.status.directive.distance = tank.rotation_to_lidar(r_dir)
- tank.status.directive.direction =r_dir;
- return tank.turn_towards(r_dir);
- }
- // Response Actions
- tank.unexpected_ping_direction = function(){
- subnotice("Calculating direction of closest unexpected ping.");
- alerts = [];
- if(tank.expected_lidar.right && tank.expected_lidar.right > tank.lidar.right){
- alerts.push([3, tank.expected_lidar.right, tank.lidar.right]);
- }
- if(tank.expected_lidar.left && tank.expected_lidar.left > tank.lidar.left){
- alerts.push([1, tank.expected_lidar.left, tank.lidar.left]);
- }
- if(tank.expected_lidar.back && tank.expected_lidar.back > tank.lidar.back){
- alerts.push([2, tank.expected_lidar.back, tank.lidar.back]);
- }
- if(alerts.length == 0){
- subnotice("No unexpected pings.");
- return false;
- }
- alerts = alerts.sort(function(a,b){return a[2] == b[2] ? (a[2] < b[2] ? -1 : 1) : 0});
- subnotice("Unexpected object to the " + avatars[tank.relative_to_rotation(alerts[0][0])] + " (expected: " + alerts[0][1] + ", was: " + alerts[0][2] + ")");
- return alerts[0][0];
- }
- tank.turn_towards_biggest_open_direction = function(){
- subnotice("Turning towards the largest open direction.");
- return tank.turn_towards(tank.biggest_open_direction());
- }
- // Values
- tank.expected_lidar_to_front_left = function(){
- if(tank.rotation == 0) return tank.expected_lidar_from_row(tank.y-1, 0, tank.x);
- if(tank.rotation == 1) return tank.expected_lidar_from_col(tank.x-1, tank.y, map.length);
- if(tank.rotation == 2) return tank.expected_lidar_from_row(tank.y+1, map[0].length, tank.x+1);
- if(tank.rotation == 3) return tank.expected_lidar_from_col(tank.x+1, tank.y, 0);
- }
- tank.expected_lidar_to_front_right = function(){
- if(tank.rotation == 0) return tank.expected_lidar_from_row(tank.y-1, map[0].length, tank.x+1);
- if(tank.rotation == 1) return tank.expected_lidar_from_col(tank.x-1, 0, tank.y);
- if(tank.rotation == 2) return tank.expected_lidar_from_row(tank.y+1, 0, tank.x);
- if(tank.rotation == 3) return tank.expected_lidar_from_col(tank.x+1, map.length, tank.y);
- }
- tank.expected_lidar_to_back_left = function(){
- if(tank.rotation == 0) return tank.expected_lidar_from_row(tank.y+1, 0, tank.x);
- if(tank.rotation == 1) return tank.expected_lidar_from_col(tank.x+1, tank.y, map.length);
- if(tank.rotation == 2) return tank.expected_lidar_from_row(tank.y-1, map[0].length, tank.x+1);
- if(tank.rotation == 3) return tank.expected_lidar_from_col(tank.x-1, tank.y, 0);
- }
- tank.expected_lidar_to_back_right = function(){
- if(tank.rotation == 0) return tank.expected_lidar_from_row(tank.y+1, map[0].length, tank.x+1);
- if(tank.rotation == 1) return tank.expected_lidar_from_col(tank.x+1, 0, tank.y);
- if(tank.rotation == 2) return tank.expected_lidar_from_row(tank.y-1, 0, tank.x);
- if(tank.rotation == 3) return tank.expected_lidar_from_col(tank.x-1, map.length, tank.y);
- }
- tank.expected_lidar_from_row = function(row, left, right){
- chunk = map[row].substring(right, left);
- if(left < right) chunk = chunk.split('').reverse().join('');
- unknown_pings = chunk.indexOf(icon.obstacle_unknown)+1;
- walls = chunk.indexOf(icon.obstacle_wall)+1;
- unknowns = chunk.indexOf(icon.unknown)+1;
- if(unknowns > 0){
- if(unknowns < unknown_pings && unknowns < walls) return false;
- }
- if(unknown_pings > 0){
- return unknown_pings < walls ? unknown_pings : (walls > 0 ? walls : unknown_pings);
- }
- return false;
- }
- tank.expected_lidar_from_col = function(col, top, bottom){
- return false;
- }
- tank.icon_at_rotation = function(rotation){
- return [tank.lidar_object.front, tank.lidar_object.left, tank.lidar_object.back, tank.lidar_object.right][tank.rotation_to_relative(rotation)];
- }
- tank.icon_at = function(rotation){
- return [tank.lidar_object.front, tank.lidar_object.left, tank.lidar_object.back, tank.lidar_object.right][rotation];
- }
- tank.biggest_open_direction = function(){
- subsubnotice("Finding biggest open direction");
- if(tank.lidar.right > tank.lidar.left){
- if(tank.lidar.right > tank.lidar.back) return tank.relative_to_rotation(3);
- else if(tank.lidar.back > tank.lidar.front) return tank.relative_to_rotation(2);
- } else {
- if(tank.lidar.left > tank.lidar.back) return tank.relative_to_rotation(1);
- else if(tank.lidar.back > tank.lidar.front) return tank.relative_to_rotation(2);
- }
- return false;
- }
- function direction_of_most_unknowns(){
- return direction_of_most(icon.unknown, false);
- }
- function direction_of_most_unknown_pings(){
- return direction_of_most(icon.obstacle_unknown, true);
- }
- function direction_of_most(icon,include_walls){
- include_walls = (include_walls == undefined || include_walls === false) ? false : include_walls;
- leftmost = include_walls ? 0 : 1;
- topmost = include_walls ? 0 : 1;
- bottommost = include_walls ? map.length : map.length - 1;
- rightmost = include_walls ? map[0].length : map[0].length - 1;
- unknowns_above = unknowns_below = unknowns_left = unknowns_right = 0;
- r = new RegExp(icon, "g");
- for(row_above = topmost; row_above <= tank.y; row_above++){
- if(row_above != tank.y) unknowns_above += (map[row_above].match(r) || []).length;
- unknowns_left += (map[row_above].substring(leftmost,tank.x).match(r) || []).length;
- unknowns_right += (map[row_above].substring(tank.x+1, rightmost).match(r) || []).length;
- }
- for(row_below = tank.y+1; row_below < bottommost; row_below++){
- unknowns_below += (map[row_below].match(r) || []).length;
- unknowns_left += (map[row_below].substring(leftmost,tank.x).match(r) || []).length;
- unknowns_right += (map[row_below].substring(tank.x+1, rightmost).match(r) || []).length;
- }
- subsubnotice("There are " + unknowns_above + " '"+icon+"'s to the north, " + unknowns_below + " south, " + unknowns_left + " east, and " + unknowns_right + " west.");
- if(unknowns_above + unknowns_below + unknowns_left + unknowns_right === 0) return false;
- if(unknowns_above >= unknowns_below){
- if(unknowns_above >= unknowns_left && unknowns_above >= unknowns_right) return 0;
- if(unknowns_above >= unknowns_left) return 3;
- return 1;
- }
- if(unknowns_below >= unknowns_left && unknowns_below >= unknowns_right) return 2;
- if(unknowns_below >= unknowns_left) return 3;
- return unknowns_right >= unknowns_left ? 3 : 1;
- }
- tank.distance_traveled = function(){
- return tank.traveled.o_up + tank.traveled.o_down + tank.traveled.o_right + tank.traveled.o_left;
- }
- tank.is_new = function(){
- return tank.distance_traveled() < 5 && tank.status.shots_fired < 1 && tank.status.ticks < 3;
- }
- // Modifiers
- tank.update_coords = function(){
- subnotice("Updating coordinate information");
- tank.x = tank.coords[0];
- tank.y = tank.coords[1];
- ends = [[x,y-tank.o_lidar.up],[x-tank.o_lidar.left,y],[x,y+tank.o_lidar.down],[x+tank.o_lidar.right,y]];
- tank.lidar_object.right = icon_for(ends[(tank.rotation+3)%4][0],ends[(tank.rotation+3)%4][1]);
- tank.lidar_object.back = icon_for(ends[(tank.rotation+2)%4][0],ends[(tank.rotation+2)%4][1]);
- tank.lidar_object.left = icon_for(ends[(tank.rotation+1)%4][0],ends[(tank.rotation+1)%4][1]);
- tank.lidar_object.front = icon_for(ends[(tank.rotation)%4][0],ends[(tank.rotation)%4][1]);
- }
- tank.tick_reset = function(){
- tank.status.ticks++;
- tank.status.tick.action_done = false;
- }
- // Translations
- tank.rotation_to_relative = function(rotation){ return ((4-tank.rotation) - rotation) % 4; }
- tank.relative_to_rotation = function(relative){ return (relative+tank.rotation) % 4; }
- tank.rotation_to_lidar = function(rotation){
- return [tank.lidar.front, tank.lidar.left, tank.lidar.back, tank.lidar.right][tank.rotation_to_relative(rotation)];
- }
- /** END FRAMEWORK **/
- /* DRIVE THE TANK! */
- // Directives # FEEL FREE TO REWRITE THESE
- tank.investigate = function(){
- notice("Investigating. Need to walk " + (tank.status.directive.distance - tank.status.directive.steps) + " more step(s).");
- if(tank.status.directive.distance - tank.status.directive.steps < 1){
- subnotice("It was around here! Anything uknown nearby?");
- tank.turn_towards_closest_unknown_ping();
- if(tank.status.tick.action_done){
- tank.reset();
- return;
- }
- subnotice("No? Explore I guess?");
- return tank.explore();
- }
- tank.status.directive.steps++;
- tank.forward();
- }
- tank.explore_half = function(){
- subnotice("Exploring up to half way?");
- if(tank.lidar.front < tank.lidar.back){
- subnotice("We're over halfway");
- open_direction = tank.biggest_open_direction();
- if(tank.icon_at(open_direction) != icon.obstacle_wall){
- subsubnotice("Lets check it out");
- tank.turn_towards(open_direction);
- if(tank.status.tick.action_done){
- tank.status.directive.name = "explore";
- tank.status.directive.direction = tank.rotation;
- return;
- }
- } else {
- subsubnotice("Biggest open area is towards a known wall. Is anything unkown?");
- tank.turn_towards_closest_unknown_ping();
- if(!tank.status.tick.action_done){
- if(tank.lidar.front > 0){
- subsubnotice("Wow. Okay. Go further?");
- return tank.explore();
- }
- subsubnotice("OMG. Fuck it.");
- tank.turn_towards_biggest_open_direction();
- if(tank.status.tick.action_done) return;
- }
- }
- }
- subsubnotice("Keep going");
- return tank.explore();
- }
- tank.explore = function(){
- if(!tank.status.directive.active){
- notice("Start exploring");
- tank.status.directive.active = true;
- tank.status.directive.name = "explore";
- subnotice("Drive towards the most unknown stuff.");
- stuff_dir = direction_of_most_unknowns();
- if(stuff_dir !== false){
- tank.status.directive.direction = stuff_dir;
- tank.turn_towards(tank.status.directive.direction);
- if(tank.status.tick.action_done) return;
- subnotice("That would be forward");
- tank.forward();
- if(tank.status.tick.action_done) return;
- subnotice("We can't go forward.");
- tank.status.lost = true;
- } else {
- subsubnotice("There is no unknown stuff");
- tank.status.lost = true;
- }
- } else notice("Continue exploring");
- if(tank.status.lost){
- subnotice("We are lost!?");
- tank.turn_towards_biggest_open_direction();
- if(tank.status.tick.action_done) return;
- subnotice("We're already facing that way?");
- tank.forward();
- if(tank.status.tick.action_done){
- tank.status.lost = false;
- return;
- }
- } else {
- subnotice("Drive forward");
- tank.forward();
- if(tank.status.tick.action_done) return;
- }
- subnotice("We can't go forward any more?");
- if(tank.is_new()){
- subnotice("We're young, go big");
- tank.turn_towards_biggest_open_direction();
- if(tank.status.tick.action_done) return;
- } else {
- most_unknowns = direction_of_most_unknowns();
- if(most_unknowns === false){
- subnotice("No unknowns? What about unknown pings?");
- most_unknowns = direction_of_most_unknown_pings();
- tank.status.directive.name = "explore_half";
- tank.status.directive.direction = most_unknowns;
- tank.turn_towards(tank.status.directive.direction);
- if(tank.status.tick.action_done) return;
- }
- if(tank.rotation == most_unknowns){
- subsubnotice("Oh. That way is forward. And we can't go forward.");
- tank.status.directive.name = "explore_half";
- tank.status.directive.direction = most_unknowns;
- tank.turn_towards_biggest_open_direction();
- if(tank.status.tick.action_done) return;
- } else if(tank.icon_at_rotation(most_unknowns) != icon.obstacle_wall){
- subsubnotice("This looks like a good bet, lets go (rotation: " + most_unknowns + ").");
- tank.status.directive.direction = most_unknowns;
- tank.turn_towards(tank.status.directive.direction);
- if(tank.status.tick.action_done) return;
- } else {
- subsubnotice("But we already know there's a wall that way (" + tank.icon_at_rotation(most_unknowns) + ").");
- tank.turn_towards_closest_unknown_ping();
- if(tank.status.tick.action_done) return;
- subsubnotice("There's a wall every way...");
- tank.turn_towards_biggest_open_direction();
- if(tank.status.tick.action_done) return;
- }
- }
- if(tank.status.tick.action_done) return;
- warn("Oh no!");
- }
- tank.next_directive_action = function(action){
- if(tank.directives.indexOf(action)<0){ warn("Warning! Cannot do '"+action+"'!"); return; }
- return tank[action]();
- }
- tank.next_combat_action = function(){
- if(!tank.status.combat.active) return false;
- notice("Battle planner");
- if(api.identifyTarget()){
- subnotice("Target directly ahead.");
- if(tank.status.shots_fired_in_a_row > 1 && tank.lidar.front <= tank.status.combat.last_shot_range + 1){
- subsubnotice("There are a lot of enemies. Try to avoid being flanked.");
- tank.backward();
- if(tank.status.tick.action_done) return;
- }
- if(tank.lidar.front <= tank.max_range){
- subsubnotice("Clear to Fire!")
- tank.shoot();
- if(tank.status.tick.action_done) return;
- } else {
- subnotice("Too far to shoot. Range: " + tank.lidar.front + ", max: " + tank.max_range + ".");
- if(tank.status.combat.chase_target_seen_count > 0){
- subsubnotice("But the target hasn't moved. Go ahead and take the shot");
- tank.shoot();
- if(tank.status.tick.action_done){
- subsubnotice("Target gone, probably. End chase.");
- tank.status.combat.chasing = false;
- tank.status.combat.chase_remaining = 0;
- return;
- }
- } else {
- subsubnotice("Get closer to the target. (Chase mode active)")
- tank.status.combat.chasing = true;
- tank.status.combat.chase_remaining = tank.lidar.front;
- tank.status.combat.chase_target_seen_count++;
- }
- }
- } else {
- tank.status.combat.time_since_last_shot++;
- subnotice("No target ahead. Time since last shot: " + tank.status.combat.time_since_last_shot);
- }
- if(tank.status.combat.chasing && tank.status.combat.chase_remaining > 0){
- subnotice("We are in persuit. Trying to travel " + tank.status.combat.chase_remaining + " more blocks");
- subnotice("Anything unexpected around?");
- unexpected_ping_direction = tank.unexpected_ping_direction();
- if(unexpected_ping_direction !== false){
- subsubnotice("Unexpected ping!");
- if(tank.status.combat.chase_remaining > tank.rotation_to_lidar(unexpected_ping_direction)){
- subsubnotice("And it's closer than our chase target!");
- tank.turn_towards(unexpected_ping_direction);
- if(tank.status.tick.action_done) return;
- }
- }
- subsubnotice("Nope.");
- tank.status.combat.chase_remaining--;
- tank.forward();
- if(tank.status.tick.action_done) return;
- }else if(tank.status.combat.chasing && tank.status.combat.chase_remaining == 0){
- subnotice("This is where we expect to see thing thing we chased. Anything unexpected?");
- tank.turn_towards_unexpected_pings();
- if(tank.status.tick.action_done) return;
- subnotice("No? Anything Unknown?");
- tank.turn_towards_closest_unknown_ping();
- if(tank.status.tick.action_done) return;
- }
- if(tank.status.combat.time_since_last_shot < 3){
- subnotice("Cannon is still warm. Can we possibly shoot any of our pings?");
- tank.turn_towards_unexpected_pings();
- if(tank.status.tick.action_done) return;
- tank.turn_towards_closest_unknown_ping();
- if(tank.status.tick.action_done) return;
- }
- if(tank.status.combat.time_since_last_shot == 3 && tank.status.turning_around){
- subnotice("Cannon is almost cooled. Finish this turn.");
- return;
- }
- subnotice("No more enemies detected");
- tank.reset();
- subnotice("Tank reset. Combat mode disabled");
- }
- // Run the thing! # FEEL FREE TO REWRITE THIS
- exports.update = function() {
- // Here we go...
- if(verbose) console.log("┌─ tick " + tank.status.ticks + "\t───────────────────────────────────────────────────────────────┐");
- tank.tick_reset();
- // What do things look like since our last action
- tank.sense();
- if(verbose) tank_stats();
- if(verbose) map_stats();
- // Respond to possible threats
- if(tank.status.combat.active){
- notice("Combat mode is active.");
- tank.next_combat_action();
- if(tank.status.tick.action_done) return;
- }
- notice("Checking scan data for unexpected movement");
- tank.turn_towards_unexpected_pings();
- if(tank.status.tick.action_done) return;
- if(tank.status.turning_around){
- notice("We were turning around.");
- return tank.finish_turning_around();
- }
- if(tank.status.directive.active){
- notice("Current directive: " + tank.status.directive.name);
- tank.next_directive_action(tank.status.directive.name);
- if(tank.status.tick.action_done) return;
- }
- if(tank.is_new()){
- notice("I'm pretty new to this level.");
- tank.reset();
- tank.explore();
- if(tank.status.tick.action_done) return;
- }
- tank.explore();
- };
Advertisement
Add Comment
Please, Sign In to add comment