4 * Author: Petr Kubizňák
8 /* -------------------------------------------------------------------------- */
11 #include "../../core/board.h"
12 #include "../../asserts.h"
13 #include "../../exceptions/AccessForbiddenException.h"
19 /* -------------------------------------------------------------------------- */
21 #define READ_AGAIN(msg1, msg2) { cin.clear(); cin.ignore(INT_MAX, '\n'); cout << (msg1) << (msg2) << endl; continue; }
23 /* -------------------------------------------------------------------------- */
25 //casto vypisovane retezce
26 const char *INVALID_INPUT
= "Invalid input! ";
27 const char *SYNTAX
= "Correct syntax corresponds to \"C n_L n_R n_C\", where \'C\' represents your command (possible values: 'U'=uncover, "
28 "'M'=(un)mask), \'n_L\' represents an ordinal number of layer, \'n_R\' a row and \'n_C\' a column. "
29 "For example expression \"U 2 6 3\" means you want to uncover a layer number two ( = third layer; indexed from zero), row six and column three.";
31 /* -------------------------------------------------------------------------- */
33 /* vytiskne pole nastaveni do vystupniho streamu; velikost pole MUSI byt (aspon) 4! */
34 ostream
& operator << (ostream
&os
, const int settingsArray
[]) {
35 os
<< "< " << settingsArray
[0] << " x " << settingsArray
[1] << " x " <<
36 settingsArray
[2] << " , " << setw(4) << settingsArray
[3] << " mines >";
40 /* -------------------------------------------------------------------------- */
42 /* umozni uzivateli zvolit rozmery desky a pocet min; hodnoty predava odkazem */
43 void readBoardSettings(int *layers
, int *rows
, int *cols
, int *mines
) {
44 assert(layers
); assert(rows
); assert(cols
); assert(mines
);
47 cout
<< "Select settings of the game:" << endl
;
48 cout
<< "\t[0]: Rookie\t" << PRESETS
[0] << endl
;
49 cout
<< "\t[1]: Advanced\t" << PRESETS
[1] << endl
;
50 cout
<< "\t[2]: Suicide\t" << PRESETS
[2] << endl
;
55 if(cin
.good() && num
>= 0 && num
< 3) break;
56 READ_AGAIN(INVALID_INPUT
, "");
58 *layers
= PRESETS
[num
][0];
59 *rows
= PRESETS
[num
][1];
60 *cols
= PRESETS
[num
][2];
61 *mines
= PRESETS
[num
][3];
64 /* -------------------------------------------------------------------------- */
66 /* precte ze vstupu pozadovane pole;
67 * vraci true, pokud se ma odkryt, false, pokud se ma oznacit */
68 bool readChoice(int *layer
, int *row
, int *col
, const Board
*b
) {
73 cin
>> command
; //prikaz
74 if(!cin
.good()) READ_AGAIN(INVALID_INPUT
, SYNTAX
);
75 if(toupper(command
) != 'U' && toupper(command
) != 'M')
76 READ_AGAIN(INVALID_INPUT
, "Possible commands are only 'U' and 'M'.");
78 cin
>> (*layer
) >> (*row
) >> (*col
); //souradnice
79 if(!cin
.good()) READ_AGAIN(INVALID_INPUT
, SYNTAX
);
80 if((*layer
>= 0) && (*layer
< b
->getLayersCount()) && (*row
>= 0) &&
81 (*row
< b
->getRowsCount()) && (*col
>=0) && (*col
< b
->getColsCount()))
82 return (toupper(command
) == 'U');
84 READ_AGAIN(INVALID_INPUT
, "Some index is out of bounds.");
88 /* -------------------------------------------------------------------------- */
90 /* spusti hru v konzolovem modu */
91 int consoleMain(void) {
93 cout
<< " ***** MINES3D *****" << endl
<< endl
;
94 cout
<< "Welcome to Mines3D - extended minesweeper game!" << endl
<< endl
;
95 cout
<< "The rules are easy - uncover every field on the board except those where mines are hidden." << endl
<<
96 "The classic game is extended by a third dimension, so there is a possibility of up to 26 mines around one field." << endl
<< endl
;
97 cout
<< "Just select the settings of the board (size and count of mines) and start playing." << endl
;
98 cout
<< "You only need to periodically type in which field to uncover. Use a specified syntax: " << SYNTAX
<< endl
;
101 cout
<< endl
<< " ***** SETTINGS *****" << endl
<< endl
;
103 readBoardSettings(&l
, &r
, &c
, &m
);
104 Board
board(r
, c
, l
, m
);
106 cout
<< endl
<< " ***** GAME *****" << endl
<< endl
;
111 bool uncover
= readChoice(&l
, &r
, &c
, &board
);
112 if(uncover
) { //prikaz = ODKRYT
113 if(!(board(l
,r
,c
).isCovered())) {
114 cout
<< "This field is already uncovered." << endl
;
115 continue; //nic se nezmenilo -> vynechame tisk
118 board
.uncover(l
,r
,c
);
119 } catch (AccessForbiddenException e
) {
120 cout
<< e
.errText
<< endl
;
121 cout
<< "Unmark the field firstly, use the \'M\' command." << endl
;
125 } else { //prikaz = (OD/ZA)MASKOVAT
127 board(l
,r
,c
).setMark(!(board(l
,r
,c
).hasMark()));
128 } catch (AccessForbiddenException e
) {
129 cout
<< e
.errText
<< endl
;
134 //tisk desky a poctu vlajecek
135 cout
<< board
<< "Marks: " << board
.getMarkedCount() << "/" << board
.getMinesCount() << endl
;
138 if(uncover
&& board(l
,r
,c
).hasMine()) {
139 cout
<< "Oooops, you stepped on a mine which exploxed!" << endl
<< "Sorry, you lost." << endl
;
142 if(board
.isCleared()) {
143 cout
<< "Very well, mister!" << endl
<< "You won." << endl
;
148 cout
<< endl
<< " ***** QUIT *****" << endl
;