Example #1
0
int main(int argc, char **argv)
{
   int debugVal, minimaxLevel, bookDepth;
   string boardClassString, outputFileName;
   const BoardClass *brdCls;
   Board *board;
   View *view;
   ofstream outFile;
   Book *book = new Book();
   
   debugVal = argc > 1 ? atoi(argv[1]) : 0;
   
   cout << "Enter boardType, level, depth, and filename: ";
   cin >> boardClassString >> minimaxLevel >> bookDepth >> outputFileName;
   
   if (!cin) 
      exit(1);
   
   if (!(brdCls = dynamic_cast<const BoardClass *>
    (Class::ForName(boardClassString)))) {
      cerr << "Unknown type " << boardClassString << endl;
      exit(1);
   }
   
   if (!(board = dynamic_cast<Board *> (brdCls->NewInstance()))) {
      cerr << "Could not create the Board" << endl;
      exit(1);
   }
   
   if (!(view = dynamic_cast<View *>(brdCls->GetViewClass()->NewInstance()))) {
      cerr << "Could not create the View" << endl;
      exit(1);
   }
   
   view->SetModel(board);
   
   outFile.open(outputFileName.c_str(), ios::out | ios::binary | ios::trunc);
   if (!outFile.is_open()) {
      cerr << "Could not open file for writing" << endl;
      exit(1);
   }
   
   book->SetLevel(minimaxLevel);
   
   BuildBook(book, board, view, minimaxLevel, bookDepth, debugVal);
   
   cout << "Writing book...";
   book->Write(outFile);
   cout << " done" << endl;

   cout << "Before clearing book, moves/keys: " << Board::Move::GetOutstanding()
    << "/" << Board::Key::GetOutstanding() << endl;
   
   delete book; book = 0;
   
   cout << "Final count, moves/keys: " << Board::Move::GetOutstanding() << "/" 
    << Board::Key::GetOutstanding() << endl;

   delete board;
   delete view;
   return 0;
}
Example #2
0
// [Staley] Write a program “MakeBook” that works like the sample executable 
// [Staley] provided.  MakeBook prompts for and accepts a single line of input 
// [Staley] of the form:
// [Staley] 
// [Staley] BoardClass level depth fileName
// [Staley] 
// [Staley] MinimaxLevel is the minimax lookahead to use when determining a 
// [Staley] best move for each board key.  BookDepth indicates how many boards 
// [Staley] to generate.  Specifically, it tells how many halfmoves from the 
// [Staley] starting board should be covered by the bookFile file.  A level 
// [Staley] of 5 and a depth of 2 indicate that you should generate a best 
// [Staley] move for the initial board and all boards reachable from it in two 
// [Staley] halfmoves (something like 257 boards for Pylos), and that for each 
// [Staley] such board you should do a lookahead-5 minimax exploration to 
// [Staley] determine the best move. 
// [Staley] 
// [Staley] I generated the boards using recursion, and you'll almost certainly 
// [Staley] have to as well.  The optimal move for each board is determined by 
// [Staley] calling Minimax with the lookahead specified, so in fact MakeBook 
// [Staley] uses double-recursion. 
// [Staley] 
// [Staley] When the bookFile is complete, write it to a binary "bookFile file" having 
// [Staley] the specified fileName.  In milestone 3  you’ll use this bookFile file 
// [Staley] to avoid minimax computations for common board positions early in 
// [Staley] the game as described above. 
// [Staley] 
// [Staley] My MakeBook executable accepts a single commandline argument giving 
// [Staley] a “debugging log level”.  (Yours need not do so.)  The only allowed 
// [Staley] value presently is 1.  If you run MakeBook with no argument, you 
// [Staley] get the output that you must match.  However, if you run it thus:
// [Staley] 
// [Staley] MakeBook 1
// [Staley] 
// [Staley] then you get a blow-by-blow description of the minimax run, with 
// [Staley] each subcall indented according to its level.  The leaf calls 
// [Staley] are the leftmost, the root calls the rightmost.  Each call gets one 
// [Staley] line of output showing the move it evaluated, and the results it 
// [Staley] arrived at for that move.
// [Staley] 
// [Staley] You can differentiate between testing your MakeBook and your 
// [Staley] transposition table by using a non-transposition board type like 
// [Staley] MancalaBoard to test just the MakeBook and non-transposition 
// [Staley] minimax,
// [Staley] 
// [Staley] You will find it necessary to track all the Keys you've generated 
// [Staley] thus far as you fill in the bookFile, so as to avoid entering the same 
// [Staley] Key twice in the bookFile (two different sequences of moves might 
// [Staley] generate the same board).  Note the "Duplicate. No bookFile entry." 
// [Staley] announcements in my output.  You must have these in yours as well.
// [Staley] 
// [Staley] A hint on how to duplicate my key count:  When I analyze a board, I 
// [Staley] first get a key for it.  Then I output the current move/key count, 
// [Staley] and then I analyze the board using the key.
int main() {
   // Restrictions:
   // 1. Your entire MakeBook.cpp can be at most 90 lines  (mine is 75).
   // Use the 'smartcount' bin in your CPE305 folder to measure this.
   // 
   // 2. No game name may appear in any of your source except for files with 
   // that game in their name.
   // 
   // 3. Your MakeBook must work correctly with my Othello classes, object 
   // files for which are supplied.  I will require an exact match with my 
   // binary file only for Othello, not for the other games.  Exact match 
   // of my text output is required for all games.
   // 
   // 4. MakeBook.cpp may only use "new" for creating a Book object.  Boards, 
   // Views, etc. are created using Class and BoardClass.
   // 
   // 5. Your MakeBook executable must run in at most twice the time mine takes
   // for a given bookFile generation.
   const BoardClass *boardClass = NULL;
   View *view = NULL;
   Board *board = NULL;
   int level = -1, depth = -1;
   string boardType(""), filename("");
   Book *bookFile = new Book();
   ofstream out;
   
   // First, prompt the user for commands of the following usage:
   cout << "Enter boardType, level, depth, and filename: ";
   cin >> boardType >> level >> depth >> filename;

   // Use reflection to instantiate the correct board, or give an error
   // message if that BoardClass type doesn't exist.
   if ((boardClass = dynamic_cast<const BoardClass *>(BoardClass::ForName(
    boardType))) == NULL || (board = dynamic_cast<Board *>(
    boardClass->NewInstance())) == NULL || (view = dynamic_cast<View *>(
    boardClass->GetViewClass()->NewInstance())) == NULL) {
      cout << "Unknown type " << boardType << endl;
      return -1;
   }
   bookFile->SetLevel(level);
   view->SetModel(board);

   // Create the "bookFile file".  This is where all the work happens.
   ConstructBookFileDFS(board, view, bookFile, boardClass->UseTransposition(), 
    level, depth);

   // When the bookFile is complete (after you finish running the DFS), write it
   // to a binary "bookFile file" having the specified fileName.
   cout << "Writing book... ";
   out.open(filename.c_str());
   bookFile->Write(out);
   cout << "done" << endl;

   cout << "Before clearing book, moves/keys: " << Board::Move::GetOutstanding()
    << "/" << Board::Key::GetOutstanding() << endl;
   delete bookFile;
   cout << "Final count, moves/keys: " << Board::Move::GetOutstanding() << "/"
    << Board::Key::GetOutstanding() << endl;

   return 0;
}