#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "TicTacToe.h"


TicTacToeGame::TicTacToeGame()
{
  srand(time(NULL));

//  printf("TicTacToeGame Created\n");
}
TicTacToeGame::~TicTacToeGame()
{
  
}

void TicTacToeGame::PlaceToken(unsigned long * _playerPos, unsigned long _oppPos)
{
  unsigned long myPos = *_playerPos;
  int x,y;
  int boardLayout[9][2];  //position, score
  int bestMove = -1;
  int bestScore = -1;
  for (x = 0; x< 9; x++)
  {
    for (y = 0; y < 2; y++)
    {
      boardLayout[x][y] = 0;
    }
  }
  for (x = 0; x<9; x++)
  {
    if (myPos & 1<<x) //Have I alread put something there?
      continue;
    if (_oppPos & 1<<x) //Is my opponent there?
      continue;
    // Now need to find the best place.. eval and what not..
    boardLayout [x][VALID] = 1;
    boardLayout [x][SCORE] = CheckMove(x,myPos, _oppPos);
    if (boardLayout[x][VALID] && (boardLayout [x][SCORE] > bestScore))
    {
      bestMove = x; 
      bestScore = boardLayout [x][SCORE];
    }
  }
  if (bestMove > -1)
  { 
    myPos |= 1<<bestMove;
  }
  else
  {
    printf("ERRoR\n");
  }
  *_playerPos = myPos;
}

void TicTacToeGame::PlaceRandomToken(unsigned long * _playerPos, unsigned long _oppPos)
{
  unsigned long myPos = *_playerPos;
  int x,y;
  int boardLayout[9];
  int totalSpacesAvailable = 0;
  for (x = 0; x< 9; x++)
  {
    boardLayout[x] = 0;
  }
  for (x = 0; x<9; x++)
  {
    if (myPos & 1<<x) //Have I alread put something there?
      continue;
    if (_oppPos & 1<<x) //Is my opponent there?
      continue;

    boardLayout[totalSpacesAvailable] = x;
    totalSpacesAvailable ++;
  }
  if (totalSpacesAvailable == 0)
  {
    printf("PlaceRandomToken: Error Full Board\n");
  }
  myPos |= 1<< boardLayout[getrandom(0,totalSpacesAvailable)];
  *_playerPos = myPos;
}



int TicTacToeGame::CheckMove (int _newPos, unsigned long _myPos, unsigned long _oppPos)
{
  int x;
  _myPos |= 1<<_newPos;
  _oppPos |= 1<<_newPos;
  for (x = 0; x< TOTAL_WIN_PATTERNS; x++)
  {
    if ((_myPos & winPatterns[x]) == winPatterns[x])
    {
      return WINNER;
    } 
  }
  for (x = 0; x< TOTAL_WIN_PATTERNS; x++)
  {
    if ((_oppPos & winPatterns[x]) == winPatterns[x])
    {
      return BLOCK;
    }
  }
  for (x = 0; x< ALMOST_WIN_PATTERNS; x++)
  {
    if ((_myPos & almostWinPatterns[x]) == almostWinPatterns[x])
    {
      return ALMOST_WIN;
    }
  }
  return 0;
}
int TicTacToeGame::CheckForWinner (unsigned long _xLoc, unsigned long yLoc)
{
  int x;
  for (x = 0; x< TOTAL_WIN_PATTERNS; x++)
  {
    if ((_xLoc & winPatterns[x]) == winPatterns[x])
      return X; //X wins
  }

  for (x = 0; x< TOTAL_WIN_PATTERNS; x++)
  {
    if ((_xLoc & winPatterns[x]) == winPatterns[x])
      return Y; //y Wins
  }
  if ( (_xLoc | yLoc) == FULL_CARD)
    return 0;  //DRAW
  return -1;
}

int TicTacToeGame::PlayTicTacToeGame()
{
  winner = -1;
  xLoc = 0;
  yLoc = 0;

  while (winner == -1)
  {
    PlaceToken(&xLoc,yLoc);
    winner = CheckForWinner(xLoc,yLoc);
    if (winner == -1)
    {
//      PlaceToken(&yLoc,xLoc);
      PlaceRandomToken(&yLoc,xLoc);
      winner = CheckForWinner(xLoc,yLoc);
    }
  }
  return winner;
}
void TicTacToeGame::SetWinPatterns(unsigned long * _winPatterns, 
                                   unsigned long * _almostWinPatterns)
{
  winPatterns = _winPatterns;
  almostWinPatterns = _almostWinPatterns;
}

