/*****************************************************************/ /* */ /* Ramdu Ver 2.0 April 8, 1994 */ /* by Randy Saint */ /* Loral AI Lab */ /* email (rsaint@freenet.fsu.edu) */ /* */ /* My robot's name is Ramdu. */ /* My main function is ramdu(). */ /* */ /*****************************************************************/ #include #include #include"const.h" #include"contest.h" /* Global defines */ #define REPAIR 5 #define GOOD 0 #define UNKNOWN 1 #define FLOOR_OR_MINE 3 #define FLOOR 2 #define EST_FLOOR 2 #define WALL_0 2 #define WALL_1 4 #define WALL_2 6 #define WALL_3 8 #define WALL_4 10 #define OUTSIDE_WALL 14 #define DEAD_BODY 15 #define LAND_MINE 44 #define BOOM 45 #define GOTPRIZE_UNKNOWN 5 #define GOTPRIZE_FLOOR_OR_MINE 3 #define LINE_OF_FIRE 20 #define EXPLORE 0 #define MAP_OUT 1 #define GET_GOOD 2 #define POT_SHOT 4 #define GO_RESURRECT 5 #define PURSUE 6 #define ATTACK 7 #define SELF_PRESERVATION 8 #define GET_PRIZE 9 #define STOP_THIEF 10 #define PROTECT_EXIT 11 #define PROTECT_PRIZE 12 #define GOT_PRIZE 13 #define BIG_DIST 255 #define NUM_PLAYERS 6 #define NUM_ROBOTS 26 #define NUM_BOOMS 35 #define MAX_PATHS 100 #define MAX_USED 200 #define MAX_HIGHWAYS 8 #define MAX_LINES 20 #define LINE_AGE 20 #define ROBOT_AGE 15 #define MY_GOAL_DIST 5 #define POWER 300 #define ENEMY_ROBOT 1 #define PLAYER_ROBOT 2 #define ATTACK_COMPUTER_ON_SIGHT 3 #define ATTACK_PLAYER_ON_SIGHT 2 #define ATTACK_IF_ATTACKED 4 #define ramduUpdateTime(how_long) {ramdu_list[q_my_num()].time += (how_long); \ ramduTime = ramdu_list[q_my_num()].time;} #define ramduSetGoal(x, y, g) {ramdu_list[q_my_num()].goal_x = x;ramdu_list[q_my_num()].goal_y = y;ramdu_list[q_my_num()].goal = g;} /* Caution! this assumes NORTH=0 EAST=1 SOUTH=2 & WEST=3 */ /* If these change, then these macros will have to change */ #define ramduOpposite(dir) (((dir) > 1) ? ((dir)-2) : ((dir)+2)) #define ramduRight(dir) (((dir) > 2) ? ((dir)-3) : ((dir)+1)) #define ramduLeft(dir) (((dir) > 0) ? ((dir)-1) : ((dir)+3)) typedef char position; typedef unsigned char distance; typedef char direction; typedef unsigned char boolean; typedef char identification; typedef unsigned char power; typedef unsigned char duration; typedef struct { direction dir; position x, y; int cost_to; int total_cost; } ramduPath; typedef struct { direction dir; position x, y; int cost_to; char here; } ramduUsed; unsigned char ramduGetDensity(void); void ramduCheckMap(int my_num); duration ramduExplore(int my_num); duration ramduProtectPrize(int my_num); duration ramduGetGood(int my_num); duration ramduGetPrize(int my_num); duration ramduReplicate(direction direct); duration ramduResurrectNear(int my_num); duration ramduStopThief(int my_num); duration ramduGoResurrect(int my_num); duration ramduGoExit(int my_num); duration ramduSelfPreservation(int my_num); duration ramduPursue(int my_num); duration ramduAttack(int my_num); boolean ramduStep(direction dir); duration ramduMove(direction dir); duration ramduCheck(direction dir); duration ramduScan(direction dir, int *found, int *id, int *dist); int ramduNumComputers(void); duration ramduScanHere(int my_num); void ramduSetMap(position x, position y, int offset, direction dir, int value); unsigned char ramduGetMap(position x, position y, int offset, direction dir); boolean ramduWallThere(position x, position y, int offset, direction dir); void ramduGetXY(position *x, position *y, distance offset, direction dir); int ramduDist(position from_x, position from_y, position to_x, position to_y); int ramduDistTo(position x, position y); direction ramduDir(position from_x, position from_y, position to_x, position to_y); direction ramduDirTo(position x, position y); int ramduTimeTo(position to_x, position to_y); int ramduCourseTo(position x, position y, ramduPath *ramdu_path, ramduUsed *ramdu_used); direction ramduPathTo(position x, position y); int ramduAddPath(int num_path, direction dir_to, direction dir, position x, position y, int cost_to, position to_x, position to_y, ramduPath *ramdu_path, ramduUsed *ramdu_used, int est_floor); int ramduCostHere(position x, position y); boolean ramduSafe(position x, position y); boolean ramduSafeSpot(position x, position y); boolean ramduRobotThere(position x, position y); direction ramduOnBomb(position x, position y); boolean ramduNoBoom(position x, position y, direction dir, int limit, int steps); duration ramduSideStep(direction dir); duration ramduShieldOn(void); direction ramduClearShot(position from_x, position from_y, position to_x, position to_y); boolean ramduShootOver(position x, position y); int ramduSetSaw(identification id); int ramduSetHit(identification id); int ramduSetExit(position x, position y, identification id); float ramduGetAggression(identification id); int ramduGetExit(identification id); int ramduGetExitAt(position x, position y); int ramduGetTeammateAt(position x, position y); int ramduGetRobotAt(position x, position y); int ramduSetRobot(position x, position y, identification id, int type); int ramduPropogateBoom(position x, position y, int num_boom); void ramduCheckBoom(void); void ramduExploded(position x, position y); int ramduSetLineOfFire(position x, position y, direction dir); void ramduSetShooting(position x, position y, direction dir); void ramduUnsetLineOfFire(position x, position y); int ramduLineOfFire(position x, position y); int ramduTimeToBoom(position x, position y); duration ramduUseDynamite(void); boolean ramduGoalTaken(position x, position y); int ramdu_boom_time[NUM_BOOMS]; struct ramduHighway { position x, y; boolean travelled_to; boolean taken; } ramdu_highway[MAX_HIGHWAYS]; struct ramduRobot { identification id; int time; position x, y; position last_x, last_y; position prev_x[2], prev_y[2]; char goal_dur; identification goal_id; char goal; position goal_x, goal_y; char fire; boolean checked[4]; power scanner_pwr; power cannon_pwr; direction built_wall; boolean strongest; char highway_index; } ramdu_list[NUM_PLAYERS]; int ramdu_num_exits = 0; int ramdu_num_robots = 0; int ramdu_num_boom = 0; boolean ramdu_thief_has_prize = FALSE; position ramdu_my_exit_x = -1; position ramdu_my_exit_y = -1; position ramdu_prize_x = -1; position ramdu_prize_y = -1; struct ramduRobotPos { identification id; position x, y; boolean lost; char type; int time; } ramdu_robot[NUM_ROBOTS]; struct ramduExitPos { identification id; position x, y; unsigned int saw; unsigned int hits; } ramdu_exit[NUM_PLAYERS]; struct ramduLinePos { identification id; position x, y; direction dir; int time; } ramdu_line[MAX_LINES]; unsigned char ramduMap[SIZE][SIZE]; unsigned char ramduMapInit = FALSE; int ramduTime = 0; unsigned char ramduNumOfUs = 1; boolean ramduAnyTravelledTo = FALSE; int ramdu_num_computer_sightings = 0; int ramdu_num_player_sightings = 0; void ramdu() { int i,j; position x, y; position test_x, test_y; int found, id, dist; int my_num; direction direct; direction fire_dir; distance distant; boolean have_prize; int num_repair, num_builder; power cannon_pwr, scanner_pwr; power shield_pwr; boolean shield_is_on; duration how_long; direction last_hit_dir; identification robot_id; int max_power, num_max_power; struct found { distance dist; position x; position y; } attacker; if (!ramduMapInit) { for (i=0; i 0) && ((ramduTime - ramdu_list[i].time) > 6)) { /* One of our guys has stopped updating his clock, go resurrect */ ramduMap[ramdu_list[i].y][ramdu_list[i].x] = DEAD_BODY; ramdu_list[i].id = -1; ramdu_list[i].x = -1; ramdu_list[i].y = -1; ramdu_list[i].goal_x = -1; ramdu_list[i].goal_y = -1; } if (ramdu_list[i].id > 0) { ramduNumOfUs++; if ((ramdu_list[i].goal == ATTACK) && (ramdu_list[i].goal_id != 0)) { if (ramduDistTo(ramdu_list[i].goal_x, ramdu_list[i].goal_y) < attacker.dist) { attacker.dist = ramduDistTo(ramdu_list[i].goal_x, ramdu_list[i].goal_y); attacker.x = ramdu_list[i].goal_x; attacker.y = ramdu_list[i].goal_y; } } if ((ramdu_list[i].scanner_pwr+ramdu_list[i].cannon_pwr) > max_power) max_power = ramdu_list[i].scanner_pwr + ramdu_list[i].cannon_pwr; } } num_max_power = 0; for (i=0; i 0) && ((ramdu_list[i].scanner_pwr+ramdu_list[i].cannon_pwr) == max_power)) num_max_power++; if (((ramdu_list[my_num].scanner_pwr+ramdu_list[my_num].cannon_pwr) == max_power) && (num_max_power == 1)) ramdu_list[my_num].strongest = TRUE; else ramdu_list[my_num].strongest = FALSE; if (last_hit_dir >= 0) { if ((ramdu_my_exit_x >= 0) && (ramduNumOfUs >= ATTACK_IF_ATTACKED) && (!ramdu_list[my_num].strongest)) { if ((ramdu_list[my_num].goal <= ATTACK) && (ramdu_list[my_num].cannon_pwr > 0)) { if ((last_hit_dir != ramduDirTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y)) || (ramdu_list[my_num].goal < ATTACK)) { x = ramdu_list[my_num].last_x; y = ramdu_list[my_num].last_y; ramduGetXY(&x, &y, 1, last_hit_dir); ramdu_list[my_num].goal_id = 0; ramdu_list[my_num].goal_x = x; ramdu_list[my_num].goal_y = y; ramdu_list[my_num].goal_dur = 1; } ramdu_list[my_num].goal = ATTACK; } } /* If someone shot through our wall, then set that map loc to floor */ if ((ramdu_list[my_num].built_wall != last_hit_dir) && (ramduWallThere(ramdu_list[my_num].x, ramdu_list[my_num].y, 1, last_hit_dir))) { ramduSetMap(ramdu_list[my_num].x, ramdu_list[my_num].y, 1, last_hit_dir, FLOOR); } robot_id = ramduSetLineOfFire(ramdu_list[my_num].last_x, ramdu_list[my_num].last_y, last_hit_dir); if ((robot_id < 0) && ((ramdu_list[my_num].x != ramdu_list[my_num].last_x) || (ramdu_list[my_num].y != ramdu_list[my_num].last_y))) robot_id = ramduSetLineOfFire(ramdu_list[my_num].x, ramdu_list[my_num].y, last_hit_dir); if (robot_id > 0) ramduSetHit(robot_id); } ramdu_list[my_num].last_x = ramdu_list[my_num].x; ramdu_list[my_num].last_y = ramdu_list[my_num].y; ramdu_list[my_num].built_wall = -1; if ((ramdu_my_exit_x < 0) || (ramdu_prize_x >= 0) || (ramdu_list[my_num].goal >= GET_GOOD) || (ramdu_list[my_num].highway_index >= 0) || (ramdu_list[my_num].scanner_pwr <= 60) || (ramdu_list[my_num].cannon_pwr <= 20) || ((ramdu_list[my_num].checked[0]) && (ramdu_list[my_num].checked[1]) && (ramdu_list[my_num].checked[2]) && (ramdu_list[my_num].checked[3]))) ramduCheckMap(my_num); x = (position)q_wherex(); y = (position)q_wherey(); if (ramduOnBomb(x, y) >= 0) { how_long = ramduMove(ramduOnBomb(x, y)); } else if (ramduOnBomb(x, y) == -99) { shield_on(); ramduUpdateTime(1); how_long = 1; ramduCheckBoom(); } else if ((x == ramdu_prize_x) && (y == ramdu_prize_y) && (!have_prize)) { if (!take_item()) { ramdu_prize_x = -1; ramdu_prize_y = -1; if (ramduGetMap(x, y, 1, NORTH) != DEAD_BODY) ramduSetMap(x, y, 1, NORTH, UNKNOWN); if (ramduGetMap(x, y, 1, SOUTH) != DEAD_BODY) ramduSetMap(x, y, 1, SOUTH, UNKNOWN); if (ramduGetMap(x, y, 1, EAST) != DEAD_BODY) ramduSetMap(x, y, 1, EAST, UNKNOWN); if (ramduGetMap(x, y, 1, WEST) != DEAD_BODY) ramduSetMap(x, y, 1, WEST, UNKNOWN); ramduSetGoal(x, y, EXPLORE); } ramduUpdateTime(2); how_long = 2; } else if ((ramduMap[y][x] == REPAIR) || (ramduMap[y][x] == GOOD)) { take_item(); ramduUpdateTime(2); how_long = 2; ramduMap[y][x] = FLOOR; } else if ((ramduLineOfFire(x, y) >= 0) && ((ramdu_list[my_num].goal <= GO_RESURRECT) || ((ramdu_list[my_num].goal == GOT_PRIZE) && (ramdu_my_exit_x <= 0)))) { /* This checks to see if we're close enough to our highway */ if (ramduDistTo(ramdu_highway[ramdu_list[my_num].highway_index].x, ramdu_highway[ramdu_list[my_num].highway_index].y) < 4) { /* This means we're close enough to the tic tac toe point */ ramdu_highway[ramdu_list[my_num].highway_index].taken = FALSE; if (ramdu_highway[ramdu_list[my_num].highway_index].travelled_to) { ramdu_list[my_num].highway_index = -1; } else { ramdu_highway[ramdu_list[my_num].highway_index].travelled_to = TRUE; ramduAnyTravelledTo = TRUE; ramdu_list[my_num].highway_index += 1; if (ramdu_list[my_num].highway_index >= MAX_HIGHWAYS) ramdu_list[my_num].highway_index = 0; if (ramdu_highway[ramdu_list[my_num].highway_index].taken) { ramdu_list[my_num].highway_index = -1; } else { ramdu_highway[ramdu_list[my_num].highway_index].taken = TRUE; ramduSetGoal(ramdu_highway[ramdu_list[my_num].highway_index].x, ramdu_highway[ramdu_list[my_num].highway_index].y, EXPLORE); } } } /* This should find the safest place, that's not where I am */ direct = ramduPathTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y); ramduGetXY(&x, &y, 1, direct); if (!ramduSafe(x, y)) { x = (position)q_wherex(); y = (position)q_wherey(); how_long = ramduSideStep(ramduLineOfFire(x, y)); if ((how_long == 0) || ((x == (position)q_wherex()) && (y == (position)q_wherey()))) { x = (position)q_wherex(); y = (position)q_wherey(); how_long = ramduShieldOn(); if (how_long == 0) { fire_dir = ramduLineOfFire(x, y); if ((fire_dir >= 0) && (num_builder > 0)) { test_x = x; test_y = y; ramduGetXY(&test_x, &test_y, 1, ramduOpposite(fire_dir)); if ((ramduGetDensity() > 20) && (num_builder > 0) && ((ramduGetMap(x, y, 1, ramduOpposite(fire_dir)) == FLOOR) || (ramduGetMap(x, y, 1, ramduOpposite(fire_dir)) == UNKNOWN) || (ramduGetMap(x, y, 1, ramduOpposite(fire_dir)) == FLOOR_OR_MINE)) && (ramduGetRobotAt(test_x, test_y) < 0)) { if (build_wall(ramduOpposite(fire_dir))) { ramduUpdateTime(4); how_long = 4; ramduSetMap(x, y, 1, ramduOpposite(fire_dir), WALL_4); ramdu_list[my_num].built_wall = ramduOpposite(fire_dir); } else { ramduUpdateTime(4); how_long = 4; ramduGetXY(&x,&y, 1, fire_dir); if (ramduSafeSpot(x, y)) { ramduStep(fire_dir); how_long += 2; } else { how_long += ramduCheck(fire_dir); if (how_long == 4) { attack(ramduOpposite(fire_dir)); ramduUpdateTime(2); how_long += 2; } } } } if (how_long == 0) { how_long = ramduCheck(ramduLeft(fire_dir)); } if (how_long == 0) { how_long = ramduCheck(ramduRight(fire_dir)); } if ((how_long == 0) && (num_builder > 0) && ((ramduGetMap(x, y, 1, ramduOpposite(fire_dir)) == FLOOR) || (ramduGetMap(x, y, 1, ramduOpposite(fire_dir)) == UNKNOWN) || (ramduGetMap(x, y, 1, ramduOpposite(fire_dir)) == FLOOR_OR_MINE)) && (ramduGetRobotAt(test_x, test_y) < 0)) { if (build_wall(ramduOpposite(fire_dir))) { ramduUpdateTime(4); how_long = 4; ramduSetMap(x, y, 1, ramduOpposite(fire_dir), WALL_4); ramdu_list[my_num].built_wall = ramduOpposite(fire_dir); } else { ramduUpdateTime(4); how_long = 4; ramduGetXY(&x,&y, 1, fire_dir); if (ramduSafeSpot(x, y)) { ramduStep(fire_dir); how_long += 2; } else { how_long += ramduCheck(fire_dir); if (how_long == 4) { attack(ramduOpposite(fire_dir)); ramduUpdateTime(2); how_long += 2; } } } } if (how_long == 0) { test_x = x; test_y = y; ramduGetXY(&test_x,&test_y, 1, fire_dir); if (ramduSafeSpot(test_x, test_y)) { ramduStep(fire_dir); how_long += 2; } else { how_long += ramduCheck(fire_dir); if (how_long == 0) { attack(ramduOpposite(fire_dir)); ramduUpdateTime(2); how_long += 2; } } } } else { how_long = ramduMove(direct); } } } } else how_long = ramduMove(direct); } else if ((num_repair > 0) && ((cannon_pwr < 150) || (scanner_pwr < 150) || (shield_pwr < 100))) { if ((scanner_pwr <= 100) || (cannon_pwr <= 100)) repair_me(REPAIR_WORST); else if (shield_pwr < 100) repair_me(REPAIR_SHIELD); else repair_me(REPAIR_WORST); ramduUpdateTime(1); how_long = 1; } /* else if ((ramdu_list[my_num].goal != ATTACK) && (ramdu_list[my_num].goal != GOT_PRIZE) && (shield_is_on)) */ else if ((shield_is_on) && (ramduSafe(x, y)) && ((ramdu_list[my_num].goal != ATTACK) && (ramdu_list[my_num].goal <= STOP_THIEF))) { shield_off(); ramduUpdateTime(1); how_long = 1; } else switch (ramdu_list[my_num].goal) { case EXPLORE: how_long = ramduExplore(my_num); break; /* end EXPLOREing */ case GET_GOOD: how_long = ramduExplore(my_num); /* how_long = ramduGetGood(&found, &id, &dist); */ break; /* end if GETting GOODies */ case GET_PRIZE: how_long = ramduGetPrize(my_num); break; /* end if GETting PRIZE */ case PURSUE: how_long = ramduPursue(my_num); break; case ATTACK: how_long = ramduAttack(my_num); break; case GO_RESURRECT: how_long = ramduGoResurrect(my_num); break; case SELF_PRESERVATION: how_long = ramduSelfPreservation(my_num); break; case STOP_THIEF: how_long = ramduStopThief(my_num); break; case PROTECT_EXIT: how_long = ramduProtectPrize(my_num); break; case PROTECT_PRIZE: how_long = ramduProtectPrize(my_num); break; case GOT_PRIZE: how_long = ramduGoExit(my_num); break; default: ramdu_list[my_num].goal = EXPLORE; break; }/* end switch */ if (how_long == 0) /* This means we didn't do ANYTHING (this is bad) */ { direct = random(4); if (scanner_pwr > 0) how_long = ramduScan(direct, &found, &id, &dist); if ((cannon_pwr > 0) && (how_long == 0)) { attack(direct); ramduUpdateTime(2); how_long += 2; } if (how_long == 0) how_long += ramduMove(direct); if ((scanner_pwr == 0) && (how_long == 0)) how_long += ramduScanHere(my_num); } } } unsigned char ramduGetDensity() { position i, j; int num_walls = 0; int num_known = 0; for (i=1; i<(SIZE-1); i++) { for (j=1; j<(SIZE-1); j++) { if (ramduWallThere(j, i, 0, 0)) num_walls++; if (ramduMap[i][j] != UNKNOWN) num_known++; } } return( (((long)num_walls)*100L)/((long)num_known)); } void ramduCheckMap(int my_num) { position i, j; char index, exit_index; char prize_index; position x, y; boolean have_prize; int prize_x, prize_y, thief_id; boolean prev_thief_has_prize; power scanner_pwr; power cannon_pwr; distance distant; direction direct; int savior = -1; int time_to; int num_wall; struct found { distance dist; position x; position y; } good, unknown, good_near, unknown_near, dead_body, half_way; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; have_prize = q_have_prize(); scanner_pwr = q_scanner_status(); cannon_pwr = q_cannon_status(); prev_thief_has_prize = ramdu_thief_has_prize; ramdu_thief_has_prize = q_prize_loc(&prize_x, &prize_y, &thief_id); if (ramdu_thief_has_prize) { /* If we know where our exit is, set the thief's spot to floor */ if (ramdu_my_exit_x >= 0) ramduMap[prize_y][prize_x] = FLOOR; ramdu_prize_x = (position)prize_x; ramdu_prize_y = (position)prize_y; if (thief_id != q_my_id()) ramduSetRobot(prize_x, prize_y, thief_id, PLAYER_ROBOT); } else if (prev_thief_has_prize) { /* This is new, after the competition */ /* This means that the thief just died, set a dead robot there */ ramduMap[ramdu_prize_y][ramdu_prize_x] = DEAD_BODY; index = ramduGetRobotAt(ramdu_prize_x, ramdu_prize_y); if (index >= 0) ramdu_robot[index].lost = TRUE; } if (ramduNumOfUs > 1) { distant = BIG_DIST; for (i=0; i= 0) && (ramdu_list[i].scanner_pwr > 0) && (ramdu_list[i].cannon_pwr > 0) && (ramduDistTo(ramdu_list[i].x, ramdu_list[i].y) < distant)) { savior = i; distant = ramduDistTo(ramdu_list[i].x, ramdu_list[i].y); } } } num_wall = 0; if (ramduWallThere(x, y, 1, NORTH)) num_wall++; if (ramduWallThere(x, y, 1, EAST)) num_wall++; if (ramduWallThere(x, y, 1, SOUTH)) num_wall++; if (ramduWallThere(x, y, 1, WEST)) num_wall++; if ((!ramduAnyTravelledTo) && (ramduNumOfUs == 1)) { distant = BIG_DIST; for (i=0; i= BOOM) && ((ramdu_boom_time[ramduMap[i][j] - BOOM] - ramduTime) > 100)) && ((ramduMap[i-1][j] == UNKNOWN) || (ramduMap[i][j+1] == UNKNOWN) || (ramduMap[i+1][j] == UNKNOWN) || (ramduMap[i][j-1] == UNKNOWN)))) { /* Found a good, or an UNKNOWN near a long time boom (it's probably hidden for a reason ) */ if (distant < 10) { if (!ramduGoalTaken(j, i)) { /* time_to = ramduTimeTo(-1, x, y, j, i); */ time_to = ramduTimeTo(j, i); if ((time_to < good.dist) && (ramduSafe(j, i))) { good.dist = time_to; good.x = j; good.y = i; } } } else if (distant < good_near.dist) { if (!ramduGoalTaken(j, i)) { if (ramduSafe(j, i)) { good_near.dist = distant; good_near.x = j; good_near.y = i; } } } } else if ((ramduMap[i][j] == UNKNOWN) && (ramdu_list[my_num].highway_index < 0)) { if (distant < 7) { if (!ramduGoalTaken(j, i)) { /* time_to = ramduTimeTo(-1, x, y, j, i); */ time_to = ramduTimeTo(j, i); if (time_to < unknown.dist) { unknown.dist = time_to; unknown.x = j; unknown.y = i; } } } else if (distant < unknown_near.dist) { if (!ramduGoalTaken(j, i)) { unknown_near.dist = distant; unknown_near.x = j; unknown_near.y = i; } } } } } if ((have_prize) && (ramdu_my_exit_x >= 0)) { if (ramdu_my_exit_x < 0) { if (unknown.dist < BIG_DIST) { ramduSetGoal(unknown.x, unknown.y, GOT_PRIZE); } else { ramduSetGoal(unknown_near.x, unknown_near.y, GOT_PRIZE); } } else { ramduSetGoal(ramdu_my_exit_x, ramdu_my_exit_y, GOT_PRIZE); } } else if ((ramdu_thief_has_prize) && (thief_id != q_my_id())) { if (thief_id != q_my_id()) { index = -1; distant = BIG_DIST; if ((dead_body.dist < BIG_DIST) && (ramduNumOfUs > 1)) { for (i=0; i= 0) { half_way.x = (ramdu_exit[exit_index].x + prize_x)/2; half_way.y = (ramdu_exit[exit_index].y + prize_y)/2; for (i=0; i 1)) { ramduSetGoal(half_way.x, half_way.y, STOP_THIEF); } else { /* Go for the thief */ if ((exit_index >= 0) && (ramduDistTo(ramdu_exit[exit_index].x, ramdu_exit[exit_index].y) < ramduDist(prize_x, prize_y, ramdu_exit[exit_index].x, ramdu_exit[exit_index].y))) { if (ramduDistTo(ramdu_exit[exit_index].x, ramdu_exit[exit_index].y) < ramduDistTo(prize_x, prize_y)) { ramduSetGoal(half_way.x, half_way.y, STOP_THIEF); } else { x = prize_x; y = prize_y; ramduGetXY(&x, &y, 1, ramduDir(prize_x, prize_y, ramdu_exit[exit_index].x, ramdu_exit[exit_index].y)); ramduSetGoal(x, y, STOP_THIEF); } } else { ramduSetGoal(prize_x, prize_y, STOP_THIEF); } } } } } else if ((ramdu_thief_has_prize) && (ramdu_my_exit_x >= 0)) { { index = -1; distant = BIG_DIST; if ((dead_body.dist < BIG_DIST) && (ramduNumOfUs > 1)) { for (i=0; i 1) { for (i=0; i 1) && (ramdu_list[my_num].y < y)) || (y == 48)) ramduGetXY(&x, &y, 1, NORTH); else ramduGetXY(&x, &y, 1, SOUTH); ramduSetGoal(x, y, PROTECT_EXIT); } } else { direct = ramduOpposite(ramduDir(ramdu_prize_x, ramdu_prize_y, ramdu_my_exit_x, ramdu_my_exit_y)); x = (position)prize_x; y = (position)prize_y; ramduGetXY(&x, &y, 1, direct); ramduSetGoal(x, y, PROTECT_PRIZE); } } /* else { direct = ramduOpposite(ramduDirTo(ramdu_my_exit_x, ramdu_my_exit_y)); ramduGetXY(&prize_x, &prize_y, 1, direct); ramduSetGoal(prize_x, prize_y, PROTECT_PRIZE); } */ } } } else if ((ramdu_prize_x >= 0) && (!have_prize) && (!ramdu_thief_has_prize)) { /* We only want to go get the prize if we know where it is, and nobody has it. */ ramduSetGoal(ramdu_prize_x, ramdu_prize_y, GET_PRIZE); } else if ((ramdu_list[my_num].goal != ATTACK) && (ramdu_list[my_num].goal != PURSUE) && (dead_body.dist < BIG_DIST)) { ramduSetGoal(dead_body.x, dead_body.y, GO_RESURRECT); } else if ((ramdu_list[my_num].goal != ATTACK) && (ramdu_list[my_num].goal != PURSUE) && ((good.dist < BIG_DIST) || (good_near.dist < BIG_DIST))) { if (good.dist < BIG_DIST) { ramduSetGoal(good.x, good.y, GET_GOOD); } else { ramduSetGoal(good_near.x, good_near.y, GET_GOOD); } } else if ((ramduTime<9000) && (((scanner_pwr == 0) || ((scanner_pwr < 60) && (cannon_pwr == 0))) && (savior >= 0)) || (((cannon_pwr > 0) && ((scanner_pwr < 20) || (cannon_pwr < 20))) && ((num_wall+q_builder()) >= 4)) && (savior < 0) && (ramduNumOfUs < 3)) { ramdu_list[my_num].goal_id = savior; ramdu_list[my_num].goal = SELF_PRESERVATION; } else if ((ramdu_list[my_num].goal != ATTACK) && (ramdu_list[my_num].goal != PURSUE) && ((unknown.dist < BIG_DIST) || (unknown_near.dist < BIG_DIST) || (ramdu_list[my_num].highway_index >= 0))) { if (ramdu_list[my_num].highway_index >= 0) { ramduSetGoal(ramdu_highway[ramdu_list[my_num].highway_index].x, ramdu_highway[ramdu_list[my_num].highway_index].y, EXPLORE); } else if (unknown.dist < BIG_DIST) { ramduSetGoal(unknown.x, unknown.y, EXPLORE); } else if (unknown_near.dist < BIG_DIST) { ramduSetGoal(unknown_near.x, unknown_near.y, EXPLORE); } } /* else if ((ramdu_list[my_num].goal <= GO_RESURRECT) && */ else if ((ramdu_list[my_num].goal != ATTACK) && (ramdu_list[my_num].goal != PURSUE) && (unknown.dist == BIG_DIST) && (unknown_near.dist == BIG_DIST) && (ramdu_list[my_num].highway_index < 0)) { /* This means all points are not UNKNOWN */ if (ramduNumOfUs == 6) { for (i=1; i<(SIZE-1); i++) { for (j=1; j<(SIZE-1); j++) { if ((ramduMap[i][j] == GOOD) || (ramduMap[i][j] == REPAIR)) { } else { ramduMap[i][j] = UNKNOWN; } } } } else { /* Set this so we'll check our exit */ ramduMap[ramdu_my_exit_y][ramdu_my_exit_x] = UNKNOWN; /* Set this so we'll check the corners */ ramduMap[1][1] = UNKNOWN; ramduMap[1][48] = UNKNOWN; ramduMap[48][1] = UNKNOWN; ramduMap[48][48] = UNKNOWN; unknown.x = -1; unknown.y = -1; for (i=0; i<(10*ramduNumOfUs); i++) { unknown.x = random(SIZE-2)+1; unknown.y = random(SIZE-2)+1; if ((ramduMap[unknown.y][unknown.x] == GOOD) || (ramduMap[unknown.y][unknown.x] == REPAIR)) { unknown.x = -1; unknown.y = -1; } else { ramduMap[unknown.y][unknown.x] = UNKNOWN; } } } } } duration ramduExplore(int my_num) { direction direct; int i; duration how_long = 0; int index; position x, y; direction pot_shot_dir = -1; direction test_dir = -1; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; if (ramduDistTo(ramdu_highway[ramdu_list[my_num].highway_index].x, ramdu_highway[ramdu_list[my_num].highway_index].y) < 2) { /* This means we're close enough to the tic tac toe point */ ramdu_highway[ramdu_list[my_num].highway_index].taken = FALSE; if (ramdu_highway[ramdu_list[my_num].highway_index].travelled_to) { ramdu_list[my_num].highway_index = -1; } else { ramdu_highway[ramdu_list[my_num].highway_index].travelled_to = TRUE; ramduAnyTravelledTo = TRUE; ramdu_list[my_num].highway_index += 1; if (ramdu_list[my_num].highway_index >= MAX_HIGHWAYS) ramdu_list[my_num].highway_index = 0; if (ramdu_highway[ramdu_list[my_num].highway_index].taken) { ramdu_list[my_num].highway_index = -1; } else { ramdu_highway[ramdu_list[my_num].highway_index].taken = TRUE; ramduSetGoal(ramdu_highway[ramdu_list[my_num].highway_index].x, ramdu_highway[ramdu_list[my_num].highway_index].y, EXPLORE); } } } direct = ramduPathTo(ramdu_list[my_num].goal_x,ramdu_list[my_num].goal_y); pot_shot_dir = -1; ramduGetXY(&x, &y, 1, direct); for (i=0; i< ramdu_num_robots; i++) { if ((!ramdu_robot[i].lost) && (ramdu_robot[i].type == PLAYER_ROBOT) && ((ramduTime - ramdu_robot[i].time) <= ROBOT_AGE)) { /* This robot is still active */ test_dir = ramduClearShot(ramdu_list[my_num].x, ramdu_list[my_num].y, ramdu_robot[i].x, ramdu_robot[i].y); if ((test_dir >= 0) && (test_dir != direct) && (test_dir != ramduOpposite(direct))) { pot_shot_dir = test_dir; index = i; } } } if ((pot_shot_dir >= 0) && (ramduSafe(x, y))) { if ((ramduDistTo(ramdu_robot[index].x, ramdu_robot[index].y) == 1) && (q_dynamite() > 0) && ((ramduGetMap(x, y, 1, ramduLeft(direct)) != LAND_MINE) && (ramduGetMap(x, y, 1, ramduLeft(direct)) < BOOM)) && ((ramduGetMap(x, y, 1, ramduRight(direct)) != LAND_MINE) && (ramduGetMap(x, y, 1, ramduRight(direct)) < BOOM)) && ((ramduGetMap(x, y, 1, direct) == FLOOR) || (ramduGetMap(x, y, 1, direct) == REPAIR) || (ramduGetMap(x, y, 1, direct) == GOOD))) { how_long = ramduUseDynamite(); if (ramduGetAggression(ramdu_robot[index].id) < 0.1) { /* This is to investigate who we just pot shot'ed */ ramduMap[ramdu_robot[index].y][ramdu_robot[index].x] = UNKNOWN; ramdu_robot[index].lost = TRUE; } } else { attack(pot_shot_dir); ramduUpdateTime(2); how_long += 2; if (ramduGetAggression(ramdu_robot[index].id) < 0.1) { /* This is to investigate who we just pot shot'ed */ ramduMap[ramdu_robot[index].y][ramdu_robot[index].x] = UNKNOWN; ramdu_robot[index].lost = TRUE; } } how_long += ramduMove(direct); } else { how_long = ramduCheck(direct); if (how_long > 0) return(how_long); how_long = ramduCheck(ramduLeft(direct)); if (how_long > 0) return(how_long); how_long = ramduCheck(ramduRight(direct)); if (how_long > 0) return(how_long); how_long = ramduCheck(ramduOpposite(direct)); if (how_long > 0) return(how_long); else { /* Randomly move (we should head for unknown territory */ if (ramdu_list[my_num].goal_x < 0) { /* We've explored everywhere, randomly go */ direct = random(4); how_long = ramduMove(direct); } else { if ((pot_shot_dir >= 0) && (ramduSafe(x, y))) { if ((ramduDistTo(ramdu_robot[index].x, ramdu_robot[index].y) == 1) && (q_dynamite() > 0) && ((ramduGetMap(x, y, 1, ramduLeft(direct)) != LAND_MINE) && (ramduGetMap(x, y, 1, ramduLeft(direct)) < BOOM)) && ((ramduGetMap(x, y, 1, ramduRight(direct)) != LAND_MINE) && (ramduGetMap(x, y, 1, ramduRight(direct)) < BOOM)) && ((ramduGetMap(x, y, 1, direct) == FLOOR) || (ramduGetMap(x, y, 1, direct) == REPAIR) || (ramduGetMap(x, y, 1, direct) == GOOD))) { how_long = ramduUseDynamite(); if (ramduGetAggression(ramdu_robot[index].id) < 0.1) { /* This is to investigate who we just pot shot'ed. */ ramduMap[ramdu_robot[index].y][ramdu_robot[index].x] = UNKNOWN; ramdu_robot[index].lost = TRUE; } } else { attack(pot_shot_dir); ramduUpdateTime(2); how_long += 2; if (ramduGetAggression(ramdu_robot[index].id) < 0.1) { /* This is to investigate who we just pot shot'ed. */ ramduMap[ramdu_robot[index].y][ramdu_robot[index].x] = UNKNOWN; ramdu_robot[index].lost = TRUE; } } how_long += ramduMove(direct); } else how_long = ramduMove(direct); } } } return(how_long); } duration ramduProtectPrize(int my_num) { int i; position x, y; int found, id, dist; int index; direction direct, fire_dir; duration how_long = 0; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; fire_dir = ramduLineOfFire(x, y); if (fire_dir >= 0) how_long += ramduShieldOn(); if ((x == ramdu_my_exit_x) && (y == ramdu_my_exit_y)) { direct = ramduPathTo(ramdu_prize_x,ramdu_prize_y); how_long += ramduSideStep(direct); if (how_long == 0) how_long += ramduSideStep(ramduLeft(direct)); if (how_long == 0) how_long += ramduScan(random(4), &found, &id, &dist); } else { /* Our team has the prize */ if ((x == ramdu_list[my_num].goal_x) && (y == ramdu_list[my_num].goal_y)) { if (ramduDistTo(ramdu_my_exit_x, ramdu_my_exit_y) == 1) direct = ramduDirTo(ramdu_my_exit_x, ramdu_my_exit_y); else direct = ramduOpposite(ramduDirTo(ramdu_my_exit_x, ramdu_my_exit_y)); how_long += ramduScan(direct, &found, &id, &dist); if ((found == S_PLAYER) && (id != ramdu_list[my_num].id) && (dist == 1) && (q_cannon_status() == 0) && (q_dynamite() > 0)) { ramduUseDynamite(); } else { index = ramduGetRobotAt(ramdu_my_exit_x, ramdu_my_exit_y); /*while ((found == S_PLAYER) && (id != ramdu_list[my_num].id)) */ while (index >= 0) { how_long += ramduShieldOn(); if (q_cannon_status() > 0) { attack(direct); ramduUpdateTime(2); how_long += 2; } else if (q_dynamite() > 0) { ramduUseDynamite(); for (i=0; i<2; i++) { if (ramduOnBomb(x, y) >= 0) { how_long += ramduMove(ramduOnBomb(x, y)); } else if (ramduOnBomb(x, y) == -99) { while (ramduOnBomb(x, y) == -99) { shield_on(); ramduUpdateTime(1); how_long += 1; ramduCheckBoom(); } } } index = -1; } if (index >= 0) { if (q_scanner_status() > 0) { how_long += ramduScan(direct, &found, &id, &dist); index = ramduGetRobotAt(ramdu_my_exit_x, ramdu_my_exit_y); } else if (ramduGetTeammateAt(ramdu_my_exit_x, ramdu_my_exit_y) >= 0) { index = -1; } else { if (replicate(ramduDirTo(ramdu_my_exit_x, ramdu_my_exit_y))) { ramduUpdateTime(2); how_long += 2; index = -1; } else { ramduUpdateTime(2); how_long += 2; index = ramduGetRobotAt(ramdu_my_exit_x, ramdu_my_exit_y); } } } } if (found == S_DEAD_BODY) { how_long += ramduReplicate(direct); } } if (ramduDistTo(ramdu_my_exit_x, ramdu_my_exit_y) == 1) { x = ramdu_my_exit_x; y = ramdu_my_exit_y; direct = ramduDirTo(ramdu_my_exit_x, ramdu_my_exit_y); ramduGetXY(&x, &y, 1, ramduLeft(direct)); while ((x < 1) || (x >48) || (y < 1) || (y > 48)) { x = ramdu_my_exit_x; y = ramdu_my_exit_y; direct = ramduRight(direct); ramduGetXY(&x, &y, 1, ramduLeft(direct)); } ramduSetGoal(x, y, PROTECT_EXIT); } } if (how_long == 0) { direct = ramduPathTo(ramdu_list[my_num].goal_x,ramdu_list[my_num].goal_y); how_long = ramduMove(direct); } } return(how_long); } duration ramduGetGood(int my_num) { duration how_long; direction direct; direct = ramduPathTo(ramdu_list[my_num].goal_x,ramdu_list[my_num].goal_y); how_long = ramduMove(direct); return(how_long); } duration ramduGetPrize(int my_num) { duration how_long = 0; direction direct; int found, id, dist; position x, y; int i; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; direct = ramduPathTo(ramdu_prize_x,ramdu_prize_y); if ((ramdu_prize_x == x) && (ramdu_prize_y == y)) { if (ramdu_list[my_num].scanner_pwr > 0) { how_long += ramduScan(direct, &found, &id, &dist); if (ramduGetMap(x, y, 1, direct) == DEAD_BODY) how_long += ramduMove(direct); else { how_long += ramduScan(ramduLeft(direct), &found, &id, &dist); if (ramduGetMap(x, y, 1, ramduLeft(direct)) == DEAD_BODY) how_long += ramduMove(ramduLeft(direct)); else { how_long += ramduScan(ramduRight(direct), &found, &id, &dist); if (ramduGetMap(x, y, 1, ramduRight(direct)) == DEAD_BODY) how_long += ramduMove(ramduRight(direct)); else { how_long += ramduScan(ramduOpposite(direct), &found, &id, &dist); if (ramduGetMap(x, y, 1, ramduOpposite(direct)) == DEAD_BODY) how_long += ramduMove(ramduOpposite(direct)); } } } } else { for (i=0; i<4; i++) { replicate(i); ramduUpdateTime(2); how_long += 2; } } } else { how_long += ramduResurrectNear(my_num); if ((ramduDistTo(ramdu_prize_x,ramdu_prize_y) == 1) && (ramduMap[ramdu_prize_y][ramdu_prize_x] == DEAD_BODY)) { direct = ramduDirTo(ramdu_prize_x,ramdu_prize_y); how_long += ramduReplicate(direct); } else how_long += ramduMove(direct); } return(how_long); } duration ramduReplicate(direction direct) { duration how_long = 0; ramduSetMap((position)q_wherex(), (position)q_wherey(), 1, direct, UNKNOWN); replicate(direct); ramduUpdateTime(2); how_long += 2; return(how_long); } duration ramduResurrectNear(int my_num) { int i; position x, y; duration how_long = 0; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; for (i=0; i<4; i++) if (ramduGetMap(x, y, 1, i) == DEAD_BODY) how_long += ramduReplicate(i); return(how_long); } duration ramduGoResurrect(int my_num) { duration how_long = 0; int found, id, dist; direction direct; direct = ramduPathTo(ramdu_list[my_num].goal_x,ramdu_list[my_num].goal_y); if ((ramduDistTo(ramdu_list[my_num].goal_x,ramdu_list[my_num].goal_y) == 1) && (ramduMap[ramdu_list[my_num].goal_y][ramdu_list[my_num].goal_x] == DEAD_BODY)) { direct = ramduDirTo(ramdu_list[my_num].goal_x,ramdu_list[my_num].goal_y); how_long += ramduReplicate(direct); ramduSetGoal(q_wherex(), q_wherey(), EXPLORE); } else how_long += ramduMove(direct); if ((ramduDistTo(ramdu_list[my_num].goal_x,ramdu_list[my_num].goal_y) == 0) || (ramduMap[ramdu_list[my_num].goal_y][ramdu_list[my_num].goal_x] != DEAD_BODY)) { ramduSetGoal(q_wherex(), q_wherey(), EXPLORE); } return(how_long); } duration ramduStopThief(int my_num) { duration how_long = 0; direction direct; position x, y; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; direct = ramduClearShot(x, y, ramdu_prize_x, ramdu_prize_y); if ((direct >= 0) && (ramdu_list[my_num].cannon_pwr > 0)) { if (ramduLineOfFire(x, y) >= 0) how_long += ramduShieldOn(); attack(direct); ramduUpdateTime(2); how_long += 2; } else { direct = ramduPathTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y); how_long += ramduResurrectNear(my_num); how_long += ramduMove(direct); } return(how_long); } duration ramduGoExit(int my_num) { duration how_long = 0; duration side; direction direct; position x, y; int fire_dir; int i; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; if ((ramdu_list[my_num].goal_x == x) && (ramdu_list[my_num].goal_y == y)) { use_exit(); ramduUpdateTime(1); } else { direct = ramduPathTo(ramdu_list[my_num].goal_x,ramdu_list[my_num].goal_y); fire_dir = ramduLineOfFire(x, y); if (fire_dir >= 0) how_long += ramduShieldOn(); if ((fire_dir == direct) || (fire_dir == ramduOpposite(direct))) { /* This means we're in someone's line of fire */ if (ramduDistTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y) == 1) { how_long += ramduMove(direct); x = (position)q_wherex(); y = (position)q_wherey(); if ((ramdu_list[my_num].goal_x == x) && (ramdu_list[my_num].goal_y == y)) { use_exit(); ramduUpdateTime(1); how_long += 1; } else { /* This means we didn't move, plant a bomb */ side = ramduSideStep(direct); how_long += side; if ((side == 0) && ((q_dynamite() == 0) || (ramduNumOfUs > 1))) { attack(direct); ramduUpdateTime(2); how_long+=2; attack(direct); ramduUpdateTime(2); how_long+=2; attack(direct); ramduUpdateTime(2); how_long+=2; attack(direct); ramduUpdateTime(2); how_long+=2; } else { how_long += ramduUseDynamite(); for (i=0; i<2; i++) { if (ramduOnBomb(x, y) >= 0) { how_long += ramduMove(ramduOnBomb(x, y)); } else if (ramduOnBomb(x, y) == -99) { while (ramduOnBomb(x, y) == -99) { shield_on(); ramduUpdateTime(1); how_long += 1; ramduCheckBoom(); } } } } } } else if (ramduDistTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y) <= 2) { how_long += ramduMove(direct); } else { if (how_long == 0) how_long += ramduCheck(ramduLeft(fire_dir)); if (how_long == 0) how_long += ramduCheck(ramduRight(fire_dir)); if (how_long == 0) how_long += ramduSideStep(fire_dir); if (how_long == 0) { if (fire_dir != direct) { how_long += ramduMove(direct); } else if (q_builder() > 0) { /* Build a wall to cover our rear flank! */ if (build_wall(ramduOpposite(fire_dir))) { ramduUpdateTime(4); how_long = 4; ramduSetMap(x, y, 1, ramduOpposite(fire_dir), WALL_4); ramdu_list[my_num].built_wall = ramduOpposite(fire_dir); } else { ramduUpdateTime(4); how_long = 4; how_long += ramduMove(direct); } } else how_long = ramduMove(direct); } } } else { how_long = ramduMove(direct); } } return(how_long); } duration ramduSelfPreservation(int my_num) { int i; duration how_long = 0; direction direct; position x, y; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; if (ramdu_list[my_num].goal_id >= 0) { if (q_builder() > 0) { for (i=0; i<4; i++) { if (build_wall(i)) { ramduSetMap(x, y, 1, i, WALL_4); ramdu_list[my_num].built_wall = i; } ramduUpdateTime(4); how_long += 4; } direct = ramduDirTo(ramdu_list[ramdu_list[my_num].goal_id].x, ramdu_list[ramdu_list[my_num].goal_id].y); if (ramduWallThere(x, y, 1, direct)) { for (i=0; i<50; i++) { move(direct); ramduUpdateTime(2); how_long += 2; ramdu_list[my_num].x = (position)q_wherex(); ramdu_list[my_num].y = (position)q_wherey(); } } else if (ramduWallThere(x, y, 1, ramduLeft(direct))) { for (i=0; i<50; i++) { move(ramduLeft(direct)); ramduUpdateTime(2); ramdu_list[my_num].x = (position)q_wherex(); ramdu_list[my_num].y = (position)q_wherey(); } } else if (ramduWallThere(x, y, 1, ramduRight(direct))) { for (i=0; i<50; i++) { move(ramduRight(direct)); ramduUpdateTime(2); ramdu_list[my_num].x = (position)q_wherex(); ramdu_list[my_num].y = (position)q_wherey(); } } else if (ramduWallThere(x, y, 1, ramduOpposite(direct))) { for (i=0; i<50; i++) { move(ramduOpposite(direct)); ramduUpdateTime(2); ramdu_list[my_num].x = (position)q_wherex(); ramdu_list[my_num].y = (position)q_wherey(); } } } if (ramduDistTo(ramdu_list[ramdu_list[my_num].goal_id].x, ramdu_list[ramdu_list[my_num].goal_id].y) < 5) { /* Commit suicide */ if (q_dynamite() > 0) { use_dynamite(0); ramduUpdateTime(2); how_long += 2; } else { /* This is pretty stupid, but we just move towards our teammate */ direct = ramduDirTo(ramdu_list[ramdu_list[my_num].goal_id].x, ramdu_list[ramdu_list[my_num].goal_id].y); ramduStep(direct); how_long += 2; } } else { direct = ramduPathTo(ramdu_list[ramdu_list[my_num].goal_id].x, ramdu_list[ramdu_list[my_num].goal_id].y); ramduStep(direct); how_long += 2; } } else { /* No one is qualified to save me! Hide and wait. */ if (((ramduWallThere(x, y, 1, NORTH)) || (ramduGetMap(x, y, 1, NORTH) == FLOOR)) && ((ramduWallThere(x, y, 1, EAST)) || (ramduGetMap(x, y, 1, EAST) == FLOOR)) && ((ramduWallThere(x, y, 1, SOUTH)) || (ramduGetMap(x, y, 1, SOUTH) == FLOOR)) && ((ramduWallThere(x, y, 1, WEST)) || (ramduGetMap(x, y, 1, WEST) == FLOOR))) { if ((ramduGetMap(x, y, 1, NORTH) == FLOOR) && (q_builder() > 0)) { if (build_wall(NORTH)) { ramduSetMap(x, y, 1, NORTH, WALL_4); ramdu_list[my_num].built_wall = NORTH; } ramduUpdateTime(4); how_long += 4; } else if ((ramduGetMap(x, y, 1, EAST) == FLOOR) && (q_builder() > 0)) { if (build_wall(EAST)) { ramduSetMap(x, y, 1, EAST, WALL_4); ramdu_list[my_num].built_wall = EAST; } ramduUpdateTime(4); how_long += 4; } else if ((ramduGetMap(x, y, 1, SOUTH) == FLOOR) && (q_builder() > 0)) { if (build_wall(SOUTH)) { ramduSetMap(x, y, 1, SOUTH, WALL_4); ramdu_list[my_num].built_wall = SOUTH; } ramduUpdateTime(4); how_long += 4; } else if ((ramduGetMap(x, y, 1, WEST) == FLOOR) && (q_builder() > 0)) { if (build_wall(WEST)) { ramduSetMap(x, y, 1, WEST, WALL_4); ramdu_list[my_num].built_wall = WEST; } ramduUpdateTime(4); how_long += 4; } how_long += ramduCheck(NORTH); if (how_long > 0) return(how_long); how_long += ramduCheck(EAST); if (how_long > 0) return(how_long); how_long += ramduCheck(SOUTH); if (how_long > 0) return(how_long); how_long += ramduCheck(WEST); if (how_long > 0) return(how_long); ramdu_list[my_num].checked[0] = FALSE; ramdu_list[my_num].checked[1] = FALSE; ramdu_list[my_num].checked[2] = FALSE; ramdu_list[my_num].checked[3] = FALSE; if ((ramdu_list[my_num].scanner_pwr == 0) && (random(10) == 0) && (q_builder() > 0)) { direct = random(4); if (build_wall(direct)) { ramduSetMap(x, y, 1, direct, WALL_4); ramdu_list[my_num].built_wall = direct; } ramduUpdateTime(4); how_long += 4; } how_long += ramduScanHere(my_num); } else how_long += ramduExplore(my_num); } return(how_long); } duration ramduPursue(int my_num) { int found, id, dist; duration how_long; direction direct; direct = ramduPathTo(ramdu_list[my_num].goal_x,ramdu_list[my_num].goal_y); if (ramduDistTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y) < 3) { how_long = ramduCheck(ramduLeft(direct)); if (how_long > 0) return(how_long); how_long = ramduCheck(ramduRight(direct)); if (how_long > 0) return(how_long); if (ramduDistTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y) == 0) { /* This means we lost the other robot */ ramdu_list[my_num].goal = EXPLORE; ramdu_list[my_num].goal_id = 0; ramdu_list[my_num].goal_dur = 0; how_long += ramduScan(direct, &found, &id, &dist); } else { how_long = ramduMove(direct); } } else { how_long = ramduMove(direct); } return(how_long); } duration ramduAttack(int my_num) { int found, id, dist; duration how_long = 0; int i; position x, y; distance distant; direction direct; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; distant = ramduDistTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y); direct = ramduDirTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y); how_long = ramduShieldOn(); if (how_long > 0) { /* This is a new target, shoot three times, then check to see if they're still there */ ramdu_list[my_num].goal_dur = 3; ramdu_list[my_num].fire = ramdu_list[my_num].goal_dur; ramduSetShooting(x, y, direct); } else if (ramdu_list[my_num].fire == 0) { /* We had to scan this round */ how_long = ramduScan(direct, &found, &id, &dist); if (((found == S_ENEMY) && (ramdu_prize_x < 0)) || ((found == S_PLAYER) && (id != ramdu_list[my_num].id))) { ramduGetXY(&x, &y, dist, direct); ramdu_list[my_num].goal_x = x; ramdu_list[my_num].goal_y = y; ramdu_list[my_num].goal_id = id; /*ramdu_list[my_num].goal_dur += 1;*/ if (found == S_ENEMY) ramdu_list[my_num].goal_dur = 5; else { if (dist < 3) ramdu_list[my_num].goal_dur = dist; else ramdu_list[my_num].goal_dur = 3; } ramdu_list[my_num].fire = ramdu_list[my_num].goal_dur; ramduSetShooting(x, y, direct); } else if (found == S_MINE) { /* Back up to be able to scan past the mine */ how_long = ramduMove(ramduOpposite(direct)); /* If we can't move here, then side step. */ if (how_long == 0) how_long = ramduSideStep(direct); } else if ((found == S_WALL) && (dist < distant)) { /* The player used a wall to block me, shoot through it */ /* This violates the rule of only one move per turn */ for (i=0; i<=id; i++) { attack(direct); ramduUpdateTime(2); how_long+=2; } } else { ramduUnsetLineOfFire(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y); ramduUnsetLineOfFire(ramdu_list[my_num].x, ramdu_list[my_num].y); if (ramduDistTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y) < 4) { ramdu_list[my_num].goal = PURSUE; x = ramdu_list[my_num].goal_x; y = ramdu_list[my_num].goal_y; ramduGetXY(&x, &y, 1, direct); if ((ramduMap[y][x] != LAND_MINE) && (!ramduWallThere(x, y, 0, 0))) { ramdu_list[my_num].goal_x = x; ramdu_list[my_num].goal_y = y; } } else { ramdu_list[my_num].goal = EXPLORE; ramdu_list[my_num].goal_id = 0; /* Dont turn off shield if we scanned an enemy, but we know where the prize is */ if ((found != S_ENEMY) || (ramdu_prize_x < 0)) { /* This violates my rule of only one time function per loop */ if (q_shield_active()) { shield_off(); ramduUpdateTime(1); how_long++; } } ramdu_list[my_num].goal_dur = 0; ramdu_list[my_num].fire = ramdu_list[my_num].goal_dur; } } } else { direct = ramduClearShot((position)q_wherex(), (position)q_wherey(), ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y); if (direct >= 0) { ramdu_list[my_num].goal_id = id; ramdu_list[my_num].fire--; if (ramdu_list[my_num].cannon_pwr == 0) { if (ramduDistTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y) == 1) how_long = ramduUseDynamite(); else how_long = ramduSideStep(direct); } else attack(direct); ramduUpdateTime(2); how_long = 2; } else { ramduUnsetLineOfFire(ramdu_list[my_num].x, ramdu_list[my_num].y); ramdu_list[my_num].goal = EXPLORE; if (q_shield_active()) { shield_off(); ramduUpdateTime(1); how_long++; } ramdu_list[my_num].goal_dur = 0; ramdu_list[my_num].fire = 0; } } return(how_long); } duration ramduShieldOn() { duration how_long = 0; if ((!q_shield_active()) && (q_shield_power() > 0)) { shield_on(); ramduUpdateTime(1); how_long = 1; } return(how_long); } boolean ramduStep(direction dir) { int i; position x, y; boolean step_worked; int my_num; boolean something_behind = FALSE; my_num = q_my_num(); ramdu_list[my_num].prev_x[1] = ramdu_list[my_num].prev_x[0]; ramdu_list[my_num].prev_y[1] = ramdu_list[my_num].prev_y[0]; ramdu_list[my_num].prev_x[0] = ramdu_list[my_num].x; ramdu_list[my_num].prev_y[0] = ramdu_list[my_num].y; /* Set my position to my new desired position, to inform teammates */ x = (position)q_wherex(); y = (position)q_wherey(); ramduGetXY(&x, &y, 1, dir); ramdu_list[my_num].x = x; ramdu_list[my_num].y = y; if (!move(dir)) { step_worked = FALSE; ramduUpdateTime(2); x = ramdu_list[my_num].x = (position)q_wherex(); y = ramdu_list[my_num].y = (position)q_wherey(); ramduMap[y][x] = UNKNOWN; } else { step_worked = TRUE; x = ramdu_list[my_num].x = (position)q_wherex(); y = ramdu_list[my_num].y = (position)q_wherey(); ramduUpdateTime(2); if ((ramduGetMap(x, y, 1, 0) == FLOOR) || (ramduGetMap(x, y, 1, 0) == UNKNOWN) || (ramduGetMap(x, y, 1, 0) == FLOOR_OR_MINE)) ramdu_list[my_num].checked[0] = FALSE; if ((ramduGetMap(x, y, 1, 1) == FLOOR) || (ramduGetMap(x, y, 1, 1) == UNKNOWN) || (ramduGetMap(x, y, 1, 1) == FLOOR_OR_MINE)) ramdu_list[my_num].checked[1] = FALSE; if ((ramduGetMap(x, y, 1, 2) == FLOOR) || (ramduGetMap(x, y, 1, 2) == UNKNOWN) || (ramduGetMap(x, y, 1, 2) == FLOOR_OR_MINE)) ramdu_list[my_num].checked[2] = FALSE; if ((ramduGetMap(x, y, 1, 3) == FLOOR) || (ramduGetMap(x, y, 1, 3) == UNKNOWN) || (ramduGetMap(x, y, 1, 3) == FLOOR_OR_MINE)) ramdu_list[my_num].checked[3] = FALSE; for (i=1; i<10; i++) if ((ramduGetMap(x, y, i, ramduOpposite(dir)) != FLOOR) && (ramduGetMap(x, y, i, ramduOpposite(dir)) != FLOOR_OR_MINE)) something_behind = TRUE; if (((ramdu_list[my_num].cannon_pwr+ramdu_list[my_num].scanner_pwr) > POWER) && (something_behind)) ramdu_list[my_num].checked[ramduOpposite(dir)] = TRUE; } return(step_worked); } duration ramduMove(direction dir) { position x, y; position test_x, test_y; int found, id, dist; int cannon_pwr; int scanner_pwr; duration how_long = 0; int num_dynamite; int friend_there; int my_num; int index; x = (position)q_wherex(); y = (position)q_wherey(); my_num = q_my_num(); num_dynamite = q_dynamite(); cannon_pwr = q_cannon_status(); scanner_pwr = q_scanner_status(); ramduGetXY(&x, &y, 1, dir); friend_there = ramduGetTeammateAt(x, y); index = ramduGetRobotAt(x, y); if (ramduSafe(x, y)) { if (!ramduStep(dir)) ramduMap[y][x] = UNKNOWN; how_long += 2; } else if (friend_there >= 0) { /* This is dodging */ if ((ramdu_list[my_num].goal == PROTECT_PRIZE) || (ramdu_list[my_num].goal == PROTECT_EXIT)) { attack(ramduOpposite(dir)); ramduUpdateTime(2); how_long = 2; } else how_long = ramduSideStep(dir); } else if (index >= 0) { if (cannon_pwr > 0) { attack(dir); ramduUpdateTime(2); how_long = 2; } else { if (num_dynamite > 0) how_long = ramduUseDynamite(); else how_long = ramduSideStep(dir); } } else switch (ramduMap[y][x]) { case FLOOR: case REPAIR: case GOOD: case BOOM: /* This means we're moving into a dangerous spot. */ /* If the next step is in the line of fire from the side and we're */ /* currently not in a line of fire, then scan across, and run across */ if (((ramduLineOfFire(x, y) == ramduLeft(dir)) || (ramduLineOfFire(x, y) == ramduRight(dir))) && (ramduLineOfFire((position)q_wherex(), (position)q_wherey()) < 0) && (scanner_pwr > 0)) { /* That's in the line of fire, don't go there, unless we can run across */ test_x = x; test_y = y; ramduGetXY(&test_x, &test_y, 1, dir); if ((ramduMap[test_y][test_x] == UNKNOWN) || (ramduMap[test_y][test_x] == FLOOR_OR_MINE)) { how_long = ramduScan(dir, &found, &id, &dist); } else if (ramduWallThere(test_x, test_y, 0, 0)) { attack(dir); ramduUpdateTime(2); how_long+=2; ramduMap[test_y][test_x] -= 2; } else if (ramduMap[test_y][test_x] == LAND_MINE) { how_long = ramduScan(ramduRight(dir), &found, &id, &dist); how_long += ramduScan(ramduLeft(dir), &found, &id, &dist); } else { if (!ramduStep(dir)) ramduMap[y][x] = UNKNOWN; how_long += 2; } } else { if (!ramduStep(dir)) ramduMap[y][x] = UNKNOWN; how_long += 2; } break; case DEAD_BODY: how_long += ramduReplicate(dir); break; case UNKNOWN: case FLOOR_OR_MINE: if (scanner_pwr > 0) how_long = ramduScan(dir, &found, &id, &dist); else { if (!ramduStep(dir)) { how_long += 2; how_long += ramduReplicate(dir); if (ramduMap[y][x] == UNKNOWN) { attack(dir); ramduUpdateTime(2); how_long += 2; } } else { how_long += 2; } } break; case WALL_1: case WALL_2: case WALL_3: case WALL_4: if (cannon_pwr > 0) { attack(dir); ramduUpdateTime(2); how_long = 2; ramduMap[y][x]-=2; } else { if (num_dynamite > 0) how_long = ramduUseDynamite(); else how_long = ramduSideStep(dir); } break; case LAND_MINE: if (num_dynamite > 0) how_long = ramduUseDynamite(); else how_long = ramduSideStep(dir); break; } return(how_long); } duration ramduCheck(direction dir) { int found, id, dist; position x, y; int i; int index; duration how_long = 0; int my_num; my_num = q_my_num(); x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; i = 1; if (dir < 0) return(-1); if ((((ramdu_my_exit_x >= 0) && (ramdu_list[my_num].highway_index < 0)) || (ramdu_list[my_num].goal == SELF_PRESERVATION)) && (!ramdu_list[my_num].checked[dir]) && (ramdu_list[my_num].scanner_pwr > 0)) { how_long = ramduScan(dir, &found, &id, &dist); return(how_long); } ramduGetXY(&x, &y, 1, dir); /* Check to see how far we have mapped out */ while ((ramduMap[y][x] == FLOOR) || ((ramduMap[y][x] == FLOOR_OR_MINE) && (i > 2)) || ((ramduMap[y][x] == LAND_MINE) && (i > 2))) { if ((x == ramdu_prize_x) && (y == ramdu_prize_y)) { return(how_long); } index = ramduGetExitAt(x, y); if (index >= 0) { return(how_long); } index = ramduGetTeammateAt(x, y); if (index >= 0) { return(how_long); } index = ramduGetRobotAt(x, y); /* If there is a robot there, as far as we know. */ if (index >= 0) { /* If the time we saw this robot was less than ROBOT_AGE moves ago, then don't scan */ if (((ramduTime - ramdu_robot[index].time) > ROBOT_AGE) && (ramdu_list[my_num].scanner_pwr > 0)) { how_long = ramduScan(dir, &found, &id, &dist); return(how_long); } else { return(how_long); } } i++; ramduGetXY(&x, &y, 1, dir); } if ((x == ramdu_prize_x) && (y == ramdu_prize_y)) { return(how_long); } index = ramduGetExitAt(x, y); if (index >= 0) { return(how_long); } index = ramduGetTeammateAt(x, y); if (index >= 0) { return(how_long); } index = ramduGetRobotAt(x, y); /* If there is a robot there, as far as we know. */ if (index >= 0) { /* If the time we saw this robot was less than ROBOT_AGE moves ago, then don't scan */ if (((ramduTime - ramdu_robot[index].time) > ROBOT_AGE) && (ramdu_list[my_num].scanner_pwr > 0)) { how_long = ramduScan(dir, &found, &id, &dist); return(how_long); } else { return(how_long); } } if (ramduMap[y][x] >= BOOM) { dist = i; } else if ((ramduMap[y][x] == FLOOR_OR_MINE) || (ramduMap[y][x] == UNKNOWN)) { if (ramdu_list[my_num].scanner_pwr > 0) how_long = ramduScan(dir, &found, &id, &dist); } return(how_long); } duration ramduScan(direction dir, int *found, int *id, int *dist) { int i; int sum; int index; position x, y; position test_x, test_y; duration how_long = 1; int my_num; boolean can_see_me = TRUE; my_num = q_my_num(); ramdu_list[my_num].checked[dir] = TRUE; if (scan(dir, found, id, dist)) { ramduUpdateTime(1); x = (position)q_wherex(); y = (position)q_wherey(); /* set all squares up to found object = FLOOR */ for (i=1; i<*dist; i++) { test_x = x; test_y = y; ramduGetXY(&test_x, &test_y, i, dir); index = ramduGetRobotAt(test_x, test_y); if (index >= 0) { if (ramdu_robot[index].id == ramdu_list[my_num].goal_id) { /* ramdu_list[my_num].goal_id = 0; */ ramdu_list[my_num].goal_dur = 0; } ramdu_robot[index].lost = TRUE; } if (i<3) { ramduSetMap(x, y, i, dir, FLOOR); } else { if (ramduGetMap(x, y, i, dir) == UNKNOWN) ramduSetMap(x, y, i, dir, FLOOR_OR_MINE); else if ((ramduGetMap(x, y, i, dir) != LAND_MINE) && (ramduGetMap(x, y, i, dir) != FLOOR_OR_MINE)) ramduSetMap(x, y, i, dir, FLOOR); } } ramduGetXY(&x, &y, *dist, dir); switch(*found) { case S_EXIT: ramduMap[y][x] = FLOOR; ramduSetExit(x, y, (identification)*id); break; case S_MY_EXIT: ramduMap[y][x] = FLOOR; ramduSetExit(x, y, (identification)q_my_id()); break; case S_WALL: if ((y > 0) && (y < 49) && (x > 0) && (x < 49)) ramduMap[y][x] = WALL_0 + (*id * 2); break; case S_BOOM: if (ramdu_num_boom == (NUM_BOOMS-1)) { index = 0; while (ramdu_boom_time[index] >= 0) index++; } else index = ramdu_num_boom; ramduMap[y][x] = BOOM+index; ramdu_boom_time[index] = ramduTime + *id; if (*id <= 6) { index = ramduPropogateBoom(x, y, index); if (index >= ramdu_num_boom) ramdu_num_boom++; } else if (index == ramdu_num_boom) { ramdu_num_boom++; if (ramdu_num_boom >= NUM_BOOMS) ramdu_num_boom = NUM_BOOMS-1; } break; case S_MINE: ramduMap[y][x] = LAND_MINE; break; case S_DEAD_BODY: index = ramduGetRobotAt(x, y); if (index >= 0) { ramdu_robot[index].lost = TRUE; } ramduMap[y][x] = DEAD_BODY; break; case S_PRIZE: ramdu_prize_x = x; ramdu_prize_y = y; ramduMap[y][x] = FLOOR; break; case S_DYNAMITE: if (q_dynamite() < 5) ramduMap[y][x] = REPAIR; else ramduMap[y][x] = GOOD; break; case S_BUILDER: if (q_builder() < 5) ramduMap[y][x] = REPAIR; else ramduMap[y][x] = GOOD; break; case S_REPAIR: ramduMap[y][x] = REPAIR; break; case S_ENEMY: ramdu_num_computer_sightings++; ramduSetRobot(x, y, *id, ENEMY_ROBOT); if (ramduMap[y][x] == DEAD_BODY) ramduMap[y][x] = FLOOR; if ((ramdu_my_exit_x >= 0) && (ramdu_prize_x < 0) && ((((ramduNumOfUs > ATTACK_COMPUTER_ON_SIGHT) || ((ramduNumOfUs == ATTACK_COMPUTER_ON_SIGHT) && (ramduNumComputers() < 6))) && (!ramdu_list[my_num].strongest)) || ((ramduDist(x, y, ramdu_my_exit_x, ramdu_my_exit_y) < (3+(max(0,(4-ramduNumComputers()))*3))) && (ramdu_list[my_num].highway_index < 0))) && (ramdu_list[my_num].cannon_pwr > 0)) { /* We know where our exit is, but we don't know where the prize is */ ramdu_list[my_num].goal_id = (identification)*id; if (ramdu_list[my_num].goal < ATTACK) { ramdu_list[my_num].goal = ATTACK; ramdu_list[my_num].goal_x = x; ramdu_list[my_num].goal_y = y; } } else { for (i=1; i<*dist; i++) { if (ramduGetMap(ramdu_list[my_num].x, ramdu_list[my_num].y, i, dir) == LAND_MINE) can_see_me = FALSE; } if (can_see_me) ramduSetShooting(x, y, ramduOpposite(dir)); } break; case S_PLAYER: ramdu_num_player_sightings++; ramduSetSaw(*id); ramduSetRobot(x, y, *id, PLAYER_ROBOT); if (ramduMap[y][x] == DEAD_BODY) ramduMap[y][x] = FLOOR; /* (ramdu_my_exit_x >= 0) && */ if ((*id != q_my_id()) && (ramdu_list[my_num].cannon_pwr > 0) && (!ramdu_list[my_num].strongest) && ((ramduNumOfUs > ATTACK_PLAYER_ON_SIGHT) || ((ramduNumOfUs == ATTACK_PLAYER_ON_SIGHT) && ((ramdu_list[my_num].cannon_pwr+ramdu_list[my_num].scanner_pwr) > 200)))) { ramdu_list[my_num].goal_id = (identification)*id; if (ramdu_list[my_num].goal < ATTACK) { ramdu_list[my_num].goal = ATTACK; ramdu_list[my_num].goal_x = x; ramdu_list[my_num].goal_y = y; } } else if ((*id != q_my_id()) && (ramdu_list[my_num].cannon_pwr > 0) && (ramdu_list[my_num].highway_index < 0) && (ramduGetAggression(*id) < 0.05) && ((ramdu_list[my_num].cannon_pwr+ramdu_list[my_num].scanner_pwr) > 200)) { /* Attacking a passive bot */ ramdu_list[my_num].goal_id = (identification)*id; if (ramdu_list[my_num].goal < ATTACK) { ramdu_list[my_num].goal = ATTACK; ramdu_list[my_num].goal_x = x; ramdu_list[my_num].goal_y = y; } } /* This means play chicken until we've mapped out our highways */ /* else if (ramdu_list[my_num].highway_index >= 0) */ else if (ramduGetAggression(*id) > 0.1) { ramduSetShooting(x, y, ramduOpposite(dir)); if ((ramduGetAggression(*id) > 0.25) && (*dist > 1)) { ramduGetXY(&x, &y, 1, ramduLeft(dir)); ramduSetShooting(x, y, ramduOpposite(dir)); ramduGetXY(&x, &y, 2, ramduRight(dir)); ramduSetShooting(x, y, ramduOpposite(dir)); } else if ((ramduGetAggression(*id) > 0.25) && (*dist == 1)) { ramduSetShooting(x, y, ramduRight(dir)); ramduSetShooting(x, y, ramduLeft(dir)); } } break; default: break; } } else { *found = -1; *dist = 0; *id = 0; ramduUpdateTime(1); } return(how_long); } int ramduNumComputers() { if (ramdu_num_player_sightings > 0) return((ramdu_num_computer_sightings*5)/ramdu_num_player_sightings); else return(ramdu_num_computer_sightings*5); } duration ramduScanHere(int my_num) { position x, y; duration how_long = 1; int here; x = ramdu_list[my_num].x; y = ramdu_list[my_num].y; here = what_am_i_on(); ramduUpdateTime(1); switch(here) { case S_EXIT: ramduMap[y][x] = FLOOR; /* what_am_i_on doesn't return an id, so we'll skip adding this to our list */ /* ramduSetExit(x, y, (identification)0); */ break; case S_MY_EXIT: ramduMap[y][x] = FLOOR; ramduSetExit(x, y, (identification)q_my_id()); break; case S_BOOM: /* We can't tell how long the bomb is set for, set this as a mine */ if (ramduMap[y][x] < BOOM) ramduMap[y][x] = LAND_MINE; break; case S_PRIZE: ramdu_prize_x = x; ramdu_prize_y = y; ramduMap[y][x] = FLOOR; break; case S_DYNAMITE: case S_BUILDER: ramduMap[y][x] = GOOD; break; case S_REPAIR: ramduMap[y][x] = REPAIR; break; case S_NOTHING: ramduMap[y][x] = FLOOR; break; default: break; } return(how_long); } void ramduSetMap(position x, position y, int offset, direction dir, int value) { switch (dir) { case NORTH: ramduMap[y-offset][x] = (unsigned char)value; break; case SOUTH: ramduMap[y+offset][x] = (unsigned char)value; break; case EAST: ramduMap[y][x+offset] = (unsigned char)value; break; case WEST: ramduMap[y][x-offset] = (unsigned char)value; break; } } unsigned char ramduGetMap(position x, position y, int offset, direction dir) { switch (dir) { case NORTH: return(ramduMap[y-offset][x]); case SOUTH: return(ramduMap[y+offset][x]); case EAST: return(ramduMap[y][x+offset]); case WEST: return(ramduMap[y][x-offset]); } /* Should never get here */ return(-1); } boolean ramduWallThere(position x, position y, int offset, direction dir) { if ((ramduGetMap(x, y, offset, dir) == WALL_1) || (ramduGetMap(x, y, offset, dir) == WALL_2) || (ramduGetMap(x, y, offset, dir) == WALL_3) || (ramduGetMap(x, y, offset, dir) == WALL_4) || (ramduGetMap(x, y, offset, dir) == OUTSIDE_WALL)) return(TRUE); else return(FALSE); } void ramduGetXY(position *x, position *y, distance offset, direction dir) { switch (dir) { case NORTH: *y -= offset; break; case SOUTH: *y += offset; break; case EAST: *x += offset; break; case WEST: *x -= offset; break; } } int ramduDistTo(position x, position y) { return(abs((position)q_wherex()-x) + abs((position)q_wherey()-y)); } int ramduDist(position from_x, position from_y, position to_x, position to_y) { return(abs(from_x-to_x) + abs(from_y-to_y)); } direction ramduDirTo(position x, position y) { if (abs((position)q_wherey()-y) > abs((position)q_wherex()-x)) if ((position)q_wherey() > y) return(NORTH); else return(SOUTH); else if ((position)q_wherex() > x) return(WEST); else return(EAST); } direction ramduDir(position from_x, position from_y, position to_x, position to_y) { if (abs(from_y-to_y) > abs(from_x-to_x)) if (from_y > to_y) return(NORTH); else return(SOUTH); else if (from_x > to_x) return(WEST); else return(EAST); } direction ramduClearShot(position from_x, position from_y, position to_x, position to_y) { direction direct = -1; int i; /* This will return the direct to shoot, if there is a clear shot */ if (from_x == to_x) { if (from_y > to_y) { direct = NORTH; for (i=from_y-1; i>to_y; i--) if (!ramduShootOver(from_x, i)) direct = -1; } else { direct = SOUTH; for (i=from_y+1; i to_x) { direct = WEST; for (i=from_x-1; i>to_x; i--) if (!ramduShootOver(i, from_y)) direct = -1; } else { direct = EAST; for (i=from_x+1; i 10) { to_x -= ((to_x-x)/2); to_y -= ((to_y-y)/2); } index = ramduCourseTo(to_x, to_y, ramdu_path, ramdu_used); return(ramdu_path[index].dir); } int ramduTimeTo(position to_x, position to_y) { int index; position x, y; int multiplier = 1; ramduPath ramdu_path[MAX_PATHS]; ramduUsed ramdu_used[MAX_USED]; x = (position)q_wherex(); y = (position)q_wherey(); if ((x == to_x) && (y == to_y)) { /* return(ramduCostHere(x, y)); */ return(0); } while (ramduDistTo(to_x, to_y) > 10) { multiplier *= 2; to_x -= ((to_x-x)/2); to_y -= ((to_y-y)/2); } index = ramduCourseTo(to_x, to_y, ramdu_path, ramdu_used); return((ramdu_path[index].cost_to + (ramduDist(ramdu_path[index].x, ramdu_path[index].y, to_x, to_y)*(EST_FLOOR))) * multiplier); } int ramduCourseTo(position to_x, position to_y, ramduPath *ramdu_path, ramduUsed *ramdu_used) { int i; direction dir_to; direction dir; position x, y; int cost_to; int here = 0; int num_path = 0; int est_floor = EST_FLOOR; int my_num; my_num = q_my_num(); x = (position)q_wherex(); y = (position)q_wherey(); dir_to = ramduDirTo(to_x, to_y); here = ramduCostHere(x, y); for (i=0; i 1)); i++) { /* Pull the bottom (best) path off the list */ num_path--; dir = ramdu_path[num_path].dir; x = ramdu_path[num_path].x; y = ramdu_path[num_path].y; cost_to = ramdu_path[num_path].cost_to; /* cost = ramdu_path[num_path].cost; */ ramdu_path[num_path].x = -1; ramdu_path[num_path].cost_to = BIG_DIST; num_path = ramduAddPath(num_path, dir_to, dir, x, y-1, cost_to, to_x, to_y, ramdu_path, ramdu_used, est_floor); num_path = ramduAddPath(num_path, dir_to, dir, x+1, y, cost_to, to_x, to_y, ramdu_path, ramdu_used, est_floor); num_path = ramduAddPath(num_path, dir_to, dir, x, y+1, cost_to, to_x, to_y, ramdu_path, ramdu_used, est_floor); num_path = ramduAddPath(num_path, dir_to, dir, x-1, y, cost_to, to_x, to_y, ramdu_path, ramdu_used, est_floor); } if (ramduDist(ramdu_path[num_path-1].x, ramdu_path[num_path-1].y, to_x, to_y) == 1) { ramdu_path[num_path-1].x = to_x; ramdu_path[num_path-1].y = to_y; ramdu_path[num_path-1].cost_to += ramduCostHere(to_x, to_y); } return(num_path-1); } int ramduAddPath(int num_path, direction dir_to, direction dir, position x, position y, int cost_to, position to_x, position to_y, ramduPath *ramdu_path, ramduUsed *ramdu_used, int est_floor) { int i,j; int here; int total_cost; if ((y == 0) || (y == 49) || (x == 0) || (x == 49)) return(num_path); for (i=0; ((i= 0) && ((ramdu_used[i].x != x) || (ramdu_used[i].y != y))); i++) { } if ((i= 0)) { /* We found it in the list */ here = ramdu_used[i].here; cost_to += here; if ((ramdu_used[i].cost_to <= cost_to)) { return(num_path); } else { ramdu_used[i].dir = dir; ramdu_used[i].x = x; ramdu_used[i].y = y; ramdu_used[i].cost_to = cost_to; ramdu_used[i].here = here; } } else if (i < MAX_USED) { here = ramduCostHere(x, y); cost_to += here; ramdu_used[i].dir = dir; ramdu_used[i].x = x; ramdu_used[i].y = y; ramdu_used[i].cost_to = cost_to; ramdu_used[i].here = here; } else { here = ramduCostHere(x, y); cost_to += here; for (j=1; j total_cost) || ((ramdu_path[i].total_cost == total_cost) && (ramdu_path[i].dir != dir_to)))); i++) { } */ for(i=num_path-1; ((i >= 0) && ((ramdu_path[i].total_cost < total_cost) || ((ramdu_path[i].total_cost == total_cost) && (dir != dir_to)))); i--) { } i++; if (num_path == MAX_PATHS) { /* We have to shift the list up to insert it. */ for(j=0; (j<(i-1)); j++) { if (ramdu_path[j+1].x >= 0) { /* Shift the list up */ ramdu_path[j].dir = ramdu_path[j+1].dir; ramdu_path[j].x = ramdu_path[j+1].x; ramdu_path[j].y = ramdu_path[j+1].y; ramdu_path[j].cost_to = ramdu_path[j+1].cost_to; ramdu_path[j].total_cost = ramdu_path[j+1].total_cost; } } if (i == MAX_PATHS) i--; /* We're adding it to the bottom of the list */ } else { if (i < num_path) { /* We need to shift the rest of the list down */ for(j=(num_path); (j>i); j--) { /* Shift the list up */ ramdu_path[j].dir = ramdu_path[j-1].dir; ramdu_path[j].x = ramdu_path[j-1].x; ramdu_path[j].y = ramdu_path[j-1].y; ramdu_path[j].cost_to = ramdu_path[j-1].cost_to; ramdu_path[j].total_cost = ramdu_path[j-1].total_cost; } } num_path++; } ramdu_path[i].dir = dir; ramdu_path[i].x = x; ramdu_path[i].y = y; ramdu_path[i].cost_to = cost_to; ramdu_path[i].total_cost = total_cost; return (num_path); } int ramduCostHere(position x, position y) { int index; position test_x, test_y; int here = 0; int my_num; my_num = q_my_num(); here = ramduMap[y][x]; if ((ramduOnBomb(x, y) >= 0) || (ramduOnBomb(x, y) == -99)) { here += LINE_OF_FIRE; } else if (ramduMap[y][x] >= BOOM) here = FLOOR; if ((ramduLineOfFire(x, y) >= 0) && ((ramdu_list[my_num].goal <= STOP_THIEF) || (ramdu_list[my_num].goal == GOT_PRIZE))) { here += LINE_OF_FIRE; } if (ramduRobotThere(x, y)) here += DEAD_BODY; if ((ramdu_list[my_num].cannon_pwr == 0) && (ramduWallThere(x, y, 0, 0))) here = LAND_MINE; if ((q_dynamite() == 0) && (here == LAND_MINE)) here += LAND_MINE; if (((ramdu_list[my_num].goal == PROTECT_PRIZE) || (ramdu_list[my_num].goal == PROTECT_EXIT)) && (ramdu_my_exit_x >= 0)) { /* Don't move onto my exit if I'm not the one with the prize */ if ((x == ramdu_my_exit_x) && (y == ramdu_my_exit_y)) here += LINE_OF_FIRE; /* Don't move to the spot directly in front of our teammate with the prize */ test_x = ramdu_prize_x; test_y = ramdu_prize_y; ramduGetXY(&test_x, &test_y, 1, ramduDir(ramdu_prize_x, ramdu_prize_y, ramdu_my_exit_x, ramdu_my_exit_y)); if ((x == test_x) && (y == test_y)) here += LINE_OF_FIRE; } if ((ramdu_list[my_num].goal == GOT_PRIZE) || (ramdu_list[my_num].goal == STOP_THIEF) || (ramdu_list[my_num].goal == GET_PRIZE)) { if (here == UNKNOWN) here = GOTPRIZE_UNKNOWN; else if (here == FLOOR_OR_MINE) here = GOTPRIZE_FLOOR_OR_MINE; } return(here); } boolean ramduSafe(position x, position y) { if (ramduSafeSpot(x, y)) { if (ramduLineOfFire(x, y) >= 0) return(FALSE); else if ((ramduOnBomb(x, y) >= 0) || (ramduOnBomb(x, y) == -99)) return(FALSE); else return(TRUE); } else return(FALSE); } boolean ramduSafeSpot(position x, position y) { if ((ramduMap[y][x] == FLOOR) || (ramduMap[y][x] == GOOD) || (ramduMap[y][x] == REPAIR) || (ramduMap[y][x] >= BOOM)) return(TRUE); else return(FALSE); } boolean ramduRobotThere(position x, position y) { int index; index = ramduGetTeammateAt(x, y); if (index >= 0) return(TRUE); index = ramduGetRobotAt(x, y); if (index >= 0) return(TRUE); return(FALSE); } direction ramduOnBomb(position x, position y) { int i; direction path[4]; int num_path = 0; direction dir_to; int my_num; int time; my_num = q_my_num(); /* If this spot is within a bomb damage area, */ /* then return direct to travel to get away from it */ time = ramduTimeToBoom(x, y); if (time >= 0) { dir_to = ramduDirTo(ramdu_list[my_num].goal_x, ramdu_list[my_num].goal_y); if ((time <= 2) && (ramduMap[y][x] < BOOM)) { num_path = 0; for (i=0; i<4; i++) if (ramduNoBoom(x, y, i, 2, 1)) path[num_path++] = i; if (num_path > 0) { for (i=0; i 0) { for (i=0; i 0) { for (i=0; i= BOOM) { /* We're on a boom */ num_path = 0; if ((ramduSafeSpot(x, y-1)) && (ramduMap[y-1][x] < BOOM) && (!ramduRobotThere(x, y-1))) path[num_path++] = NORTH; if ((ramduSafeSpot(x, y+1)) && (ramduMap[y+1][x] < BOOM) && (!ramduRobotThere(x, y+1))) path[num_path++] = SOUTH; if ((ramduSafeSpot(x-1, y)) && (ramduMap[y][x-1] < BOOM) && (!ramduRobotThere(x-1, y))) path[num_path++] = WEST; if ((ramduSafeSpot(x+1, y)) && (ramduMap[y][x+1] < BOOM) && (!ramduRobotThere(x+1, y))) path[num_path++] = EAST; if (num_path > 0) { for (i=0; i 0) && (test_y < 49) && (test_x > 0) && (test_x < 49)) { time = ramduTimeToBoom(test_x, test_y); if (((time < 0) || (time > limit)) && (ramduSafeSpot(test_x, test_y)) && (!ramduRobotThere(test_x, test_y))) return_value = TRUE; else return_value = FALSE; } else return_value = FALSE; } return(return_value); } duration ramduSideStep(direction direct) { position x, y; int my_num; duration how_long = 0; x = (position)q_wherex(); y = (position)q_wherey(); my_num = q_my_num(); if ((direct == NORTH) || (direct == SOUTH)) { if (ramdu_list[my_num].goal_x < x) { ramduGetXY(&x, &y, 1, WEST); if (ramduSafe(x, y)) how_long = ramduMove(WEST); else { ramduGetXY(&x, &y, 2, EAST); if (ramduSafe(x, y)) how_long = ramduMove(EAST); } return(how_long); } else if (ramdu_list[my_num].goal_x > x) { ramduGetXY(&x, &y, 1, EAST); if (ramduSafe(x, y)) how_long = ramduMove(EAST); else { ramduGetXY(&x, &y, 2, WEST); if (ramduSafe(x, y)) how_long = ramduMove(WEST); } return(how_long); } } else if ((direct == EAST) || (direct == WEST)) { if (ramdu_list[my_num].goal_y < y) { ramduGetXY(&x, &y, 1, NORTH); if (ramduSafe(x, y)) how_long = ramduMove(NORTH); else { ramduGetXY(&x, &y, 2, SOUTH); if (ramduSafe(x, y)) how_long = ramduMove(SOUTH); } return(how_long); } else if (ramdu_list[my_num].goal_y > y) { ramduGetXY(&x, &y, 1, NORTH); if (ramduSafe(x, y)) how_long = ramduMove(NORTH); else { ramduGetXY(&x, &y, 2, SOUTH); if (ramduSafe(x, y)) how_long = ramduMove(SOUTH); } return(how_long); } } if (how_long == 0) { if (random(2) == 0) { ramduGetXY(&x, &y, 1, ramduLeft(direct)); if (ramduSafe(x, y)) how_long = ramduMove(ramduLeft(direct)); else { ramduGetXY(&x, &y, 2, ramduRight(direct)); if (ramduSafe(x, y)) how_long = ramduMove(ramduRight(direct)); } } else { ramduGetXY(&x, &y, 1, ramduRight(direct)); if (ramduSafe(x, y)) how_long = ramduMove(ramduRight(direct)); else { ramduGetXY(&x, &y, 2, ramduLeft(direct)); if (ramduSafe(x, y)) how_long = ramduMove(ramduLeft(direct)); } } } return(how_long); } boolean ramduShootOver(position x, position y) { unsigned char value; int index; int my_num; value = ramduMap[y][x]; my_num = q_my_num(); if ((value == FLOOR) || (value == GOOD) || (value == REPAIR) || (value == LAND_MINE) || (value == BOOM) || (value == FLOOR_OR_MINE) || (value == UNKNOWN)) { index = ramduGetTeammateAt(x, y); if ((index >= 0) && (index != my_num)) { /* If one of our guys is in the way, then it's not safe to shoot over this spot */ return(FALSE); } return(TRUE); } else return(FALSE); } int ramduSetSaw(identification id) { int index; for (index=0; ((index < ramdu_num_exits) && (index < NUM_PLAYERS) && (ramdu_exit[index].id != id)); index++) { } /* If this exit was not in our list */ if (index == ramdu_num_exits) ramdu_num_exits++; ramdu_exit[index].id = id; ramdu_exit[index].saw++; return(index); } int ramduSetHit(identification id) { int index; for (index=0; ((index < ramdu_num_exits) && (index < NUM_PLAYERS) && (ramdu_exit[index].id != id)); index++) { } /* If this exit was not in our list */ if (index == ramdu_num_exits) ramdu_num_exits++; ramdu_exit[index].id = id; ramdu_exit[index].hits++; return(index); } int ramduSetExit(position x, position y, identification id) { int index; if (id == (identification)q_my_id()) { ramdu_my_exit_x = x; ramdu_my_exit_y = y; } for (index=0; ((index < ramdu_num_exits) && (index < NUM_PLAYERS) && (ramdu_exit[index].id != id)); index++) { } /* If this exit was not in our list */ if (index == ramdu_num_exits) ramdu_num_exits++; ramdu_exit[index].id = id; ramdu_exit[index].x = x; ramdu_exit[index].y = y; return(index); } float ramduGetAggression(identification id) { int index; for (index=0; ((index < ramdu_num_exits) && (ramdu_exit[index].id != id)); index++) { } /* If this player was not found */ if (index == ramdu_num_exits) { index = -1; return(0.0); } else if (ramdu_exit[index].saw == 0) return(0.0); else return(((float)ramdu_exit[index].hits)/((float)ramdu_exit[index].saw)); } int ramduGetExit(identification id) { int index; for (index=0; ((index < ramdu_num_exits) && (ramdu_exit[index].id != id)); index++) { } if (index == ramdu_num_exits) { /* This players exit was not found */ index = -1; } return(index); } int ramduGetExitAt(position x, position y) { int index; for (index=0; ((index < ramdu_num_exits) && ((ramdu_exit[index].x != x) || (ramdu_exit[index].y != y))); index++) { } /* If this exit was not found at this spot */ if (index == ramdu_num_exits) index = -1; return(index); } int ramduGetTeammateAt(position x, position y) { int index; index = q_my_num(); if (ramduNumOfUs == 1) { if ((x == ramdu_list[index].x) && (y == ramdu_list[index].y)) return(index); else return(-1); } for (index=0; ((index < NUM_PLAYERS) && ((ramdu_list[index].x != x) || (ramdu_list[index].y != y))); index++) { } /* If this robot was not found or is gone from this spot */ if (index == NUM_PLAYERS) index = -1; return(index); } int ramduGetRobotAt(position x, position y) { int index; for (index=0; ((index < ramdu_num_robots) && ((ramdu_robot[index].x != x) || (ramdu_robot[index].y != y))); index++) { } if ((index == ramdu_num_robots) || (ramdu_robot[index].lost) || ((ramduTime - ramdu_robot[index].time) > ROBOT_AGE)) { /* This robot was not found or is gone from this spot */ index = -1; } return(index); } int ramduSetRobot(position x, position y, identification id, int type) { int index; if ((id == (identification)q_my_id()) && (type == PLAYER_ROBOT)) return(-1); /* (ramdu_robot[index].type != type) && */ /* for (index=0; ((index < ramdu_num_robots) && (ramdu_robot[index].id != id) && ((ramduTime - ramdu_robot[index].time) < (ramduDist(ramdu_robot[index].x, ramdu_robot[index].y, x, y)*2))); index++) */ for (index=0; ((index < ramdu_num_robots) && (index < NUM_ROBOTS) && (ramdu_robot[index].id != id)); index++) { } if (index == NUM_ROBOTS) { index = 0; while(!ramdu_robot[index].lost) index++; } if (index == ramdu_num_robots) { /* This robot was not found */ ramdu_num_robots++; } ramdu_robot[index].id = id; ramdu_robot[index].x = x; ramdu_robot[index].y = y; ramdu_robot[index].lost = FALSE; ramdu_robot[index].type = type; ramdu_robot[index].time = ramduTime; return(index); } int ramduPropogateBoom(position x, position y, int num_boom) { int index; int i,j; index = num_boom; if ((x == 0) || (x == (SIZE-1)) || (y == 0) || (y == (SIZE-1))) return(index); for (i=(y-1); i < (y+2); i++) for (j = (x-1); j < (x+2); j++) { if ((ramduMap[i][j] == LAND_MINE) || ((ramduMap[i][j] >= BOOM) && (ramdu_boom_time[ramduMap[i][j] - BOOM] > ramdu_boom_time[index]))) { ramduMap[i][j] = BOOM+index; index = ramduPropogateBoom(j, i, index); } else if ((ramduMap[i][j] >= BOOM) && (ramdu_boom_time[ramduMap[i][j] - BOOM] < ramdu_boom_time[index])) { index = ramduMap[i][j] - BOOM; index = ramduPropogateBoom(j, i, index); } /* else it's equal, or not an explosive, so ignore */ } return(index); } void ramduCheckBoom() { unsigned char index; position i, j; for (index=0; index < ramdu_num_boom; index++) { if ((ramdu_boom_time[index] > 0) && (ramdu_boom_time[index] <= ramduTime)) { /* This has exploded */ for (i=1; i < (SIZE-1); i++) { for (j=1; j <(SIZE-1); j++) if (ramduMap[i][j] == (BOOM+index)) ramduExploded(j, i); } ramdu_boom_time[index] = -1; } else if ((ramdu_boom_time[index] > 0) && (ramdu_boom_time[index] <= (ramduTime+6))) { for (i=1; i < (SIZE-1); i++) for (j=1; j <(SIZE-1); j++) if (ramduMap[i][j] == (BOOM+index)) ramduPropogateBoom(j, i, index); } } } void ramduExploded(position x, position y) { int i, j; ramduMap[y][x] = FLOOR; for (i=(y-1); i<(y+2); i++) for (j=(x-1); j<(x+2); j++) { if ((ramduMap[i][j] >= BOOM) || (ramduMap[i][j] == LAND_MINE)) ramduExploded(j, i); else switch(ramduMap[i][j]) { case FLOOR_OR_MINE: case WALL_1: case WALL_2: case WALL_3: case WALL_4: case GOOD: case REPAIR: ramduMap[i][j] = FLOOR; break; } } } int ramduSetLineOfFire(position x, position y, direction dir) { int i; distance dist; position test_x, test_y; identification id = -1; int index = -1; dist = 0; test_x = x; test_y = y; ramduGetXY(&test_x, &test_y, 1, dir); for (i=1; ((i<48) && (index < 0) && (test_x > 0) && (test_y > 0) && (test_x < 49) && (test_y < 49)); i++) { index = ramduGetRobotAt(test_x, test_y); if (index >= 0) { dist = i; id = ramdu_robot[index].id; } ramduGetXY(&test_x, &test_y, 1, dir); } if (dist == 0) dist = 3; ramduGetXY(&x, &y, dist, dir); if (y < 1) y = 1; if (y > 48) y = 48; if (x < 1) x = 1; if (x > 48) x = 48; for (i=0; i 0)) ramduUnsetLineOfFire(ramdu_line[i].x, ramdu_line[i].y); for (i=0; ((i= 0) && ((ramdu_line[i].dir != ramduOpposite(dir)) || (ramdu_line[i].x != x) || (ramdu_line[i].y != y))); i++) { } ramdu_line[i].id = id; ramdu_line[i].x = x; ramdu_line[i].y = y; ramdu_line[i].dir = ramduOpposite(dir); ramdu_line[i].time = ramduTime; if (id >= 0) { if (ramdu_robot[index].type == ENEMY_ROBOT) return(0); else return(id); } else return(-1); } void ramduSetShooting(position x, position y, direction dir) { int i; int index; for (i=0; ((i= 0) && ((ramdu_line[i].dir != ramduOpposite(dir)) || (ramdu_line[i].x != x) || (ramdu_line[i].y != y))); i++) { } index = ramduGetRobotAt(x, y); if ((index >= 0) && (ramdu_robot[index].type == PLAYER_ROBOT)) ramdu_line[i].id = ramdu_robot[index].id; /* Player robot */ else ramdu_line[i].id = -1; /* One of us */ ramdu_line[i].x = x; ramdu_line[i].y = y; ramdu_line[i].dir = dir; ramdu_line[i].time = ramduTime; } void ramduUnsetLineOfFire(position x, position y) { int i; for (i=0; i= 0) && (ramduTime-ramdu_line[i].time < LINE_AGE)) { ramdu_line[i].id = -1; ramdu_line[i].x = -1; ramdu_line[i].y = -1; ramdu_line[i].dir = -1; ramdu_line[i].time = -1; } else if ((ramdu_line[i].dir >= 0) && (ramduTime-ramdu_line[i].time >= LINE_AGE)) { /* This line of fire has timed out, reset it. */ ramdu_line[i].id = -1; ramdu_line[i].x = -1; ramdu_line[i].y = -1; ramdu_line[i].dir = -1; ramdu_line[i].time = -1; } } } int ramduLineOfFire(position x, position y) { int i; for (i=0; i= 0) && (ramduTime-ramdu_line[i].time < LINE_AGE)) { if (ramdu_line[i].dir == ramduClearShot(ramdu_line[i].x, ramdu_line[i].y, x, y)) return(ramdu_line[i].dir); } else if (ramdu_line[i].dir >= 0) { /* This line of fire has timed out, reset it. */ ramdu_line[i].dir = -1; } } return(-1); } int ramduTimeToBoom(position x, position y) { position i, j; int time = BIG_DIST; for (i=(y-1); i < (y+2); i++) for (j=(x-1); j <(x+2); j++) if (ramduMap[i][j] >= BOOM) time = min(time, (ramdu_boom_time[ramduMap[i][j]-BOOM] - ramduTime)); if (time == BIG_DIST) time = -1; return(time); } duration ramduUseDynamite() { position x, y; int time; int index; x = (position)q_wherex(); y = (position)q_wherey(); time = 4; use_dynamite(time); ramduUpdateTime(2); ramduMap[y][x] = BOOM+ramdu_num_boom; ramdu_boom_time[ramdu_num_boom] = ramduTime + time; index = ramduPropogateBoom(x, y, ramdu_num_boom); ramduMap[y][x] = BOOM+index; if (index >= ramdu_num_boom) ramdu_num_boom++; if (ramdu_num_boom >= NUM_BOOMS) ramdu_num_boom = NUM_BOOMS-1; return(2); } boolean ramduGoalTaken(position x, position y) { int my_num; int k; int taken = FALSE; if (ramduNumOfUs == 1) return(FALSE); my_num = q_my_num(); for (k=0; k= 0) && (ramduDist(ramdu_list[k].goal_x, ramdu_list[k].goal_y, x, y) < MY_GOAL_DIST)) taken = TRUE; } return(taken); }