#include <iostream>
#include <iomanip>
using namespace std;

#include <deckpontoon.h>

#include <playerGame.h>


playerGame::playerGame()
{
  dealerWins=0;
  playerWins=0;

  cards = new deckpontoon();
  deal = new dealer(*cards);

  alive=false;
}

playerGame::~playerGame()
{
  delete deal;
  deal=0;

  delete cards;
  cards=0;
}


void playerGame::notalive_dealCards()
{
  assert(alive==false);

  player.reset();
  player.add(cards->draw());
  deal->hnd.reset();
  deal->hnd.add(cards->draw());

  bet=1;

  alive=true;
}


void playerGame::alive_hold()
{
  assert(alive==true);

  assert(player.isbusted()==false);

  deal->play();

  alive=false;

  if (deal->hnd.isbusted())
  {
    playerWins += bet;
    return;
  }

  if (deal->hnd.value > player.value)
  {
    dealerWins += bet;
    return;
  }

  if (deal->hnd.value < player.value)
  {
    playerWins += bet;
    return;
  }

  // Draw game then do nothing.
}


void playerGame::alive_play()
{
  assert(alive==true);

  player.add(cards->draw());
  if (player.isbusted())
  {
    alive=false; 
    dealerWins += bet;
    return;
  }

  if (player.calculate()==21)
  {
    alive=false; 
    playerWins += bet;
    return;
  }

  
}


void playerGame::alive_doubleAndPlay()
{
  assert(alive==true);

  bet *= 2;
  alive_play();
}


playerGameSimulate::playerGameSimulate( uintc _nsamples )
  : nsamples(_nsamples)
{
}


void playerGameSimulate::calculateHit
(
  double & win,
  double & loss,
  uintc dealer0,
  uintc player0
) 
{
  dealerWins = 0;
  playerWins = 0;
  bet = 1;

  hand & dh(deal->hnd);

  if (dealer0==1)
  {
    for (uint i=0; i<nsamples; ++i)
    {
      player.value = player0;
      dh.value = 0;
      dh.hasAce = true;
      alive = true;

      alive_play();
      if (alive)
        alive_hold();
    }
  }
  else
  {
    for (uint i=0; i<nsamples; ++i)
    {
      player.value = player0;
      dh.value = dealer0;
      dh.hasAce = false;
      alive = true;

      alive_play();
      if (alive)
        alive_hold();
    }
  }

  loss = (double)dealerWins / (double) nsamples;
  win = (double)playerWins / (double) nsamples;
}




void playerGameSimulate::calculate
(
  double & win,
  double & loss,
  uintc dealer0,
  uintc player0
) 
{
  dealerWins = 0;
  playerWins = 0;
  bet = 1;

  hand & dh(deal->hnd);

  if (dealer0==1)
  {
    for (uint i=0; i<nsamples; ++i)
    {
      player.value = player0;
      dh.value = 0;
      dh.hasAce = true;
      alive = true;
      alive_hold();
    }
  }
  else
  {
    for (uint i=0; i<nsamples; ++i)
    {
      player.value = player0;
      dh.value = dealer0;
      dh.hasAce = false;
      alive = true;
      alive_hold();
    }
  }

  loss = (double)dealerWins / (double) nsamples;
  win = (double)playerWins / (double) nsamples;
}


void playerGameSimulate::tableCalculateHitRowPrint(uintc dealer0)
{
  double win;
  double loss;

  //cout << "(dealer0,player)=<dealer win,player win>" << endl;
  cout << "(dealer0,player)=&lt;dealer win,player win&gt;" << endl;

  for (uint i=7; i<19; ++i)
  {
    calculateHit(win,loss,dealer0,i);
    //cout << "(" << dealer0 << "," << i << ")=<" << loss << "," << win << ">" << endl;
    cout << "(" << dealer0 << "," << i << ")=&lt;" << loss << "," << win << "&gt;" << endl;
  }
}

void playerGameSimulate::tableCalculateHitPrint()
{
  for (uint k=1; k<=10; ++k)
    tableCalculateHitRowPrint(k);
}




void playerGameSimulate::tableCalculateRowPrint(uintc dealer0)
{
  double win;
  double loss;

  //cout << "(dealer0,player)=<dealer win,player win>" << endl;
  cout << "(dealer0,player)=&lt;dealer win,player win&gt;" << endl;

  for (uint i=12; i<21; ++i)
  {
    calculate(win,loss,dealer0,i);
    //cout << "(" << dealer0 << "," << i << ")=<" << loss << "," << win << ">" << endl;
    cout << "(" << dealer0 << "," << i << ")=&lt;" << loss << "," << win << "&gt;" << endl;
  }
}

void playerGameSimulate::tableCalculatePrint()
{
  for (uint k=1; k<=10; ++k)
    tableCalculateRowPrint(k);
}



