File indexing completed on 2024-11-24 03:43:17
0001 /******************************************************************* 0002 * 0003 * Copyright 2002,2007 Aron Boström <aron.bostrom@gmail.com> 0004 * 0005 * This file is part of the KDE project "Bovo" 0006 * 0007 * Bovo is free software; you can redistribute it and/or modify 0008 * it under the terms of the GNU General Public License as published by 0009 * the Free Software Foundation; either version 2, or (at your option) 0010 * any later version. 0011 * 0012 * Bovo is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 * GNU General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU General Public License 0018 * along with Bovo; see the file COPYING. If not, write to 0019 * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 0020 * Boston, MA 02110-1301, USA. 0021 * 0022 ********************************************************************/ 0023 0024 #include <cstdlib> 0025 #include <ctime> 0026 #include <iostream> 0027 0028 #include "board.h" 0029 #include "dim.h" 0030 0031 using namespace luffarschack; 0032 using namespace std; 0033 0034 struct error { 0035 }; 0036 0037 int tests = 0; 0038 char ESC = 27; 0039 0040 void ok(const string &s) 0041 { 0042 cout << " " << s << "... "; 0043 cout.setf(ios::right); 0044 cout << ESC << "[32m" 0045 << " [OK] " << ESC << "[0m" << endl; 0046 cout.setf(ios::left); 0047 ++tests; 0048 } 0049 0050 void fail(const string &s) 0051 { 0052 cout << " " << s << "... "; 0053 cout.setf(ios::right); 0054 cout << ESC << "[31m" 0055 << " FAILED! " << ESC << "[0m" << endl; 0056 cout.setf(ios::left); 0057 } 0058 0059 void ass(const bool b, const string &s) throw(error) 0060 { 0061 if (b) { 0062 ok(s); 0063 return; 0064 } else { 0065 fail(s); 0066 throw error(); 0067 } 0068 } 0069 0070 void status(const string &s) 0071 { 0072 cout << endl << ESC << "[33m" << s << ':' << ESC << "[0m" << endl; 0073 } 0074 0075 void testWidthHeight() throw(error) 0076 { 0077 status("Testing width and height"); 0078 short int WIDTH = 7; 0079 short int HEIGHT = 9; 0080 board b(WIDTH, HEIGHT); 0081 ass(b.width() == WIDTH, "width() for board(int, int)"); 0082 ass(b.height() == HEIGHT, "height() for board(int, int)"); 0083 ass(b.width() != HEIGHT, "width != height for board(int, int)"); 0084 WIDTH = 13; 0085 board b2(dim(WIDTH, HEIGHT)); 0086 ass(b2.width() == WIDTH, "width() for board(dim)"); 0087 ass(b2.height() == HEIGHT, "height() for board(dim)"); 0088 ass(b2.height() != WIDTH, "height != width for board(dim)"); 0089 } 0090 0091 void testOutsideBoundaries() throw(error) 0092 { 0093 status("Testing boundaries"); 0094 short int WIDTH = 3; 0095 short int HEIGHT = 4; 0096 board b(WIDTH, HEIGHT); 0097 board b2(dim(WIDTH, HEIGHT)); 0098 bool test = false; 0099 try { 0100 for (short int i = 0; i < WIDTH; ++i) 0101 for (short int j = 0; j < HEIGHT; ++j) { 0102 coord c(i, j); 0103 b.empty(c); 0104 b2.empty(c); 0105 b.player(c); 0106 b2.player(c); 0107 } 0108 test = true; 0109 } catch (outOfBounds) { 0110 test = false; 0111 } 0112 ass(test, "inside boundaries"); 0113 test = false; 0114 try { 0115 coord c(-1, 0); 0116 b.empty(c); 0117 test = false; 0118 } catch (outOfBounds) { 0119 test = true; 0120 } 0121 ass(test, "empty() lesser than width"); 0122 test = false; 0123 try { 0124 coord c(0, -1); 0125 b.empty(c); 0126 test = false; 0127 } catch (outOfBounds) { 0128 test = true; 0129 } 0130 ass(test, "empty() lesser than height"); 0131 test = false; 0132 try { 0133 coord c(WIDTH, 0); 0134 b.empty(c); 0135 test = false; 0136 } catch (outOfBounds) { 0137 test = true; 0138 } 0139 ass(test, "empty() too wide"); 0140 test = false; 0141 try { 0142 coord c(0, HEIGHT); 0143 b.empty(c); 0144 test = false; 0145 } catch (outOfBounds) { 0146 test = true; 0147 } 0148 ass(test, "empty() too high"); 0149 test = false; 0150 try { 0151 coord c(-1, 0); 0152 b.player(c); 0153 test = false; 0154 } catch (outOfBounds) { 0155 test = true; 0156 } 0157 ass(test, "player() lesser than width"); 0158 test = false; 0159 try { 0160 coord c(0, -1); 0161 b.player(c); 0162 test = false; 0163 } catch (outOfBounds) { 0164 test = true; 0165 } 0166 ass(test, "player() lesser than height"); 0167 test = false; 0168 try { 0169 coord c(WIDTH, 0); 0170 b.player(c); 0171 test = false; 0172 } catch (outOfBounds) { 0173 test = true; 0174 } 0175 ass(test, "player() too wide"); 0176 test = false; 0177 try { 0178 coord c(0, HEIGHT); 0179 b.player(c); 0180 test = false; 0181 } catch (outOfBounds) { 0182 test = true; 0183 } 0184 ass(test, "player() too high"); 0185 test = false; 0186 try { 0187 coord c(-1, 0); 0188 b.setPlayer(c, 1); 0189 test = false; 0190 } catch (outOfBounds) { 0191 test = true; 0192 } 0193 ass(test, "setPlayer() lesser than width"); 0194 test = false; 0195 try { 0196 coord c(0, -1); 0197 b.setPlayer(c, 1); 0198 test = false; 0199 } catch (outOfBounds) { 0200 test = true; 0201 } 0202 ass(test, "setPlayer() lesser than height"); 0203 test = false; 0204 try { 0205 coord c(WIDTH, 0); 0206 b.setPlayer(c, 1); 0207 test = false; 0208 } catch (outOfBounds) { 0209 test = true; 0210 } 0211 ass(test, "setPlayer() too wide"); 0212 test = false; 0213 try { 0214 coord c(0, HEIGHT); 0215 b.setPlayer(c, 1); 0216 test = false; 0217 } catch (outOfBounds) { 0218 test = true; 0219 } 0220 ass(test, "setPlayer() too high"); 0221 } 0222 0223 void testSetPlayerAndEmpty() throw(error) 0224 { 0225 status("Testing setPlayer(coord, unsigned short int) and checking with empty(coord) and player(coord)"); 0226 unsigned short int WIDTH = 3; 0227 unsigned short int HEIGHT = 4; 0228 board b(WIDTH, HEIGHT); 0229 bool test = false; 0230 try { 0231 for (unsigned short int i = 0; i < WIDTH; ++i) 0232 for (unsigned short int j = 0; j < HEIGHT; ++j) { 0233 coord c(i, j); 0234 if (!b.empty(c) || b.player(c) != 0) 0235 throw error(); 0236 } 0237 test = true; 0238 } catch (error) { 0239 test = false; 0240 } 0241 ass(test, "board is empty and player is 0"); 0242 test = false; 0243 try { 0244 coord c(1, 1); 0245 b.setPlayer(c, 1); 0246 for (unsigned short int i = 0; i < WIDTH; ++i) 0247 for (unsigned short int j = 0; j < HEIGHT; ++j) { 0248 if (i == 1 && j == 1) 0249 continue; 0250 coord c2(i, j); 0251 if (!b.empty(c2) || b.player(c2) != 0) 0252 throw busy(); 0253 } 0254 ass(b.player(c) == 1, "setPlayer(coord, 1) -> player(coord) == 1"); 0255 test = true; 0256 } catch (busy) { 0257 test = false; 0258 } 0259 ass(test, "board should still be empty"); 0260 test = false; 0261 try { 0262 coord c(1, 1); 0263 b.setPlayer(c, 1); 0264 test = false; 0265 } catch (busy) { 0266 test = true; 0267 } 0268 ass(test, "setPlayer(coord, 1) again should fail"); 0269 test = false; 0270 try { 0271 coord c(1, 1); 0272 b.setPlayer(c, 2); 0273 test = false; 0274 } catch (busy) { 0275 test = true; 0276 } 0277 ass(test, "setPlayer(coord, 2) should also fail"); 0278 ass(b.player(coord(1, 1)) == 1, "player(coord) should still be 1"); 0279 test = false; 0280 try { 0281 for (unsigned short int i = 0; i < WIDTH; ++i) 0282 for (unsigned short int j = 0; j < HEIGHT; ++j) { 0283 if (i == 1 && j == 1) 0284 continue; 0285 coord c2(i, j); 0286 b.setPlayer(c2, 2); 0287 } 0288 ass(b.player(coord(0, 0)) == 2, "setPlayer(coord, 2) -> player(coord) == 2"); 0289 test = true; 0290 } catch (busy) { 0291 test = false; 0292 } 0293 ass(test, "board should be setable"); 0294 } 0295 0296 void testGameOver() 0297 { 0298 status("Testing game over"); 0299 unsigned short int WIDTH = 29; 0300 unsigned short int HEIGHT = 29; 0301 board b(dim(WIDTH, HEIGHT)); 0302 ass(!b.setPlayer(coord(1, 1), 1), "not five in row shouldn't win"); 0303 ass(!b.setPlayer(coord(2, 1), 1), "not five in row shouldn't win"); 0304 ass(!b.setPlayer(coord(4, 1), 1), "not five in row shouldn't win"); 0305 ass(!b.setPlayer(coord(5, 1), 1), "not five in row shouldn't win"); 0306 ass(!b.setPlayer(coord(6, 1), 1), "not five in row shouldn't win"); 0307 ass(!b.setPlayer(coord(7, 1), 1), "not five in row shouldn't win"); 0308 ass(!b.setPlayer(coord(3, 1), 2), "not five in row shouldn't win"); 0309 ass(!b.setPlayer(coord(8, 1), 2), "not five in row shouldn't win"); 0310 ass(!b.setPlayer(coord(9, 1), 1), "not five in row shouldn't win"); 0311 ass(!b.setPlayer(coord(10, 1), 1), "not five in row shouldn't win"); 0312 ass(!b.setPlayer(coord(11, 1), 1), "not five in row shouldn't win"); 0313 ass(!b.setPlayer(coord(13, 1), 1), "not five in row shouldn't win"); 0314 ass(!b.setPlayer(coord(14, 1), 1), "not five in row shouldn't win"); 0315 ass(!b.setPlayer(coord(15, 1), 1), "not five in row shouldn't win"); 0316 ass(b.setPlayer(coord(12, 1), 1), "five in row should win"); 0317 try { 0318 b.setPlayer(coord(16, 1), 1); 0319 ass(false, "Nothing should be done when game is over"); 0320 } catch (gameover) { 0321 ass(b.empty(coord(16, 1)), "Nothing should be done when game is over"); 0322 } 0323 board b5(dim(WIDTH, HEIGHT)); 0324 b5.setPlayer(coord(3, 2), 2); 0325 b5.setPlayer(coord(4, 2), 2); 0326 b5.setPlayer(coord(5, 2), 2); 0327 ass(!b5.setPlayer(coord(6, 2), 2), "not five in row shouldn't win"); 0328 ass(b5.setPlayer(coord(7, 2), 2), "five in row SHOULD win"); 0329 board b4(dim(WIDTH, HEIGHT)); 0330 b4.setPlayer(coord(0, 0), 2); 0331 b4.setPlayer(coord(1, 1), 2); 0332 b4.setPlayer(coord(2, 2), 2); 0333 ass(!b4.setPlayer(coord(3, 3), 2), "not five in diag shouldn't win"); 0334 ass(b4.setPlayer(coord(4, 4), 2), "five in diag SHOULD win"); 0335 board b2(dim(WIDTH, HEIGHT)); 0336 b2.setPlayer(coord(4, 0), 2); 0337 b2.setPlayer(coord(3, 1), 2); 0338 b2.setPlayer(coord(2, 2), 2); 0339 ass(!b2.setPlayer(coord(1, 3), 2), "not five in other diag shouldn't win"); 0340 ass(b2.setPlayer(coord(0, 4), 2), "five in other diag SHOULD win"); 0341 board b3(dim(WIDTH, HEIGHT)); 0342 b3.setPlayer(coord(4, 0), 2); 0343 b3.setPlayer(coord(4, 1), 2); 0344 b3.setPlayer(coord(4, 2), 2); 0345 ass(!b3.setPlayer(coord(4, 3), 2), "not five in col shouldn't win"); 0346 ass(b3.setPlayer(coord(4, 4), 2), "five in col SHOULD win"); 0347 } 0348 0349 void testSetNonvalidPlayer() 0350 { 0351 status("Testing setting a non-valid player"); 0352 board b = board(dim(1, 1)); 0353 bool test = false; 0354 try { 0355 b.setPlayer(coord(0, 0), 0); 0356 test = false; 0357 } catch (notValidPlayer) { 0358 test = true; 0359 } 0360 ass(test, "player 0 (empty) should not work"); 0361 test = false; 0362 try { 0363 b.setPlayer(coord(0, 0), 3); 0364 test = false; 0365 } catch (notValidPlayer) { 0366 test = true; 0367 } 0368 ass(test, "player 3 should not work either"); 0369 } 0370 0371 void testEcho() 0372 { 0373 board b = board(dim(20, 20)); 0374 unsigned short int player = 1; 0375 qsrand((unsigned)time(0)); 0376 try { 0377 while (true) { 0378 coord c(0, 0); 0379 while (true) { 0380 c = coord(qrand() % 20, qrand() % 20); 0381 if (b.empty(c)) 0382 break; 0383 } 0384 b.setPlayer(c, player); 0385 player = player % 2 + 1; 0386 } 0387 } catch (busy) { 0388 } catch (gameover) { 0389 cout << endl << "Player " << player % 2 + 1 << " won" << endl; 0390 } 0391 b.echo(); 0392 } 0393 0394 int main() 0395 { 0396 try { 0397 testWidthHeight(); 0398 testOutsideBoundaries(); 0399 testSetPlayerAndEmpty(); 0400 testSetNonvalidPlayer(); 0401 testGameOver(); 0402 testEcho(); 0403 cout << endl << ESC << "[32m" << tests << " tests passed!" << ESC << "[0m" << endl; 0404 } catch (error) { 0405 cerr << endl 0406 << ESC << "[31m" 0407 << "FEL FEL FEL!!!" << ESC << "[0m" << endl; 0408 } 0409 }