/* MORTON - sample simple bot. attacks, avoids walls (sort of), and dodges bullets To compile: gcc -o morton morton.c -lxpilot_ai or, if necessary: gcc -o morton morton.c -lxpilot_ai -L/path/to/libxpilot_ai/ -I/path/to/xpilot_ai.h/ then to run, type: ./morton "-join localhost -team 3" or, for no command line arguments: ./morton "" */ #include "xpilot_ai.h" #include int main (int argc, char **argv) { char launchstring[512]; /*set max turn speed to 20 degrees per frame*/ AI_setmaxturn (20); /* launch xpilot with a ship named "Morton", using the command line args */ strcpy(launchstring, argv[1]); strcat(launchstring, " -name Morton"); AI_xpilot_setargs(launchstring); AI_xpilot_launch(); return 1; } /*wall_feeler checks for walls at some degree and range from self ship */ int wall_feeler(int range, int degree); int wall_feeler(int range, int degree) { int res = AI_wallbetween(AIself_x(), AIself_y(), AIself_x() + range * cos( rad (degree)), AIself_y() + range * sin(rad( degree))); if (res == -1) return range; return res; } /* gets nearest enemy on screen or returns -1 if no enemy */ int screen_enemy_num (int n); int screen_enemy_num (int n) { if (AIship_x(n) == -1) return -1; else if (AI_teamplay() == 1 && AIself_team() != AIship_team(n)) return n; else return screen_enemy_num(n + 1); } /* gets nearest enemy on radar or -1 if none */ int radar_enemy_num (int n); int radar_enemy_num (int n) { if (AIradar_x(n) == -1) return -1; else if (AIradar_enemy(n) == 1) return n; else return radar_enemy_num(n + 1); } /* libxpilot_ai.so defines a void function called AImain() that it calls every frame. If you redefine it, it will call your function instead. */ void AImain(void) { int shipnum = screen_enemy_num(0); int rshipnum = radar_enemy_num(0); int wall_feeler1 = wall_feeler(500, angleadd(AIself_track(), -15)); int wall_feeler2 = wall_feeler(500, angleadd(AIself_track(), 15)); /* Dodge bullet if dangerous */ if (AIshot_alert(0) > -1 && AIshot_alert(0) < 80) { AIself_turn(anglediff(AIself_heading(), angleadd(AIshot_idir(0), 90))); AIself_thrust(1); } /* Turn and shoot at nearest enemy ship on screen */ else if (shipnum > -1) { AIself_turn(anglediff(AIself_heading(), AIship_aimdir(shipnum))); AIself_shoot(1); } /* Turn to radar ship, thrust if not going to fast, shoot otherwise */ else if (rshipnum > -1) { AIself_turn(anglediff(AIself_heading(), AIradar_xdir(rshipnum))); if (AIself_vel() < 10) AIself_thrust(1); else AIself_shoot(1); } /* dodges walls. Two feelers out front at -15 and 15 degrees from track tell Morton the best way to turn to avoid the wall. */ if (wall_feeler1 == wall_feeler2 && wall_feeler1 < (20 * AIself_vel()) && AIself_vel() > 1) { AIself_turn(anglediff(AIself_heading(), angleadd(180, AIself_track()))); AIself_thrust(1); } else if (wall_feeler1 < wall_feeler2 && wall_feeler1 < (20 * AIself_vel()) && AIself_vel() > 1) { AIself_turn(anglediff(AIself_heading(), angleadd(180, angleadd(-15, AIself_track())))); AIself_thrust(1); } else if (wall_feeler1 > wall_feeler2 && wall_feeler2 < (20 * AIself_vel()) && AIself_vel() > 1) { AIself_turn(anglediff(AIself_heading(), angleadd(180, angleadd(15, AIself_track())))); AIself_thrust(1); } return; }