home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d191 / pz15.lha / Pz15 / pz.c < prev    next >
C/C++ Source or Header  |  1989-03-14  |  5KB  |  234 lines

  1. /*
  2.  *    15 puzzle 
  3.  */
  4.  
  5. #include    <intuition/intuition.h>
  6. #include    <libraries/dos.h>        /* just for SIGBREAKF_CTRL_C */
  7. #include    <proto/intuition.h>
  8. #include    <proto/exec.h>
  9.  
  10. extern struct IntuitionBase    *IntuitionBase;
  11. extern struct GfxBase        *GfxBase;
  12.  
  13. #define    NPZ    4        /* the square puzzle is NPZ x NPZ */
  14. #define    PZ_MT    0        /* the value of the "empty" tile */
  15.  
  16. char    pz[NPZ][NPZ];        /* the puzzle array */
  17. int    mtr, mtc;        /* location of the "empty" tile */
  18.  
  19. #define    R0    11        /* origin row/col of upper left */
  20. #define    C0    4
  21. #define    RS    (IMG_HT+1)    /* row/col scaling factors (match images!!) */
  22. #define    CS    (IMG_WID+3)
  23. #define    IMG_WID    0x1f        /* from the output of 'brush' */
  24. #define    IMG_HT    0xd
  25.  
  26. struct Image img = {        /* shared Image struct for all "tiles" */
  27.     0,0, IMG_WID,IMG_HT, 1, NULL, 1,0, NULL
  28. };
  29.  
  30. /* the image data (in chip ram!) */
  31. extern short    id0[], id1[],  id2[],  id3[],  id4[],  id5[],  id6[],  id7[], 
  32.         id8[], id9[], id10[], id11[], id12[], id13[], id14[], id15[];
  33.  
  34. short    *imgs[] = {        /* array of pointers to the image data arrays */
  35.     id0, id1,  id2,  id3,  id4,  id5,  id6,  id7,
  36.     id8, id9, id10, id11, id12, id13, id14, id15
  37. };
  38.  
  39. #define    W_WID    141
  40. #define    W_HT    68
  41. struct NewWindow newin = {
  42.     100,50, W_WID,W_HT, 2,-1,
  43.     MOUSEBUTTONS | CLOSEWINDOW | REFRESHWINDOW,
  44.     WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG | SIMPLE_REFRESH,
  45.     NULL, NULL, "Pz15", NULL, NULL, 0,0, 0,0, WBENCHSCREEN
  46. };
  47.  
  48. struct Window    *win = NULL;
  49. struct RastPort    *rp  = NULL;
  50.  
  51. /* Lattice likes prototypes: */
  52. void    putpiece(unsigned short, unsigned short, unsigned short);
  53. void    refrow(unsigned short), refcol(unsigned short);
  54. short    pzmove(unsigned short, unsigned short);
  55. void    byewin(long);
  56.  
  57. /*
  58.  *    Repaint a single tile.
  59.  */
  60. void putpiece(r, c, v)
  61. register unsigned short r, c, v;
  62. {
  63.     img.ImageData = imgs[v];
  64.     DrawImage(rp, &img, (long) c*CS+C0, (long) r*RS+R0);
  65. }
  66.  
  67. /*
  68.  *    Repaint a specified row.
  69.  */
  70. void refrow(r)
  71. register unsigned short r;
  72. {
  73.     register unsigned short c;
  74.  
  75.     for ( c = 0; c < NPZ; c++ )
  76.         putpiece(r, c, (unsigned short)pz[r][c]);
  77. }
  78.  
  79. /*
  80.  *    Repaint a specified column.
  81.  */
  82. void refcol(c)
  83. register unsigned short c;
  84. {
  85.     register unsigned short r;
  86.  
  87.     for ( r = 0; r < NPZ; r++ )
  88.         putpiece(r, c, (unsigned short) pz[r][c]);
  89. }
  90.  
  91. /*
  92.  *    Move the "empty" tile (MT) to the "moused" row and column.
  93.  */
  94. short pzmove(mr, mc)
  95. unsigned short mr, mc;
  96. {
  97.     register unsigned short     r,  c;        /* row/col counters */
  98.     register short    ir, ic;            /* row/col increments */
  99.  
  100.     if ( mtr == mr )        /* Are we in the same row as MT? */
  101.         ir = 0;                /* yes, row-inc is zero */
  102.     else
  103.         ir = (mtr < mr) ? 1 : -1;    /* yes, row-inc is +/-1 */
  104.  
  105.     if ( mtc == mc )        /* Are we in the same col as MT? */
  106.         ic = 0;                /* yes, col-inc is zero */
  107.     else
  108.         ic = (mtc < mc) ? 1 : -1;    /* yes, col-inc is +/-1 */
  109.  
  110.     if ( ir == 0 && ic == 0 )    /* If in same row and col as MT... */
  111.         return 0;        /* ... nothing to do */
  112.     if ( ir != 0 && ic != 0 )    /* If not in either row or col as MT... */
  113.         return -1;        /* ... too much to do */
  114.  
  115.     /* "double-loop", but really only r _or_ c gets changed */
  116.     for ( r = mtr, c = mtc; ; r += ir, c += ic ) {    /* start at MT */
  117.         pz[r][c] = pz[r+ir][c+ic];    /* shift pieces towards MT */
  118.         if ( r == mr && c == mc )    /* until we hit the 'moused' position */
  119.             break;
  120.     }
  121.     pz[mr][mc] = PZ_MT;        /* mark the new empty square */
  122.     mtr = mr;
  123.     mtc = mc;
  124.     if ( ir == 0 )            /* update the display */
  125.         refrow(mr);        /* either change a row */
  126.     else
  127.         refcol(mc);        /* or a column */
  128.     return 1;            /* say there was just enough to do */
  129. }
  130.  
  131. /*
  132.  *    Refresh the entire puzzle.
  133.  */
  134. void pzref()
  135. {
  136.     register unsigned short    r;
  137.  
  138.     for ( r = 0; r < NPZ; r++ )    
  139.         refrow(r);
  140. }
  141.  
  142. /*
  143.  *    Setup the puzzle array.
  144.  */
  145. void pzinit()
  146. {
  147.     register unsigned short    r, c, i;
  148.  
  149.     i = 0;
  150.     for ( r = 0; r < NPZ; r++ )
  151.         for ( c = 0; c < NPZ; c++ )
  152.             pz[c][r] = i++;        /* scramble a little */
  153. }
  154.  
  155. /*
  156.  *    Get mouse clicks and handle them.
  157.  */
  158. void dopuz()
  159. {
  160.     register struct IntuiMessage *msg;
  161.     register unsigned short    r, c;
  162.     unsigned long    class;
  163.     unsigned short    code;
  164.     long    flags, ret;
  165.  
  166.     flags = (1L << win->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C;
  167.  
  168.     /* loop, get mouse clicks, call pzmove() with reduced coords */
  169.     for ( ; ; ) {
  170.         ret = Wait ( flags );
  171.         while ( msg = (struct IntuiMessage *)GetMsg(win->UserPort) ) {
  172.             class = msg->Class;
  173.             code = msg->Code;
  174.             r = (msg->MouseY - R0) / RS;
  175.             c = (msg->MouseX - C0) / CS;
  176.             ReplyMsg((struct Message *)msg);
  177.             if ( class == MOUSEBUTTONS && code == SELECTDOWN ) {
  178.                 (void)pzmove(r, c);
  179.             }
  180.             else if ( class == REFRESHWINDOW ) {
  181.                 pzref();
  182.             }
  183.             else if ( class == CLOSEWINDOW ) {
  184.                 return;
  185.             }
  186.         }
  187.         if ( ret & SIGBREAKF_CTRL_C ) {
  188.             return;
  189.         }
  190.     }
  191. }
  192.  
  193. /*
  194.  *    Shut the window; put back the things we borrowed.
  195.  */
  196. void byewin(r)
  197. long r;
  198. {
  199.     if ( win )
  200.          CloseWindow(win);
  201.     if ( GfxBase )
  202.         CloseLibrary(GfxBase);
  203.     if ( IntuitionBase )
  204.         CloseLibrary(IntuitionBase);
  205.     _exit(r);
  206. }
  207.  
  208. /*
  209.  *    Open some libraries and a window.
  210.  */
  211. void mkwin()
  212. {
  213.     if ( (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0L)) == NULL )
  214.         byewin(-100L);
  215.     if ( (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L)) == NULL )
  216.         byewin(-101L);
  217.     if ( (win = (struct Window *)OpenWindow(&newin)) == NULL )
  218.         byewin(-102L);
  219.     rp = win->RPort;
  220. }
  221.  
  222. /*
  223.  *    FINALLY, here's where it all starts.
  224.  */
  225. void _main()
  226. {
  227.     mkwin();        /* open up our window */
  228.     pzinit();        /* initialize the puzzle */
  229.     pzref();        /* and show it */
  230.     dopuz();        /* play it, until we close or get a ^C */
  231.     byewin(0L);        /* then close the window and exit */
  232. }
  233.  
  234.