Facebook
From Violet Kangaroo, 9 Years ago, written in C++.
Embed
Download Paste or View Raw
Hits: 487
  1. #include <cstdlib>
  2. #include <ctime>
  3. #include <iostream>
  4. #include <iomanip>
  5. #include <string>
  6.  
  7. using std::rand;
  8. using std::srand;
  9. using std::time;
  10. using std::cout;
  11. using std::cin;
  12. using std::endl;
  13. using std::right;
  14. using std::left;
  15. using std::setw;
  16. using std::string;
  17.  
  18. // MineSweepBoard.h
  19.  
  20. class MineSweepBoard
  21. {
  22. public:
  23.     MineSweepBoard(int rows, int cols, float per);
  24.     MineSweepBoard(int rows, int cols);
  25.     MineSweepBoard();
  26.     virtual ~MineSweepBoard();
  27.  
  28.     static const int ROW_DEFAULT, COL_DEFAULT;
  29.     static const float CHANCE_DEFAULT;
  30.     static const unsigned char MINE_MASK, UNCOVERED_MASK;
  31.     static void Randomize();
  32.  
  33.     void RandomizeBoard();
  34.     bool IsMine(int r, int c);
  35.     bool IsUncovered(int r, int c);
  36.     int UncoverSpace(int r, int c);
  37.     int GetAdjMineCount(int r, int c);
  38.     bool IsOnBoard(int r, int c);
  39.     char GetBoardSquare(int r, int c);
  40.  
  41.     int GetRows();
  42.     int GetCols();
  43.     float GetPercentage();
  44.     int GetMineCount();
  45.     int GetSafeCount();
  46.  
  47. private:
  48.     int rowcount, colcount;
  49.     int minecount, safecount;
  50.  
  51.     float percentage;
  52.     char * board;
  53.     bool safedummy;
  54.  
  55.     void Init(int rows, int cols, float per);
  56. };
  57.  
  58. // MineSweeper.h
  59.  
  60. class MineSweeper : public MineSweepBoard
  61. {
  62. public:
  63.     MineSweeper();
  64.     MineSweeper(int rows, int cols, float difficulty);
  65.     MineSweeper(int rows, int cols, float difficulty, char mchar, char bchar, char uchar);
  66.  
  67.     static const char MINE_DEFAULT, BLANK_DEFAULT, UNKNOWN_DEFAULT;
  68.  
  69.     void PrintBoard();
  70.     char GetCharForSpace(int r, int c);
  71.     void Play();
  72.     bool WonGame();
  73. private:
  74.     char minechar, blankchar, unknownchar;
  75.     int cleared;
  76.  
  77.     void Init(char mchar, char bchar, char uchar);
  78. };
  79.  
  80. // MineSweepBoard.cpp
  81.  
  82. const int MineSweepBoard::ROW_DEFAULT = 10, MineSweepBoard::COL_DEFAULT = 10;
  83. const float MineSweepBoard::CHANCE_DEFAULT = 0.85;
  84. const unsigned char MineSweepBoard::MINE_MASK = 0x1, MineSweepBoard::UNCOVERED_MASK = 0x2;
  85.  
  86. void MineSweepBoard::Randomize()
  87. {
  88.     srand(time(NULL));
  89. }
  90.  
  91. int MineSweepBoard::GetRows()
  92. {
  93.     return rowcount;
  94. }
  95.  
  96. int MineSweepBoard::GetCols()
  97. {
  98.     return colcount;
  99. }
  100.  
  101. float MineSweepBoard::GetPercentage()
  102. {
  103.     return percentage;
  104. }
  105.  
  106. int MineSweepBoard::GetMineCount()
  107. {
  108.     return minecount;
  109. }
  110.  
  111. int MineSweepBoard::GetSafeCount()
  112. {
  113.     return safecount;
  114. }
  115.  
  116. MineSweepBoard::MineSweepBoard()
  117. {
  118.     Init(ROW_DEFAULT, COL_DEFAULT, CHANCE_DEFAULT);
  119. }
  120.  
  121. MineSweepBoard::MineSweepBoard(int rows, int cols)
  122. {
  123.     Init(rows, cols, CHANCE_DEFAULT);
  124. }
  125.  
  126. MineSweepBoard::MineSweepBoard(int rows, int cols, float per)
  127. {
  128.     Init(rows, cols, per);
  129. }
  130.  
  131. MineSweepBoard::~MineSweepBoard()
  132. {
  133.     delete[] board;
  134. }
  135.  
  136. void MineSweepBoard::Init(int rows, int cols, float per)
  137. {
  138.     minecount = 0;
  139.     safecount = rows * cols;
  140.     percentage = per;
  141.     rowcount = rows;
  142.     colcount = cols;
  143.     board = new char [rows * cols];
  144.     RandomizeBoard();
  145. }
  146.  
  147. char MineSweepBoard::GetBoardSquare(int r, int c)
  148. {
  149.     return board[r * colcount + c];
  150. }
  151.  
  152. void MineSweepBoard::RandomizeBoard()
  153. {
  154.     for (int i = 0, j = rowcount * colcount; i != j; ++i)
  155.     {
  156.         float r = (((float) rand()) / ((float) RAND_MAX));
  157.         board[i] = (percentage < r);
  158.         if (board[i]) ++minecount;
  159.     }
  160.     safecount -= minecount;
  161. }
  162.  
  163. bool MineSweepBoard::IsOnBoard(int r, int c)
  164. {
  165.     return (
  166.                (r >= 0 && r < rowcount) &&
  167.                (c >= 0 && c < colcount)
  168.            );
  169. }
  170.  
  171. bool MineSweepBoard::IsMine(int r, int c)
  172. {
  173.     return (
  174.                (IsOnBoard(r, c)) &&
  175.                (GetBoardSquare(r, c) & MINE_MASK)
  176.            );
  177. }
  178.  
  179. bool MineSweepBoard::IsUncovered(int r, int c)
  180. {
  181.     return (
  182.                (IsOnBoard(r, c)) &&
  183.                (GetBoardSquare(r, c) & UNCOVERED_MASK)
  184.            );
  185. }
  186.  
  187. int MineSweepBoard::UncoverSpace(int r, int c)
  188. {
  189.     int uncovered = 0;
  190.     while (IsOnBoard(r, c) && !IsUncovered(r, c))
  191.     {
  192.         board[r * colcount + c] |= UNCOVERED_MASK;
  193.         if (!(GetBoardSquare(r, c) & MINE_MASK)) ++uncovered;
  194.         else break;
  195.  
  196.         if (GetAdjMineCount(r, c) == 0)
  197.         {
  198.             uncovered += UncoverSpace(r + 0, c + 1);
  199.             uncovered += UncoverSpace(r + 0, c - 1);
  200.             uncovered += UncoverSpace(r + 1, c + 0);
  201.             uncovered += UncoverSpace(r - 1, c + 0);
  202.         }
  203.  
  204.         break;
  205.     }
  206.     return uncovered;
  207. }
  208.  
  209. int MineSweepBoard::GetAdjMineCount(int r, int c)
  210. {
  211.     return IsMine(r + 0, c + 1) + IsMine(r + 0, c - 1) +
  212.            IsMine(r + 1, c + 0) + IsMine(r - 1, c + 0) +
  213.            IsMine(r + 1, c + 1) + IsMine(r - 1, c - 1) +
  214.            IsMine(r + 1, c - 1) + IsMine(r - 1, c + 1);
  215. }
  216.  
  217. // MineSweeper.cpp
  218.  
  219. const char MineSweeper::MINE_DEFAULT = 'X', MineSweeper::BLANK_DEFAULT = ' ', MineSweeper::UNKNOWN_DEFAULT = '?';
  220.  
  221. MineSweeper::MineSweeper() : MineSweepBoard()
  222. {
  223.     Init(MINE_DEFAULT, BLANK_DEFAULT, UNKNOWN_DEFAULT);
  224. }
  225.  
  226. MineSweeper::MineSweeper(int rows, int cols, float difficulty) : MineSweepBoard(rows, cols, difficulty)
  227. {
  228.     Init(MINE_DEFAULT, BLANK_DEFAULT, UNKNOWN_DEFAULT);
  229. }
  230.  
  231. MineSweeper::MineSweeper(int rows, int cols, float difficulty, char mchar, char bchar, char uchar) : MineSweepBoard(rows, cols, difficulty)
  232. {
  233.     Init(mchar, bchar, uchar);
  234. }
  235.  
  236. void MineSweeper::Init(char mchar, char bchar, char uchar)
  237. {
  238.     minechar = mchar;
  239.     blankchar = bchar;
  240.     unknownchar = uchar;
  241. }
  242.  
  243. void MineSweeper::PrintBoard()
  244. {
  245.     for (int i = 0; i < GetCols(); ++i) cout << setw(4) << right << i;
  246.     cout << left << endl << endl;
  247.     for (int r = 0; r < GetCols(); ++r)
  248.     {
  249.         cout << setw(3) << r;
  250.         for (int c = 0; c < GetRows(); ++c)
  251.         {
  252.             cout << setw(4) << GetCharForSpace(r, c);
  253.         }
  254.         cout << endl;
  255.     }
  256. }
  257.  
  258. char MineSweeper::GetCharForSpace(int r, int c)
  259. {
  260.     if (IsUncovered(r, c))
  261.     {
  262.         if (IsMine(r, c))
  263.             return minechar;
  264.         int count = GetAdjMineCount(r, c);
  265.         if (count == 0)
  266.             return blankchar;
  267.         else
  268.             return '0' + count;
  269.     }
  270.     else
  271.         return unknownchar;
  272. }
  273.  
  274. void MineSweeper::Play()
  275. {
  276.     int score = 0;
  277.     PrintBoard();
  278.     cout << "Laczna ilosc bomb: " << GetMineCount() << endl;
  279.  
  280.     while (true)
  281.     {
  282.         string dummy;
  283.         int inputrow = -1, inputcol = -1;
  284.         cout << "Podaj rzad i kolumne (np. 3 2): ";
  285.         cin >> inputrow >> inputcol;
  286.         if (!cin || IsUncovered(inputrow, inputcol) || !IsOnBoard(inputrow, inputcol))
  287.         {
  288.             cout << "Bledny wybor! ";
  289.             if (!cin)
  290.             {
  291.                 cin.clear();
  292.                 cin >> dummy;
  293.             }
  294.             continue;
  295.         }
  296.  
  297.         int uncovered = UncoverSpace(inputrow, inputcol);
  298.         PrintBoard();
  299.         if (IsMine(inputrow, inputcol))
  300.         {
  301.             cout << endl << endl << "\t\tXXXXXX Trafiles na bombe XXXXXX" << endl << "\t\t\tPrzegrales." << endl << endl;
  302.             break;
  303.         }
  304.         else
  305.         {
  306.             score += uncovered;
  307.             cleared += uncovered;
  308.             if (WonGame())
  309.             {
  310.                 cout << endl << endl << "\t\t------ Wszystkie bomby znalezione ------" << endl << "\t\t\tWygrales!" << endl << endl;
  311.                 break;
  312.             }
  313.  
  314.         }
  315.     }
  316.     cout << "Twoj wynik: " << score << endl;
  317. }
  318.  
  319. bool MineSweeper::WonGame()
  320. {
  321.     return (cleared == GetSafeCount());
  322. }
  323.  
  324. // main.cpp
  325.  
  326. int main(int argc, char * argv[])
  327. {
  328.     MineSweepBoard::Randomize();
  329.  
  330.     cout << endl << endl << "\t\tWitamy w grze Saper" << endl << endl;
  331.  
  332.     while(true)
  333.     {
  334.         char again = 'n';
  335.         MineSweeper m;
  336.         m.Play();
  337.         cout << endl << "Jescze raz? (y/n) ";
  338.         cin >> again;
  339.         if (again == 'y')
  340.         {
  341.             cout << endl << endl;
  342.             continue;
  343.         }
  344.         else break;
  345.     }
  346.     return 0;
  347. }
  348.