qt/MainForm.cpp: Unneeded variable removed (take it easy ;-) - furthermore it made...
[mines3d.git] / ui / console / console.cpp
blobec71a7657f072eb8550445adb58b33fc2cd3bb2d
1 /*
2 * File: console.cpp
3 * Created: 6.1.2010
4 * Author: Petr Kubizňák
5 * Purpose:
6 */
8 /* -------------------------------------------------------------------------- */
10 #include "console.h"
11 #include "../../core/board.h"
12 #include "../../asserts.h"
13 #include "../../exceptions/AccessForbiddenException.h"
14 #include <iostream>
15 #include <iomanip>
16 #include <climits>
17 using namespace std;
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 >";
37 return os;
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);
45 int num;
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;
52 while(true) {
53 cout << "Number: ";
54 cin >> num;
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) {
69 while(true) {
70 char command;
71 cout << "Choice: ";
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) {
92 //uvodni instrukce
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;
100 //vyber nastaveni
101 cout << endl << " ***** SETTINGS *****" << endl << endl;
102 int l, r, c, m;
103 readBoardSettings(&l, &r, &c, &m);
104 Board board(r, c, l, m);
106 cout << endl << " ***** GAME *****" << endl << endl;
107 cout << board;
109 // smycka hry
110 while(true) {
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
116 } else {
117 try {
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;
122 continue;
125 } else { //prikaz = (OD/ZA)MASKOVAT
126 try {
127 board(l,r,c).setMark(!(board(l,r,c).hasMark()));
128 } catch (AccessForbiddenException e) {
129 cout << e.errText << endl;
130 continue;
134 //tisk desky a poctu vlajecek
135 cout << board << "Marks: " << board.getMarkedCount() << "/" << board.getMinesCount() << endl;
137 //testy na konec hry
138 if(uncover && board(l,r,c).hasMine()) {
139 cout << "Oooops, you stepped on a mine which exploxed!" << endl << "Sorry, you lost." << endl;
140 break;
142 if(board.isCleared()) {
143 cout << "Very well, mister!" << endl << "You won." << endl;
144 break;
146 } // konec smycky
148 cout << endl << " ***** QUIT *****" << endl;
149 return 0;