Advertisement
Guest User

Yossi

a guest
Apr 8th, 2009
696
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.82 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <string>
  5. #include <algorithm>
  6. #include <gccore.h>
  7. #include <wiiuse/wpad.h>
  8. #include <fat.h>
  9. #include <wiisprite.h>
  10. #include <hbmenuhead.h>
  11. // remember, add here, add to the makefile
  12.  
  13. #include "bufferredchecker.h"
  14. #include "bufferredfill.h"
  15. #include "bufferblackchecker.h"
  16. #include "bufferblackfill.h"
  17. #include "bufferemptychecker.h"
  18. #include "bufferemptyfill.h"
  19. #include "bufferpressA.h"
  20. #include "bufferredwins.h"
  21. #include "bufferblackwins.h"
  22. #include "bufferemptywins.h"
  23.  
  24. /* TODO:
  25.  * add intro - DONE
  26.  * add better end game result - DONE
  27.  * make A button abort intro during it's run - GIVE UP?
  28.  * add homebrew menu - DONE
  29.  * two player support - DONE
  30.  * create settings.ini - DONE
  31.  * create setting for one/two wiimote support - DONE
  32.  * image loading - FIXED
  33.  * better 2player start (a at any time) - DONE
  34.  * allow setiiiings.ini - DONE
  35.  * make it look like its sliding down - DONE
  36.    
  37.    tolerate different name in path
  38.    redo win()
  39.    nunchuck
  40.    keep track of what was played
  41.    create ai for single player game
  42.    make ai smarter
  43.    figure out image loading without extra .c files
  44.    clean up code
  45.    add the other homebrew menu
  46.    sound? simpsons sounds (??)
  47.    rumble?
  48.  * */
  49.  
  50. #define EVER ;;
  51.  
  52. #define ONEWIIMOTE 1
  53. #define TWOWIIMOTES 2
  54. #define NUNCHUCK 3
  55.  
  56. #define CPU 0
  57. #define HUMAN 1
  58.  
  59. #define BLACK 0
  60. #define RED 1
  61. #define EMPTY -1
  62.  
  63. int control = ONEWIIMOTE;
  64. int numrows = 6;
  65. int numcols = 7;
  66. int numwin = 4;
  67. int firstplayer = BLACK;
  68. int moves = 0; // moves made in this game. helps spot tie // do NOT merge with whos_turn
  69. int player2 = HUMAN;
  70.  
  71. // libwiisprite uses wsp as it's namespace
  72. using namespace wsp;
  73.  
  74. GameWindow gwd; // Initializes and renders our scene
  75.  
  76. Image redchecker;
  77. Image redfill;
  78. Image blackchecker;
  79. Image blackfill;
  80. Image emptychecker;
  81. Image emptyfill;
  82. Image pressA;
  83. Image redwins;
  84. Image blackwins;
  85. Image emptywins;
  86.  
  87. Sprite board[9 +1][13]; // largest board size is 9 x 13
  88. Sprite label;
  89.  
  90. // all our little helpers in the order they were thought of :)
  91. void composeboard(int num_rows, int num_cols, LayerManager *lm);
  92. Image *getchecker(int color);
  93. Image *getfill(int color);
  94. bool drop(int col, int color, int x, int y, LayerManager *lm);
  95. bool win(int testcolor);
  96. void intro();
  97. Image *getwinner(int color);
  98. int strtocolor(char *str);
  99. bool strtobool(char *str);
  100. int strtocontrol(char *str);
  101. int getWPADchannel(int whosturn);
  102. const char *appendpathto( char *argv, const char *str);
  103.  
  104. int main(int argc, char **argv)
  105. {
  106.     // it's an init, i'nit?
  107.     WPAD_Init();
  108.    
  109.     if (fatInitDefault())
  110.     {
  111.         FILE *f = NULL;
  112.  
  113.         f = fopen(appendpathto(argv[0], "setiiiings.ini"), "rb");
  114.         if (f == NULL)
  115.             f = fopen(appendpathto(argv[0], "settings.ini"), "rb");
  116.        
  117.         if (f != NULL) // settings parser. if neither of those exist this would still be NULL and we go on with our defaults
  118.         {
  119.             char file_line [25];
  120.             while (fgets (file_line, 25, f) && f != NULL)
  121.             {
  122.                 char *temp;
  123.                 temp = strtok(file_line, " ");
  124.                 if (temp != NULL && temp[0] != '#') // else ignore line
  125.                 {
  126.                     if (!strcmp(temp, "player2"))
  127.                     {
  128.                         temp = strtok (NULL, " ");
  129.                         if (temp != NULL)
  130.                             strtobool(temp);
  131.                     }
  132.                     if (!strcmp(temp, "whostarts"))
  133.                     {
  134.                         temp = strtok (NULL, " ");
  135.                         if (temp != NULL)
  136.                             firstplayer = strtocolor(temp);
  137.                     }
  138.                     if (!strcmp(temp, "control"))
  139.                     {
  140.                         temp = strtok (NULL, " ");
  141.                         if (temp != NULL)
  142.                             control = strtocontrol(temp);
  143.                     }
  144.                     if (!strcmp(temp, "rows"))
  145.                     {
  146.                         temp = strtok (NULL, " ");
  147.                         if (temp != NULL)
  148.                             numrows = atoi(temp);
  149.                         if (numrows <= 0 || numrows >= 10)
  150.                             numrows = 6;
  151.                     }
  152.                     if (!strcmp(temp, "cols"))
  153.                     {
  154.                         temp = strtok (NULL, " ");
  155.                         if (temp != NULL)
  156.                             numcols = atoi(temp);
  157.                         if (numcols <= 0 || numcols >= 14)
  158.                             numcols = 7;
  159.                     }
  160.                     if (!strcmp(temp, "winlength"))
  161.                     {
  162.                         temp = strtok (NULL, " ");
  163.                         if (temp != NULL)
  164.                             numwin = atoi(temp);
  165.                         int m = std::max(numcols, numrows);
  166.                         if (numwin > m)
  167.                             numwin = m;
  168.                         if (numwin <= 0)
  169.                             numwin = 4;
  170.                     }              
  171.                 }
  172.             }
  173.             fclose(f);
  174.         }
  175.                
  176.        
  177.         redchecker.LoadImage(appendpathto(argv[0], "images/redchecker.png"));
  178.         redfill.LoadImage(appendpathto(argv[0], "images/redfill.png"));
  179.         blackchecker.LoadImage(appendpathto(argv[0], "images/blackchecker.png"));
  180.         blackfill.LoadImage(appendpathto(argv[0], "images/blackfill.png"));
  181.         emptychecker.LoadImage(appendpathto(argv[0], "images/emptychecker.png"));
  182.         emptyfill.LoadImage(appendpathto(argv[0], "images/emptyfill.png"));
  183.         pressA.LoadImage(appendpathto(argv[0], "images/pressA.png"));
  184.         redwins.LoadImage(appendpathto(argv[0], "images/redwins.png"));
  185.         blackwins.LoadImage(appendpathto(argv[0], "images/blackwins.png"));
  186.         emptywins.LoadImage(appendpathto(argv[0], "images/emptywins.png"));
  187.     }
  188.  
  189.     gwd.InitVideo();
  190.     gwd.SetBackground((GXColor){ 255, 255, 255, 255 });
  191.    
  192.     LayerManager game((numrows+1)*numcols);
  193.   { // just to roll up default image loading code
  194.     if(!redchecker.IsInitialized())
  195.         if(redchecker.LoadImage(bufferredchecker) != IMG_LOAD_ERROR_NONE)
  196.             exit(0);
  197.  
  198.     if(!redfill.IsInitialized())   
  199.         if(redfill.LoadImage(bufferredfill) != IMG_LOAD_ERROR_NONE)
  200.             exit(0);
  201.  
  202.     if(!blackchecker.IsInitialized())
  203.         if(blackchecker.LoadImage(bufferblackchecker) != IMG_LOAD_ERROR_NONE)
  204.             exit(0);
  205.  
  206.     if(!blackfill.IsInitialized())
  207.         if(blackfill.LoadImage(bufferblackfill) != IMG_LOAD_ERROR_NONE)
  208.             exit(0);
  209.  
  210.     if(!emptychecker.IsInitialized())
  211.         if(emptychecker.LoadImage(bufferemptychecker) != IMG_LOAD_ERROR_NONE)
  212.             exit(0);
  213.  
  214.     if(!emptyfill.IsInitialized())
  215.         if(emptyfill.LoadImage(bufferemptyfill) != IMG_LOAD_ERROR_NONE)
  216.             exit(0);
  217.  
  218.     if(!pressA.IsInitialized())
  219.         if(pressA.LoadImage(bufferpressA) != IMG_LOAD_ERROR_NONE)
  220.             exit(0);
  221.  
  222.     if(!redwins.IsInitialized())
  223.         if(redwins.LoadImage(bufferredwins) != IMG_LOAD_ERROR_NONE)
  224.             exit(0);
  225.  
  226.     if(!blackwins.IsInitialized())
  227.         if(blackwins.LoadImage(bufferblackwins) != IMG_LOAD_ERROR_NONE)
  228.             exit(0);
  229.  
  230.     if(!emptywins.IsInitialized())
  231.         if(emptywins.LoadImage(bufferemptywins) != IMG_LOAD_ERROR_NONE)
  232.             exit(0);
  233.   }
  234.     intro();
  235.     composeboard(numrows, numcols, &game);
  236.  
  237.     int centerX = (gwd.GetWidth() - (emptychecker.GetWidth() * numcols)) / 2; // (screen size - (size of image * numcols)) / 2
  238.     int centerY = (gwd.GetHeight() - (emptychecker.GetHeight() * (numrows+1))) / 2;
  239.    
  240.     int whos_turn = firstplayer;   
  241.     int active_col = numcols / 2; // what column the checker is over (center one)
  242.     board[0][active_col].SetImage(getchecker(whos_turn%2));
  243.  
  244.     bool won = false;
  245.  
  246.     for(EVER) // playtime loop
  247.     {
  248.         WPAD_ScanPads();
  249.            
  250.         if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_HOME) // old school exit
  251.             break;
  252.  
  253.         if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_MINUS) // Arikado and Co.'s homebrew menu
  254.             homemenu(&gwd);
  255.            
  256.         if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_PLUS) // MetaFight's hombrew menu
  257.             ; // ADD THIS CODE
  258.  
  259.         if(WPAD_ButtonsDown(WPAD_CHAN_1)&WPAD_BUTTON_A) // second controller kicks in late
  260.             control = TWOWIIMOTES;
  261.            
  262.         if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_LEFT && player2) // move left
  263.         {
  264.             board[0][active_col].SetImage(getchecker(EMPTY));
  265.             active_col -= 1;
  266.             if (active_col < 0) active_col += numcols;
  267.             board[0][active_col].SetImage(getchecker(whos_turn%2));
  268.         }
  269.  
  270.         if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_RIGHT && player2) // move right
  271.         {
  272.             board[0][active_col].SetImage(getchecker(EMPTY));
  273.             active_col += 1;
  274.             if (active_col > numcols - 1) active_col -= numcols;
  275.             board[0][active_col].SetImage(getchecker(whos_turn%2));
  276.         }
  277.  
  278.         if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_B && !won && player2) // drop the checker
  279.         {
  280.             bool dropped = drop(active_col, whos_turn%2, centerX, centerY, &game);
  281.             won = win(whos_turn%2);
  282.            
  283.             if (dropped && !won) // common case
  284.             {
  285.                 whos_turn++; // change turns. black is even, red is odd
  286.                 moves++;
  287.             }
  288.            
  289.             if (won) // game over
  290.             {
  291.                 label.SetImage(getwinner(whos_turn%2));
  292.                 label.SetTransparency(0xFF);
  293.             }
  294.             else if (moves >= (numrows * numcols)) // tie
  295.             {
  296.                 label.SetImage(getwinner(EMPTY));
  297.                 label.SetTransparency(0xFF);
  298.             }
  299.            
  300.             board[0][active_col].SetImage(getchecker(whos_turn%2));
  301.         }
  302.  
  303.         if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_1 && player2) // reset game
  304.         {                              // winner gets to do it, so they have time for gloating
  305.             composeboard(numrows, numcols, &game);
  306.             moves = 0;
  307.             won = false;
  308.             whos_turn = firstplayer;
  309.             active_col = numcols / 2;
  310.             board[0][active_col].SetImage(getchecker(whos_turn%2));
  311.             centerX = (gwd.GetWidth() - (emptychecker.GetWidth() * numcols)) / 2;
  312.             centerY = (gwd.GetHeight() - (emptychecker.GetHeight() * (numrows+1))) / 2;
  313.             label.SetTransparency(0x00);
  314.         }
  315.        
  316.         if (!player2) // CPU is player 2
  317.         {
  318.             ; // DO AI HERE
  319.         }
  320.  
  321.         game.Draw(centerX, centerY);
  322.         label.Draw(-2,0);
  323.         gwd.Flush();
  324.     }
  325.    
  326.     // One last draw and ...
  327.     game.Draw(centerX, centerY);
  328.     gwd.Flush(); // ... flush twice, it's a long way to the kitchen
  329.    
  330.     // And we return to our loader!
  331.     return 0;
  332. }
  333.  
  334. void composeboard(int num_rows, int num_cols, LayerManager *lm)
  335. {
  336.     for (int row = 0; row < num_rows + 1; row++) // num_rows and the blank row on top
  337.     {
  338.         for (int col = 0; col < num_cols; col++)
  339.         {
  340.             if (!row)
  341.                 board[row][col].SetImage(&emptychecker);
  342.             else
  343.                 board[row][col].SetImage(&emptyfill);
  344.             board[row][col].SetPosition(emptychecker.GetWidth()*col, emptychecker.GetHeight()*row);
  345.             lm->Append(&(board[row][col]));
  346.         }
  347.     }
  348.     return;
  349. }
  350.  
  351. Image *getchecker(int color)
  352. {
  353.     if (color == BLACK)
  354.         return &blackchecker;
  355.     if (color == RED)
  356.         return &redchecker;
  357.     return &emptychecker;
  358. }
  359.  
  360. Image *getfill(int color)
  361. {
  362.     if (color == BLACK)
  363.         return &blackfill;
  364.     if (color == RED)
  365.         return &redfill;
  366.     return &emptyfill;
  367. }
  368.  
  369. bool drop(int col, int color, int x, int y, LayerManager *lm)
  370. {
  371.     int row;
  372.     for(row = 0; row < numrows; row++)
  373.     {
  374.         if (row != 0)
  375.         {
  376.             if (row == 1)
  377.             {
  378.                 board[row][col].SetImage(getfill(color));
  379.                 if (board[row+1][col].GetImage() != &emptyfill)
  380.                     return true;
  381.             }
  382.             else
  383.             {
  384.                 board[row-1][col].SetImage(getfill(EMPTY));
  385.                 board[row][col].SetImage(getfill(color));
  386.                 if (board[row+1][col].GetImage() != &emptyfill)
  387.                     return true;
  388.             }
  389.         }
  390.         else
  391.         {
  392.             if (board[row+1][col].GetImage() != &emptyfill)
  393.                 return false;
  394.         }
  395.        
  396.         lm->Draw(x, y);
  397.         gwd.Flush();   
  398.     }
  399.    
  400.     board[row-1][col].SetImage(getfill(EMPTY));
  401.     board[row][col].SetImage(getfill(color));
  402.     return true; // got to the bottom
  403. }
  404.  
  405. bool win(int testcolor)
  406. {
  407.     int row;
  408.     int col;
  409.     int i;
  410.     Image *color = getfill(testcolor); // what color we are trying to find lines of
  411.    
  412.     // down
  413.     for (row = 0+1; row <= numrows-numwin+1; row++) // the +1 stuff is cuz row 0 is the blank top row
  414.     {
  415.         for (col = 0; col < numcols; col++)
  416.         {
  417.             for (i = 0; i < numwin; i++)
  418.             {
  419.                 if (board[row+i][col].GetImage() != color)
  420.                     break;
  421.             }
  422.             if (i == numwin)
  423.                 return true;
  424.         }
  425.     }
  426.    
  427.     // right
  428.     for (col = 0; col <= numcols-numwin; col++)
  429.     {
  430.         for (row = 0+1; row < numrows+1; row++)
  431.         {
  432.             for (i = 0; i < numwin; i++)
  433.             {
  434.                 if (board[row][col+i].GetImage() != color)
  435.                     break;
  436.             }
  437.             if (i == numwin)
  438.                 return true;
  439.         }
  440.     }
  441.    
  442.     // downright
  443.     for (row = 0+1; row <= numrows-numwin+1; row++)
  444.     {
  445.         for (col = 0; col <= numcols-numwin; col++)
  446.         {
  447.             for (i = 0; i < numwin; i++)
  448.             {
  449.                 if (board[row+i][col+i].GetImage() != color)
  450.                     break;
  451.             }
  452.             if (i == numwin)
  453.                 return true;
  454.         }
  455.     }
  456.    
  457.     // downleft
  458.     for (row = 0+1; row <= numrows-numwin+1; row++)
  459.     {
  460.         for (col = numcols-1; col >= numcols-numwin; col--)
  461.         {
  462.             for (i = 0; i < numwin; i++)
  463.             {
  464.                 if (board[row+i][col-i].GetImage() != color)
  465.                     break;
  466.             }
  467.             if (i == numwin)
  468.                 return true;
  469.         }
  470.     }
  471.    
  472.     return false;
  473. }
  474.  
  475. void intro()
  476. {
  477.     LayerManager introlm((6+1)*7);
  478.     composeboard(6, 7, &introlm);
  479.     for (int row = 6; row >= 1; row--)
  480.     {
  481.         for (int col = 6; col >= 0; col--)
  482.         {
  483.             if (row != 2)
  484.             {
  485.                 if (col % 2)
  486.                     board[row][col].SetImage(getfill(RED));
  487.                 else
  488.                     board[row][col].SetImage(getfill(BLACK));
  489.             }
  490.             else
  491.                 board[row][col].SetImage(getfill(RED));
  492.        
  493.             introlm.Draw(152, 72);
  494.             gwd.Flush();
  495.         }
  496.     }
  497.     label.SetImage(&pressA);
  498.     for(EVER) // intro loop
  499.     {
  500.         WPAD_ScanPads();
  501.         if(WPAD_ButtonsDown(WPAD_CHAN_1)&WPAD_BUTTON_A) // second controller kicks in
  502.             control = TWOWIIMOTES;
  503.            
  504.         if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_A)
  505.         {
  506.             label.SetTransparency(0x00);
  507.             return;
  508.         }
  509.         //if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_B)exit(0); // REMOVE?
  510.         introlm.Draw(152, 72);
  511.         label.Draw(189,76);
  512.         gwd.Flush();
  513.     }
  514. }
  515.  
  516. Image *getwinner(int color)
  517. {
  518.     if (color == BLACK)
  519.         return &blackwins;
  520.     if (color == RED)
  521.         return &redwins;
  522.     return &emptywins;
  523. }
  524.  
  525. int strtocolor(char *str)
  526. {
  527.     if (!strcmp(str, "RED"))
  528.         return RED;
  529.     return BLACK;
  530. }
  531.  
  532. bool strtobool(char *str)
  533. {
  534.     if (!strcmp(str, "FALSE"))
  535.         return false;
  536.     return true;
  537. }
  538.  
  539. int strtocontrol(char *str)
  540. {
  541.     if (!strcmp(str, "TWOWIIMOTES"))
  542.         return TWOWIIMOTES;
  543.     if (!strcmp(str, "NUNCHUCK"))
  544.         return NUNCHUCK;
  545.     return ONEWIIMOTE; 
  546. }
  547.  
  548. int getWPADchannel(int whosturn)
  549. {
  550.     if (control == NUNCHUCK)
  551.         ; // return ?      
  552.     if (control == TWOWIIMOTES)
  553.         return whosturn % 2;
  554.     return WPAD_CHAN_0;
  555. }
  556.  
  557. const char *appendpathto(char *argv, const char *str)
  558. {
  559.         /*<SquidMan>
  560.         char settiiiingspath[] = "settiiiings.ini";
  561.         for(i = strlen(argv[0]) - 8, z = 0; z < 8; z++, i++)
  562.             argv[0][i] = settiiiingspath[z];*/
  563.  
  564.     std::string path = argv;
  565.     path.replace(path.size()-8, 8, str);
  566.     return path.c_str();
  567. }
  568.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement