// Solve knight's tour chess puzzle
// See C++htp, exercise ?? for definitions and related discussion.
// bds 11/98
#include <stdlib.h>
#include <iostream.h>
#include "board.h"
extern int showMoves; // defining instance is in kt.cc

Board::Board(int m, int n) {
  rows = m; 
  cols = n; 
  goal = m*n;
  // allocate mem for board[][] and position history, x[] and y[].
  x = new int[goal+1]; 
  y = new int[goal+1];
  board = new int*[m];
  for (int i = 0; i < m; i++) board[i] = new int[n];

  // initialize values for board[][] and positions x[] and y[]
  for (i = 1; i <= goal; i++) y[i] = x[i] = 0;
  for (i = 0; i < m; i++)
    for (int j = 0; j < n; j++)
      board[i][j] = 0;

  // place a first knight
  last = 1;
  board[ x[ last ] ][ y[ last ] ] = last;
} // constructor Board definition

int Board::validMove( int i ) {
  static int attempts = 0; // counter of calls to validMove
  int xnew = x[last] + xstep[i];
  int ynew = y[last] + ystep[i];
  int ans = 
         0 <= xnew && xnew < rows 
     &&  0 <= ynew && ynew < cols
     &&  0 == board[ xnew ][ ynew ];
  // display of attempts
  if ( showMoves ) { // display each attempt
    for (int p = 2; p <= last; p++) cout << " ";
    cout << "from " << last << "th, ";
    cout << "validMove( " << i << " ) to [" << xnew << "][" << ynew << "] is "
         << (ans ? "true" : "false") << endl;
  }
  else { // count attempts and report periodically 
    attempts++;
    if (0 == attempts%1000)
      cout << "attempts: " << attempts << endl;
  }
  return ans;
} // member function validMove of class Board definition

void Board::extend( int i ) {
  int prev = last++;
  x[last] = x[prev] + xstep[i];
  y[last] = y[prev] + ystep[i];
  board[x[last]][y[last]] = last;
} // member function extend of class Board definition

void Board::unextend() {
  board[x[last]][y[last]] = 0;
  last--;
} // member function unextend of class Board definition

