1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <unistd.h>
#include "NimMove.h"
#include "NimGame.h"

using namespace std;

int main() {
   cout << "*** Game of Nim ***" << endl;

   // read parameters of the game
   unsigned int number_of_heaps;
   cout << "Number of heaps: ";
   if (!(cin >> number_of_heaps) || number_of_heaps == 0) {
      cout << "Bye!" << endl; return 1;
   }
   unsigned int maxtake;
   cout << "Maximal number of sticks that can be taken in one move: ";
   if (!(cin >> maxtake)) {
      cout << "Bye!" << endl; return 1;
   }

   // seed pseudo random generator
   srand(getpid() ^ time(0));
   // setup game
   NimGame game(number_of_heaps, maxtake);
   unsigned int minsize; unsigned int maxsize;
   if (maxtake) {
      minsize = maxtake2; maxsize = maxtake4;
   } else {
      minsize1; maxsize7;
   }
   unsigned int range = maxsize - minsize1;
   for (unsigned int i = 0; i < number_of_heaps; ++i) {
      game.set_heap_size(i, rand() % range + minsize);
   }

   while (!game.finished()) {
      // print current state
      cout << "Heaps:";
      for (unsigned int i = 0; i < number_of_heaps; ++i) {
         cout << " " << game.get_heap_size(i);
      }
      cout << endl;
      NimMove move;
      if (game.get_next_player() == NimGame::PLAYER1) {
         // human player
         do {
            unsigned int heap_index; unsigned int count;
            cout << "Your move: ";
            if (!(cin >> heap_index >> count)) {
               cout << "Bye!" << endl; return 1;
            }
            move = NimMove(heap_index, count);
         } while (!game.valid_move(move));
      } else {
         // computer
         if (game.nim_value() == 0) {
            // bad luck
            for (unsigned int i = 0; i < number_of_heaps; ++i) {
               if (game.get_heap_size(i) > 0) {
                  move = NimMove(i1); break;
               }
            }
         } else {
            // find a winning move
            bool not_done = true;
            for (unsigned int heap_index=0; not_done && heap_index<game.get_number_of_heaps(); ++heap_index) {
                for (unsigned int count=1;
                     not_done
                     && count <= game.get_heap_size(heap_index)
                     && (maxtake==0 || count<=maxtake);
                     ++count) {
                   NimGame test = game// make a copy of the current game
                   NimMove testmove(heap_index, count); // create a move
                   test.execute_move(testmove); // execute it
                   if (test.nim_value() == 0) {
                      move = testmove;
                      not_donefalse;
                   }
                }
            }
            assert(!not_done);
         }
         cout << "Taking " << move.get_count() << " from heap "
            << move.get_heap() << endl;
      }
      game.execute_move(move);
   }
   switch (game.winner()) {
      case NimGame::PLAYER1: cout << "Congratulations!" << endl; break;
      case NimGame::PLAYER2: cout << "You lose!" << endl; break;
   }
}