home *** CD-ROM | disk | FTP | other *** search
/ Megahits 4 / MegaHits_Vol.4.iso / mui / game / think / muipuzzle.lha / MUI_Puzzle.c < prev    next >
C/C++ Source or Header  |  1994-04-26  |  13KB  |  402 lines

  1. /*************************************************
  2. **     Yet Another Magic MUI Puzzle Game X      **
  3. **     -----------------------------------      **
  4. **          Written on 15. April 1994           **
  5. **                     by                       **
  6. **                Michael Bauer                 **
  7. ** EMail: bauermichael@student.uni-tuebingen.de **
  8. **************************************************/
  9.  
  10. /// "includes & defines"
  11. #include <muidef.h> /* You could also use the demo.h include in the mui */
  12.                     /* distribution                                     */
  13.  
  14. #define RAND(min,max) ((rand()%(int)(((max)+1)-(min)))+(min))
  15.  
  16. #define BUTTON      42
  17. #define ABOUT       43
  18. #define SHUFFLE     44
  19. #define CRSRUP      45
  20. #define CRSRDOWN    46
  21. #define CRSRLEFT    47
  22. #define CRSRRIGHT   48
  23. #define SCRSRUP     49
  24. #define SCRSRDOWN   50
  25. #define SCRSRLEFT   51
  26. #define SCRSRRIGHT  52
  27.  
  28. APTR app,window,about_gad,shuffle_gad,text,b[16];
  29.  
  30. int con[16] = { 
  31.     1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,-1 
  32. };
  33.  
  34. int moves = 0;
  35. int actobj = 0;
  36. ///
  37.  
  38. /// "main"
  39. int main(int argc,char *argv[])
  40. {
  41.     ULONG signals;
  42.     BOOL running = TRUE;
  43.     int i;
  44.     LONG button_nr;
  45.  
  46.     char about_text[] =
  47. "\33c© April 1994 by Michael Bauer\n\n\
  48. MuiPuzzle is Mailware. You may spread it to your friends for free\n\
  49. as long as you don't charge more than the price Fred Fish takes\n\
  50. for his disks. It may be put in PD-series or on Fileservers. For\n\
  51. the rules refer to the documents.\n\n\
  52. The usage of this program by persons who support violence against\n\
  53. foreign people is strictly prohibited.\n\n\
  54. bauermichael@student.uni-tuebingen.de\n\
  55. Gutgolf@IRC\n\
  56. Gutgolf@Nightfall (134.2.62.161 4242)\n";
  57.  
  58.     init();
  59.  
  60.     app = ApplicationObject,
  61.         MUIA_Application_Title      , "MUI Puzzle",
  62.         MUIA_Application_Version    , "$VER: MUIpuzzle 1.0 (26.4.94)",
  63.         MUIA_Application_Copyright  , "©1994 Michael Bauer",
  64.         MUIA_Application_Author     , "Michael Bauer",
  65.         MUIA_Application_Description, "A small puzzle game",
  66.         MUIA_Application_Base       , "MUIPUZZLE",
  67.  
  68.         SubWindow, window = WindowObject,
  69.             MUIA_Window_Title, "MUI Puzzle",
  70.             MUIA_Window_ID   , MAKE_ID('P','U','Z','Z'),
  71.  
  72.             WindowContents, VGroup,
  73.                 Child, text = TextObject, TextFrame,
  74.                     MUIA_Text_Contents, "Moves: 0",
  75.                 End,
  76.                 Child, VGroup, GroupFrame,
  77.                     MUIA_Group_VertSpacing,0,
  78.                     Child, HGroup,
  79.                         MUIA_Group_SameSize, TRUE,
  80.                         MUIA_Group_HorizSpacing,0,
  81.                         Child,  b[0] = SimpleButton("1"),
  82.                         Child,  b[1] = SimpleButton("2"),
  83.                         Child,  b[2] = SimpleButton("3"),
  84.                         Child,  b[3] = SimpleButton("4"),
  85.                     End,
  86.                     Child, HGroup,
  87.                         MUIA_Group_SameSize, TRUE,
  88.                         MUIA_Group_HorizSpacing,0,
  89.                         Child,  b[4] = SimpleButton("5"),
  90.                         Child,  b[5] = SimpleButton("6"),
  91.                         Child,  b[6] = SimpleButton("7"),
  92.                         Child,  b[7] = SimpleButton("8"),
  93.                     End,
  94.                     Child, HGroup,
  95.                         MUIA_Group_SameSize, TRUE,
  96.                         MUIA_Group_HorizSpacing,0,
  97.                         Child,  b[8] = SimpleButton("9"),
  98.                         Child,  b[9] = SimpleButton("10"),
  99.                         Child,  b[10] = SimpleButton("11"),
  100.                         Child,  b[11] = SimpleButton("12"),
  101.                     End,
  102.                     Child, HGroup,
  103.                         MUIA_Group_SameSize, TRUE,
  104.                         MUIA_Group_HorizSpacing,0,
  105.                         Child,  b[12] = SimpleButton("13"),
  106.                         Child,  b[13] = SimpleButton("14"),
  107.                         Child,  b[14] = SimpleButton("15"),
  108.                         Child,  b[15] = SimpleButton(" "),
  109.                     End,
  110.                 End,
  111.                 Child, HGroup, GroupFrame,
  112.                     MUIA_Group_SameSize, TRUE,
  113.                     Child, about_gad = KeyButton("About",'a'),
  114.                     Child, shuffle_gad = KeyButton("Shuffle",'s'),
  115.                 End,
  116.             End,
  117.         End,
  118.     End;
  119.  
  120.     if (!app)
  121.         fail(app,"Failed to create Application.");
  122.  
  123.     set(window,MUIA_Window_Open,TRUE);
  124.  
  125.     shuffle();
  126.  
  127.     DoMethod(window,MUIM_Notify,MUIA_Window_CloseRequest,MUIV_EveryTime,app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  128.  
  129.     /* Fill the number of a pressed button in the MUIA_UserField */
  130.     for (i=0; i<=15; i++) {
  131.         DoMethod(b[i],MUIM_Notify,MUIA_Pressed,FALSE,window,3,MUIM_Set,MUIA_UserData,i);
  132.     }
  133.  
  134.     /* Send an ReturnID to the application every time the value in the */
  135.     /* MUIA_UserField changes                                          */
  136.     DoMethod(window,MUIM_Notify,MUIA_UserData,MUIV_EveryTime,app,2,MUIM_Application_ReturnID,BUTTON);
  137.  
  138.     /* Setup a small cycle chain */
  139.     DoMethod(window,MUIM_Window_SetCycleChain,b[0],b[1],b[2],b[3],b[4],b[5],
  140.              b[6],b[7],b[8],b[9],b[10],b[11],b[12],b[13],b[14],b[15],NULL);
  141.  
  142.     DoMethod(window,MUIM_Notify,MUIA_Window_InputEvent,"up",app,2,MUIM_Application_ReturnID,CRSRUP);
  143.     DoMethod(window,MUIM_Notify,MUIA_Window_InputEvent,"down",app,2,MUIM_Application_ReturnID,CRSRDOWN);
  144.     DoMethod(window,MUIM_Notify,MUIA_Window_InputEvent,"left",app,2,MUIM_Application_ReturnID,CRSRLEFT);
  145.     DoMethod(window,MUIM_Notify,MUIA_Window_InputEvent,"right",app,2,MUIM_Application_ReturnID,CRSRRIGHT);
  146.     
  147.     DoMethod(window,MUIM_Notify,MUIA_Window_InputEvent,"shift up",app,2,MUIM_Application_ReturnID,SCRSRUP);
  148.     DoMethod(window,MUIM_Notify,MUIA_Window_InputEvent,"shift down",app,2,MUIM_Application_ReturnID,SCRSRDOWN);
  149.     DoMethod(window,MUIM_Notify,MUIA_Window_InputEvent,"shift left",app,2,MUIM_Application_ReturnID,SCRSRLEFT);
  150.     DoMethod(window,MUIM_Notify,MUIA_Window_InputEvent,"shift right",app,2,MUIM_Application_ReturnID,SCRSRRIGHT);
  151.  
  152.     DoMethod(about_gad,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ABOUT);
  153.     DoMethod(shuffle_gad,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,SHUFFLE);
  154.  
  155.     set (window,MUIA_Window_ActiveObject, b[0]);
  156.  
  157.     while (running)
  158.     {
  159.         switch (DoMethod(app,MUIM_Application_Input,&signals))
  160.         {
  161.                 case MUIV_Application_ReturnID_Quit:
  162.                         running = FALSE;
  163.                         break;
  164.                 case BUTTON:
  165.                     get(window,MUIA_UserData,&button_nr);
  166.                     moveb((int)button_nr);
  167.                     break;
  168.                 case ABOUT:
  169.                     MUI_RequestA(app,window,0,"MUI Puzzle","*OK",about_text,NULL);
  170.                     break;
  171.                 case SHUFFLE:
  172.                     shuffle();
  173.                     break;
  174.  
  175.                 case SCRSRDOWN:
  176.                     while (actobj < 12 ) {
  177.                         actobj += 4;
  178.                     }
  179.                     set(window,MUIA_Window_ActiveObject,b[actobj]);
  180.                     break;
  181.  
  182.                 case CRSRDOWN:
  183.                     actobj += 4;
  184.                     if (actobj > 15)
  185.                         actobj -= 16;
  186.                     set(window,MUIA_Window_ActiveObject,b[actobj]);
  187.                     break;
  188.  
  189.                 case SCRSRUP:
  190.                     while (actobj > 3) {
  191.                         actobj -= 4;
  192.                     }
  193.                     set(window,MUIA_Window_ActiveObject,b[actobj]);
  194.                     break;
  195.  
  196.                 case CRSRUP:
  197.                     actobj -= 4;
  198.                     if (actobj < 0)
  199.                         actobj += 16;
  200.                     set(window,MUIA_Window_ActiveObject,b[actobj]);
  201.                     break;
  202.  
  203.                 case SCRSRLEFT:
  204.                     while (actobj != 0 && actobj != 4 && actobj != 8 && actobj != 12) {
  205.                         actobj -= 1;
  206.                     }
  207.                     set(window,MUIA_Window_ActiveObject,b[actobj]);
  208.                     break;
  209.  
  210.                 case CRSRLEFT:
  211.                     actobj -= 1;
  212.                     switch (actobj) {
  213.                         case -1:
  214.                         case  3:
  215.                         case  7:
  216.                         case 11:
  217.                             actobj += 4;
  218.                             break;
  219.                     }
  220.                     set(window,MUIA_Window_ActiveObject,b[actobj]);
  221.                     break;
  222.  
  223.                 case SCRSRRIGHT:
  224.                     while (actobj != 3 && actobj != 7 && actobj != 11 && actobj != 15) {
  225.                         actobj += 1;
  226.                     }
  227.                     set(window,MUIA_Window_ActiveObject,b[actobj]);
  228.                     break;
  229.  
  230.                 case CRSRRIGHT:
  231.                     actobj += 1;
  232.                     switch(actobj) {
  233.                         case  4:
  234.                         case  8:
  235.                         case 12:
  236.                         case 16:
  237.                             actobj -= 4;
  238.                             break;
  239.                     }
  240.                     set(window,MUIA_Window_ActiveObject,b[actobj]);
  241.                     break;
  242.         }
  243.  
  244.         if (running && signals) Wait(signals);
  245.     }
  246.  
  247.     set(window,MUIA_Window_Open,FALSE);
  248.  
  249.     fail(app,NULL);
  250. }
  251. ///
  252.  
  253. /// "shuffle"
  254. int shuffle()
  255. {
  256.     int i,x,y,x1,y1,dummy;
  257.  
  258.     /* Set the array to it's original (sorted) state */
  259.     for (i=0;i<15;i++)
  260.         con[i]=i+1;
  261.     con[15] = -1;
  262.  
  263.     /* Start position of the hole */
  264.     x = 3; y = 3;
  265.  
  266.     /* Random swapping of the hole and one of it's neighbours */
  267.     for (i=0;i<150;i++) {
  268.         x1 = -1; y1 = -1;
  269.         switch( RAND(1,4) ) {
  270.             case 1: x1 = x-1;
  271.                     if (x1 < 0)
  272.                         x1 += 2;
  273.                     y1 = y;
  274.                     break;
  275.             case 2: x1 = x+1;
  276.                     if (x1 > 3)
  277.                         x1 -= 2;
  278.                     y1 = y;
  279.                     break;
  280.             case 3: y1 = y-1;
  281.                     if (y1 < 0)
  282.                         y1 += 2;
  283.                     x1 = x;
  284.                     break;
  285.             case 4: y1 = y+1;
  286.                     if (y1 > 3)
  287.                         y1 -= 2;
  288.                     x1 = x;
  289.                     break;
  290.         }
  291.         dummy = con[x+y*4];
  292.         con[x+y*4] = con[x1+y1*4];
  293.         con[x1+y1*4] = dummy;
  294.         x=x1; y=y1;
  295.     }
  296.  
  297.     draw_field();
  298.  
  299.     /* Reset the counter */
  300.     moves = 0;
  301.     set (text,MUIA_Text_Contents,"Moves: 0");
  302.  
  303.     return;
  304. }
  305. ///
  306.  
  307. /// "moveb"
  308. int moveb(int n)
  309. {
  310.     int test = 0;
  311.     int xc,yc,xe,ye,i;
  312.  
  313.     if (n<0 || n>15)
  314.         return;
  315.  
  316.     /* Get the coordinates of the clicked button */
  317.     yc = (int)(n/4);
  318.     xc = (int)(n-yc*4);
  319.  
  320.     /* Get the coordinates of the empty field */
  321.     for (i=0; i<=15; i++) {
  322.         if (con[i] == -1) {
  323.             ye = (int)(i/4);
  324.             xe = (int)(i-ye*4);
  325.         }
  326.     }
  327.  
  328.     /* If the player tries to click on the empty field nothing happens */
  329.     /* If the button can't be moved because the empty field doesn't    */
  330.     /* sit in the same row or column return too.                       */
  331.     if ((xe == xc && ye == yc) || (xe != xc && ye != yc))
  332.         return (0);
  333.  
  334.     if (ye == yc) { /* horizontal */
  335.         if (xe < xc) { /* move left */
  336.             for (i=xe; i<xc; i++) {
  337.                 con[ye*4+i] = con[ye*4+i+1];
  338.                 DoMethod(b[ye*4+i],MUIM_SetAsString,MUIA_Text_Contents,"%ld",con[ye*4+i]);
  339.             }
  340.             con[yc*4+xc] = -1;
  341.         }
  342.         else { /* move right */
  343.             for (i=xe; i>xc; i--) {
  344.                 con[ye*4+i] = con[ye*4+i-1];
  345.                 DoMethod(b[ye*4+i],MUIM_SetAsString,MUIA_Text_Contents,"%ld",con[ye*4+i-1]);
  346.             }
  347.             con[yc*4+xc] = -1;
  348.         }
  349.         set(b[yc*4+xc],MUIA_Text_Contents," ");
  350.     }
  351.     else { /* vertical */
  352.         if (ye < yc) { /* move up */
  353.             for (i=ye; i<yc; i++) {
  354.                 con[xc+i*4] = con[xc+(i+1)*4];
  355.                 DoMethod(b[xc+i*4],MUIM_SetAsString,MUIA_Text_Contents,"%ld",con[xc+(i+1)*4]);
  356.             }
  357.             con[yc*4+xc] = -1;
  358.         }
  359.         else { /* move down */
  360.             for (i=ye; i>yc; i--) {
  361.                 con[xc+i*4] = con[xc+(i-1)*4];
  362.                 DoMethod(b[xc+i*4],MUIM_SetAsString,MUIA_Text_Contents,"%ld",con[xc+(i-1)*4]);
  363.             }
  364.             con[yc*4+xc] = -1;
  365.         }
  366.         set(b[yc*4+xc],MUIA_Text_Contents," ");
  367.     }
  368.  
  369.     moves++;
  370.     DoMethod(text,MUIM_SetAsString,MUIA_Text_Contents,"Moves: %ld",moves);
  371.  
  372.     /* Check if all buttons have the right value, i.e they're sorted */
  373.     for (i=0; i<15; i++) {
  374.         if (con[i] == i+1)
  375.             test++;
  376.     }
  377.  
  378.     /* If the buttons are sorted then popup the requester and reshuffle */
  379.     if (test == 15) {
  380.         MUI_RequestA(app,window,0,"MUI Puzzle","*OK","CONGRATULATIONS",NULL);
  381.         shuffle();
  382.     }
  383.  
  384.     return (0);
  385. }
  386. ///
  387.  
  388. /// "draw_field"
  389. draw_field() {
  390.     int i;
  391.  
  392.     /* Set the new values to MUIA_Text_Contents, if value == -1 set */
  393.     /* this button to <SPACE>                                       */
  394.     for (i=0; i<=15; ++i) {
  395.         if (con[i] == -1)
  396.             set(b[i],MUIA_Text_Contents," ");
  397.         else
  398.             DoMethod(b[i],MUIM_SetAsString,MUIA_Text_Contents,"%ld",con[i]);
  399.     }
  400. }
  401. ///
  402.