#include "robot.h" /* array for coordinates of other robot */ long other_position[2]; static long cell_array[CSTRUCT_SIZE]; int safe_move(unsigned int direction) { unsigned int test_direction = direction; int safe = 0; do { struct cheth_coord dxdy = cheth_dir_to_dxdy(test_direction); long dirthere; look (0,0, cell_array); dirthere = cell_array[CSTRUCT_DIRT_DEX]; look (dxdy.x, dxdy.y, cell_array); if (dirthere - cell_array[CSTRUCT_DIRT_DEX] > 150) /* drop too great */ test_direction = (test_direction + 1) % 6; else safe = 1; } while (!safe && test_direction != direction); if (safe) { write_string("Moving"); write_long(test_direction); return move(test_direction); } else return -100; } int katie_spiral_move (void) { /* moves in a spiral that hits all hexes */ static unsigned dir = 3; static unsigned edge_length = 1; static pos_in_edge = 0; int result; /* edge_number = dir - 3 */ /* invariant = 0 <= edge_number < 6 /\ 0 <= dir < 6 /\ 1 <= edge_length /\ 0 <= pos_in_edge < edge_length + (if edge_number == 4 then 1 else 0) /* do four edges of edge_length, a fifth of edge_length + 1, and a sixth of the original length */ if (pos_in_edge == edge_length) { /* must be at end of edge four */ result = safe_move(dir); } else { pos_in_edge++; result = safe_move(dir); if (pos_in_edge != edge_length || dir == 1) return result; } /* change direction */ dir = (dir + 1) % 6; if (dir == 3) edge_length++; pos_in_edge = 0; return result; } static unsigned cpu_speed = 3; static interrupted; void energy_alarm(void) { set_hr_misc_speed(cpu_speed /= 2); write_string("CPU speed halved in light of energy losses."); set_hr_int_energy(0); interrupted = 1; } static int biotake = 200; void main(void) { while (1) { int biomass_amount, biotaken; int oldenergy = get_energy(); switch (katie_spiral_move()) { case -100: write_string("Aargh - trapped!"); detonate(); break; case NO_ENERGY: write_string("Move failed due to lack of energy"); break; default: ; } /* having moved, should now get some biomass */ look(0, 0, cell_array); if ((biomass_amount = cell_array[CSTRUCT_BIOMASS_DEX]) > 30) { int returncode; write_string("Taking biomass: "); biotaken = biomass_amount > biotake ? biotake : biomass_amount; switch (returncode = take(-1, ITEM_BIOMASS, biotaken)) { case NO_ENERGY: write_string("Take failed due to lack of energy"); break; default: if (returncode < 0) { write_string("Take failed with code:"); write_long(returncode); } else { write_string("Took"); write_long(returncode); } } } if (get_biomass() >= 100) { int oldenergy = get_energy(); burn(ITEM_BIOMASS, get_biomass()); write_string("Burnt some biomass"); write_long(get_energy() - oldenergy); if (interrupted) { interrupted = 0; if (cpu_speed > 1) set_hr_int_energy(energy_alarm); } } if (get_energy() >= 300) { int returncode = radar(0, 6, 10, (char *)&other_position, 1); switch (returncode) { case 0: write_string("No robot to be found."); move(0); break; case FAIL: write_string("Radar error - possibly out of energy"); break; default: if (returncode < 0) { write_string("Radar failed with code"); write_long(returncode); } else { /* found a robot */ write_string("Radar result"); write_long(other_position[0]); write_long(other_position[1]); attack(other_position[0], other_position[1], 100, 1); } break; } } if (get_energy() < oldenergy) { biotake += 50; } } }