home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / bbs / ff810.lha / FF810 / Snake / snake.c < prev    next >
C/C++ Source or Header  |  1993-01-24  |  4KB  |  224 lines

  1.  
  2. /* SNAKE by Michael Warner January 1993. Public Domain. */
  3.  
  4. #include <mw/rawkeys.h>
  5.  
  6. #define XSIZE 40
  7. #define YSIZE 40
  8.  
  9. #define CLEAR 0
  10. #define SNAKE 3
  11. #define BRICK 1
  12. #define FROG  2
  13.  
  14. extern APTR IntuitionBase,DOSBase,GfxBase;
  15.  
  16. struct Window *win;
  17. struct RastPort *rp;
  18. BOOL stretch;
  19.  
  20. void open_window(void)
  21. {
  22.   struct Screen *scr;
  23.  
  24.   scr = LockPubScreen(NULL);
  25.   stretch = scr->Height<400;
  26.   UnlockPubScreen(NULL,scr);
  27.  
  28.   win = OpenWindowTags(NULL,
  29.     WA_Width,stretch?491:251, WA_Height,255,
  30.     WA_IDCMP, CLOSEWINDOW|RAWKEY,
  31.     WA_ScreenTitle,"Snake by Michael Warner 1993 (Public Domain)",
  32.     WA_Flags,ACTIVATE|WINDOWCLOSE|WINDOWDRAG|RMBTRAP|WINDOWDEPTH|SMART_REFRESH|NOCAREREFRESH,
  33.     TAG_DONE);
  34.   if (!win) exit(10);
  35.   rp = win->RPort;
  36. }
  37.  
  38. void close_window(void)
  39. {
  40.   CloseWindow(win);
  41. }
  42.  
  43. void notify(char *str)
  44. {
  45.   struct EasyStruct es;
  46.  
  47.   es.es_StructSize = sizeof(struct EasyStruct);
  48.   es.es_Flags = 0;
  49.   es.es_Title = "Snake Info";
  50.   es.es_TextFormat = str;
  51.   es.es_GadgetFormat = "OK";
  52.   EasyRequestArgs(NULL,&es,NULL,NULL);
  53. }
  54.  
  55. UBYTE grid[XSIZE][YSIZE];
  56. UBYTE snx[1500],sny[1500],frx[5],fry[5];
  57. int dir,length,head,tail,grow,frogtime[5];
  58. UBYTE key;
  59.  
  60. void set_point(int x, int y, int item)
  61. {
  62.   grid[x][y]=item;
  63.  
  64.   SetAPen(rp,item);
  65.   if (stretch) RectFill(rp,5+x*12,12+y*6,5+x*12+11,12+y*6+5);
  66.   else RectFill(rp,5+x*6,12+y*6,5+x*6+5,12+y*6+5);
  67. }
  68.  
  69. void clear_grid(void)
  70. {
  71.   int x,y;
  72.  
  73.   for (x=0;x<XSIZE;x++) for (y=0;y<YSIZE;y++)
  74.     if (grid[x][y]) set_point(x,y,CLEAR);
  75. }
  76.  
  77. void draw_score(void)
  78. {
  79.   static char str[20];
  80.  
  81.   sprintf(str,"Length: %d",length);
  82.   SetWindowTitles(win,str,(APTR)-1);
  83. }
  84.  
  85. void pause(void)
  86. {
  87.   struct IntuiMessage *msg;
  88.  
  89.   FOREVER {
  90.     msg=WaitPort(win->UserPort);
  91.     if (msg->Class==RAWKEY && msg->Code&0x80) 
  92.       ReplyMsg(GetMsg(win->UserPort));
  93.     else return;
  94.   }
  95. }
  96.  
  97. void create_frog(int n)
  98. {
  99.   int x,y;
  100.  
  101.   do { x = RangeRand(XSIZE); y = RangeRand(YSIZE); } 
  102.   while (grid[x][y]);
  103.   frx[n]=x; fry[n]=y; 
  104.   set_point(x,y,FROG);
  105.   frogtime[n] = 20 + RangeRand(50);
  106. }
  107.  
  108. void check_frogs(void)
  109. {
  110.   int n,x,y;
  111.  
  112.   for (n=0;n<5;n++) {
  113.     if (!frogtime[n]--) {
  114.       x=frx[n]; y=fry[n];
  115.       create_frog(n);
  116.       set_point(x,y,RangeRand(10)?CLEAR:BRICK); 
  117.     }
  118.   }
  119. }
  120.  
  121. void replace_frog(int x, int y)
  122. {
  123.   int n;
  124.  
  125.   for (n=0;n<5;n++) {
  126.     if (frx[n]==x && fry[n]==y) create_frog(n);
  127.   }
  128.   set_point(x,y,CLEAR);
  129. }
  130.  
  131. void setup_game(void)
  132. {
  133.   int i;
  134.  
  135.   clear_grid();
  136.   length=1; draw_score();
  137.   head=tail=0; snx[0]=XSIZE/2; sny[0]=YSIZE/2;
  138.   set_point(snx[0],sny[0],SNAKE);
  139.   key = KEY_RIGHT;
  140.   for (i=0;i<5;i++) create_frog(i);
  141.   draw_score();
  142. }
  143.  
  144. BOOL play_one_game(void)
  145. {
  146.   int i,item;
  147.   struct IntuiMessage *msg;
  148.   ULONG class; USHORT code;
  149.   int x,y,nx,ny;
  150.  
  151.   FOREVER {
  152.     for (i=0;i<6;i++) WaitTOF();
  153.     while (msg=GetMsg(win->UserPort)) {
  154.       class = msg->Class; code = msg->Code;
  155.       ReplyMsg(msg);
  156.       switch (class) {
  157.         case CLOSEWINDOW: return(TRUE);
  158.         case RAWKEY:
  159.           if (!(code&0x80)) switch (code) {
  160.             case KEY_ESC: return(TRUE);
  161.             case KEY_P: pause(); break;
  162.         case KEY_UP: case KEY_DOWN:case KEY_LEFT: case KEY_RIGHT:           
  163.               key = code;
  164.           }
  165.       }
  166.     }
  167.  
  168.     x=snx[head]; y=sny[head];
  169.     switch (key) {
  170.       case KEY_UP: nx=x; ny=y-1; break;
  171.       case KEY_DOWN: nx=x; ny=y+1; break;
  172.       case KEY_LEFT: nx=x-1; ny=y; break;
  173.       case KEY_RIGHT: nx=x+1; ny=y; break;
  174.     }
  175.     if (nx<0||ny<0||nx>=XSIZE||ny>=YSIZE) return(FALSE);
  176.     item = grid[nx][ny];
  177.     switch (item) {
  178.       case FROG: grow+=2+RangeRand(10); replace_frog(nx,ny);
  179.       case CLEAR: 
  180.         head = (head+1)%1500; snx[head]=nx; sny[head]=ny; 
  181.         set_point(nx,ny,SNAKE);
  182.         if (grow) { grow--; length++; draw_score(); }
  183.         else {
  184.           set_point(snx[tail],sny[tail],CLEAR); tail = (tail+1)%1500; 
  185.         }
  186.         break;
  187.       case SNAKE: case BRICK: return(FALSE);
  188.     }
  189.     check_frogs();
  190.   }
  191. }       
  192.  
  193. void play_game(void)
  194. {
  195.   char str[80];
  196.  
  197.   FOREVER {
  198.     setup_game(); WaitPort(win->UserPort);
  199.     if (play_one_game()) return;
  200.     sprintf(str,"You were %d long",length);
  201.     notify(str);
  202.   }
  203. }
  204.  
  205. void randomise(void)
  206. {
  207.   extern ULONG __far RangeSeed;
  208.   int clk[2];
  209.  
  210.   timer(clk); RangeSeed = clk[0]+clk[1];
  211. }
  212.  
  213. void main(void)
  214. {
  215.   randomise();
  216.   open_window();
  217.   SetTaskPri(FindTask(0),10);
  218.   play_game();
  219.   close_window();
  220.   SetTaskPri(FindTask(0),0);
  221. }
  222.  
  223.  
  224.