home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 79 / maccd 79.iso / multimedial / GL Tron / Source / gltron / computer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-10  |  5.5 KB  |  259 lines  |  [TEXT/CWIE]

  1. #include "gltron.h"
  2.  
  3. int freeway(Data *data, int dir) {
  4.   int i;
  5.   int wd = 20;
  6.  
  7.   for(i = 1; i < wd; i++)
  8.     if(getCol((int)data->posx + dirsX[dir] * i, 
  9.           (int)data->posy + dirsY[dir] * i)) 
  10.       break;
  11.   return i;
  12. }
  13.  
  14. void getDistPoint(int dir, int d, int *x, int *y) {
  15.   *x += dirsX[dir] * d;
  16.   *y += dirsY[dir] * d;
  17. }
  18.  
  19. void setPos(Data *data, int *x, int *y) {
  20.   *x = (int)data->posx;
  21.   *y = (int)data->posy;
  22. }
  23.  
  24. #define MAX_PROBE_DIST 20
  25.  
  26. #define LEFT(x) ((x + 3) % 4)
  27. #define RIGHT(x) ((x + 1) % 4)
  28.  
  29. static int probe_dists[][2] = {
  30.   { 8, 10 },
  31.   { 2, 5 },
  32. };
  33.  
  34. /*
  35. static int target_dir[][2] = {
  36.   { 0, 1 },
  37.   { 2, 1 },
  38.   { 3, 0 },
  39.   { 3, 2 }
  40. };
  41. */
  42.  
  43. static int turn_time[] = {
  44.   200, 100
  45. };
  46.  
  47. static float max_moves[] = {
  48.   .4, 0.5
  49. };
  50.  
  51. static int spiral[] = {
  52.   10, 10
  53. };
  54.     
  55. void doComputer(int player, int target) {
  56.   AI *ai;
  57.   Data *data;
  58.   Player *me, *him;
  59.   int i, j, level, x, y, rdist, ldist;
  60.  
  61.   me = &(game->player[ player ]);
  62.   him = &(game->player[ target ]);
  63.   if(me->ai == NULL) {
  64.     printf("This player has no AI data!\n");
  65.     return;
  66.   }
  67.   data = me->data;
  68.   ai = me->ai;
  69.   level = game->settings->ai_level;
  70.  
  71.   ai->moves++;
  72.   /* avoid to short turns */
  73.   if(game2->time.current - ai->lasttime < turn_time[level])
  74.     return;
  75.  
  76.  
  77.   /* first, check if we are in danger */
  78.   /* check the highest level first! */
  79.   for(i = level; i >= 0; i++) {
  80.     for(j = probe_dists[i][0]; j <= probe_dists[i][1]; j++) {
  81.       setPos(data, &x, &y);
  82.       getDistPoint(data->dir, j, &x, &y);
  83.       if(getCol(x, y)) {
  84.     ai->danger = j;
  85.     break;
  86.       }
  87.     }
  88.     if(ai->danger != 0) break;
  89.   }
  90.  
  91.   if(ai->danger != 0 || ai->moves > max_moves[level] * game->settings->grid_size) {
  92.     ai->moves = 0;
  93.  
  94.     /* figure out how far it's to either side */
  95.     for(i = 1; i < MAX_PROBE_DIST; i++) {
  96.       setPos(data, &x, &y);
  97.       getDistPoint(LEFT(data->dir), i, &x, &y);
  98.       if(getCol(x, y)) {
  99.     ldist = i;
  100.     break;
  101.       } else { ldist = i; }
  102.     }
  103.     for(i = 1; i < MAX_PROBE_DIST; i++) {
  104.       setPos(data, &x, &y);
  105.       getDistPoint(RIGHT(data->dir), i, &x, &y);
  106.       if(getCol(x, y)) {
  107.     rdist = i;
  108.     break;
  109.       } else { rdist = i; }
  110.     }
  111.     /* decide where to turn */
  112.     if(ai->danger > rdist && ai->danger > ldist) {
  113.       ai->danger--;
  114.       return;
  115.     } else if(rdist > ldist && ai->tdiff > -spiral[level] ) {
  116.       createTurnEvent(player, TURN_RIGHT);
  117.       ai->tdiff--;
  118.     } else if(rdist < ldist && ai->tdiff < spiral[level] ) {
  119.       createTurnEvent(player, TURN_LEFT);
  120.       ai->tdiff++;
  121.     } else {
  122.       if(ai->tdiff > 0) { 
  123.     createTurnEvent(player, TURN_RIGHT);
  124.     ai->tdiff--; }
  125.       else { 
  126.     createTurnEvent(player, TURN_LEFT);
  127.     ai->tdiff++; }
  128.     }
  129.     ai->danger = 0;
  130.     ai->lasttime = game2->time.current;
  131.   }
  132. }
  133.  
  134. /* new AI code */
  135.  
  136. #define DIR_LEFT 1
  137. #define DIR_RIGHT 2
  138. #define DIR_FRONT 4
  139. #define DIR_BACK 8
  140.  
  141. void getXYdir(int dir, int *x, int *y) {
  142.   int tx = 0, ty = 0;
  143.   if(dir & DIR_FRONT) { tx = *x; ty = *y; }
  144.   if(dir & DIR_BACK) { tx = -*x; ty = -*y; }
  145.   if(dir & DIR_LEFT) { tx += -*y; ty += *x; }
  146.   if(dir & DIR_RIGHT) { tx += *y; ty += -*x; }
  147.   *x = tx; *y = ty;
  148. }
  149.  
  150. int freeway2(Data* data, int xdir, int ydir, int c) {
  151.   if(xdir == 0 && ydir == 0) {
  152.     fprintf(stderr, "bug: xdir == ydir == 0\n");
  153.     return 0;
  154.   }
  155.  
  156.   while(getCol(data->iposx + xdir * c, 
  157.            data->iposy + ydir * c) == 0) c++;
  158.   return c;
  159. }
  160.  
  161. /*
  162.   if FRONT < 0.92063 go straight
  163.   else if 0.92063 >= REAR_RIGHT turn left
  164.   else if LEFT < RIGHT turn right
  165.   else turn left
  166. */
  167.  
  168. #define MIN_FREE 1
  169. #define MIN_TURN 5
  170. #define CRIT_F 0.92063
  171.  
  172. static int min_turn[] = { 1, 1, 15, 6 };
  173.  
  174. /* level 2 and better */
  175.  
  176. void doComputer2(int player, int target) {
  177.   /* target is ignored */
  178.   Data *data;
  179.   Player *me;
  180.   AI *ai;
  181.   int level;
  182.   int front, rear_right, left, right;
  183.   int x, y;
  184.   float critical;
  185.  
  186.   me = &(game->player[ player ]);
  187.   if(me->ai == NULL) {
  188.     printf("This player has no AI data!\n");
  189.     return;
  190.   }
  191.   ai = me->ai;
  192.   level = game->settings->ai_level;
  193.   data = me->data;
  194.   if(abs(data->iposx - ai->lastx) < min_turn[level] &&
  195.      abs(data->iposy - ai->lasty) < min_turn[level]) {
  196.     /* fprintf(stderr, "too early\n"); */
  197.     return;
  198.   }
  199.  
  200.   critical = (1 - CRIT_F) * game->settings->grid_size;
  201.   x = dirsX[ data->dir ];
  202.   y = dirsY[ data->dir ];
  203.   getXYdir(DIR_FRONT, &x, &y);
  204.   front = freeway2(data, x, y, MIN_FREE);
  205.  
  206.   x = dirsX[ data->dir ];
  207.   y = dirsY[ data->dir ];
  208.   getXYdir(DIR_BACK | DIR_RIGHT, &x, &y);
  209.   rear_right = freeway2(data, x, y, MIN_FREE);
  210.  
  211.   x = dirsX[ data->dir ];
  212.   y = dirsY[ data->dir ];
  213.   getXYdir(DIR_RIGHT, &x, &y);
  214.   right = freeway2(data, x, y, MIN_FREE);
  215.  
  216.   x = dirsX[ data->dir ];
  217.   y = dirsY[ data->dir ];
  218.   getXYdir(DIR_LEFT, &x, &y);
  219.   left = freeway2(data, x, y, MIN_FREE);
  220.  
  221.   /*
  222.     fprintf(stderr, "-------------------------\n");
  223.     fprintf(stderr, "front space %d\n", front);
  224.     fprintf(stderr, "rear_right space %d\n", rear_right);
  225.     fprintf(stderr, "right space %d\n", right);
  226.     fprintf(stderr, "left space %d\n", left);
  227.   */
  228.  
  229.   if(front < critical && (left > front || right > front) ) {
  230.     /*
  231.     if(critical <= rear_right && left > critical) {
  232.       // turn left
  233.       createTurnEvent(player, TURN_LEFT);
  234.       fprintf(stderr, "turning left\n");
  235.       return;
  236.     }
  237.     */
  238.     if(left < right) {
  239.       // turn right
  240.       createTurnEvent(player, TURN_RIGHT);
  241.       fprintf(stderr, "turning right\n");
  242.       // return;
  243.     } else {
  244.       // turn left 
  245.       createTurnEvent(player, TURN_LEFT);
  246.       fprintf(stderr, "turning left\n");
  247.       // return;
  248.     }
  249.     ai->lastx = data->iposx;
  250.     ai->lasty = data->iposy;
  251.   }
  252.   
  253. }
  254.  
  255.  
  256.  
  257.  
  258.  
  259.