#include <cassert>
#include <cstdlib> #include <iostream> #include <link.h> #include <unistd.h> #include "NimMove.hpp" #include "NimGame.hpp" #include "NimPlayer.hpp" typedef NimPlayer* NimPlayerConstructor(); NimPlayer* load_player(char* name) { std::string path("./"); // look in current directory path += name; path += ".so"; // add suffix void* handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL); if (!handle) { return nullptr; } NimPlayerConstructor* constructor = (NimPlayerConstructor*) dlsym(handle, "construct"); if (!constructor) { dlclose(handle); return nullptr; } return constructor(); } int main(int argc, char **argv) { if (argc!=3) { std::cerr << "usage: " << argv[0] << " player1 player2" << std::endl; return 1; } NimPlayer* player[2] = { load_player(argv[1]), load_player(argv[2])}; if (!player[0] || !player[1]) { std::cerr << "Loading players failed!" << std::endl; return 2; } std::cout << "*** Game of Nim ***" << std::endl; // read parameters of the game unsigned int number_of_heaps; std::cout << "Number of heaps: "; if (!(std::cin >> number_of_heaps) || number_of_heaps == 0) { std::cout << "Bye!" << std::endl; return 1; } unsigned int maxtake; std::cout << "Maximal number of sticks that can be taken in one move: "; if (!(std::cin >> maxtake)) { std::cout << "Bye!" << std::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 = maxtake * 2; maxsize = maxtake * 4; } else { minsize = 1; maxsize = 7; } unsigned int range = maxsize - minsize + 1; for (unsigned int i = 0; i < number_of_heaps; ++i) { game.set_heap_size(i, rand() % range + minsize); } while (!game.finished()) { // print current state std::cout << "Heaps:"; for (unsigned int i = 0; i < number_of_heaps; ++i) { std::cout << " " << game.get_heap_size(i); } std::cout << std::endl; NimPlayer* next_player = player[game.get_next_player()]; NimMove move = next_player->get_move(game); std::cout << next_player->get_name(); if (move.has_resigned()) { std::cout << " resigns." << std::endl; } else { std::cout << " takes " << move.get_count() << " from heap " << move.get_heap() << std::endl; } game.execute_move(move); } NimPlayer* winner = player[game.winner()]; std::cout << winner->get_name() << " has won!" << std::endl; } |