View Single Post
Old 01-29-2005, 10:56 PM   #11 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Lol we need more loops .

Here is my code, where I tried to uphold your logic as much as I could. But obviously I optimized it. Check it out and see what you can do with it. There is tons of improvement left.

Code:
#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

enum Player{  HUMAN, AI } ; 

Player activePlayer = HUMAN;
int losecount(0), tiecount(0), wincount(0);
string name;

//Name of array which places X's and O's. Initialise all fields with ' '.
char toe[9]={' '};
void resetboard();
//Human move.        
void human();
void drawboard();  
// Validates human input.
bool valcheck(int entry);
//Did a player win by any chance?
bool win(Player x);
//Is there a forced winning move or defending move (in this order)?
bool force_win_lose();
//Do a random move, center first, then random corner, otherwise random side.
void do_random();
//Is the board full?
bool board_full();
//Are the two fields equal, where "compare" = 'X' or 'Y'.
bool equal(char x, char y, char compare);
void swap_player(Player& plr);
void make_move(Player plr);
void intro();
void wrap_up();

//--

int main()
{
  intro();
  
  while(1)   
  {
   srand( static_cast<unsigned>(time(0)) );
   resetboard();
   drawboard();
   while(1)
   {
     make_move(activePlayer);
     drawboard();
     if(win(activePlayer) )
     {
       //We have a winner.
       if(activePlayer == HUMAN)
       {
         cout<<"You win!"<<endl;
         ++wincount;
       }
       else //So the AI must have won.
       {
         cout<<"You lose!"<<endl;
         ++losecount;
       }    
       break;
     }
     //No winner, perhaps board is full, therefore a tie?
     if(board_full() )
     {
       cout<<"It is a tie!"<<endl;
       ++tiecount;       
       break;
     }
     //No winners, no tie. Move on to next move.
     swap_player(activePlayer);
   }
   
   char yesno;
   cout << "Would you like to play again? (y or n) \t";
   cin >> yesno;
   if (yesno == 'y' || yesno == 'Y')
   {
     system("CLS");
   }
   else
   {
     break;
   }  
 }
 
 wrap_up();
   
 system("PAUSE");
 return 0;
}

//---------------------------------------------------

void intro()
{                
  cout << "TIC-TAC-TOE" << endl << endl 
   << "You are 'X'. Use the number pad to place your O's." << endl 
   << "Please enter your name: ";
  cin >> name;
  cout<< "When you see - "<< name <<": - that means it is your turn to move." 
   << endl << "Good Luck!" << endl;
   
  char beginner('3');  
  while(1)
  {
    cout<<"Who should begin? (0 = Human, 1 = Computer) => ";
    cin>>beginner;
    if(beginner == '0')
    {
      activePlayer = HUMAN;
      break;
    }
    else if(beginner == '1')
    {
      activePlayer = AI;
      break;
    }
  }  
}  

//---------------------------------------------------

void make_move(Player plr)
{
  if(plr == HUMAN)
  {
    human();
    return;
  }
  else
  {
    //Can the AI do a forced winnning move, or a forced defending move??
     if( !force_win_lose() )
     {
       //No forced win or defend. Do a random move.
       do_random();
     }
     cout<<"\t\t\tComputer's move:"<<endl;
  }  
}  

///////////DRAW BOARD///////////////
void drawboard()
{
    cout << endl 
    << "\t\t\t " << toe[7] << " | " << toe[8] << " | " << toe[9] << endl  
    << "\t\t\t---|---|---" << endl 
    << "\t\t\t " << toe[4] << " | " << toe[5]  << " | " << toe[6] << endl 
    << "\t\t\t---|---|---" << endl 
    << "\t\t\t " << toe[1] << " | " << toe[2] << " | " << toe[3] << endl 
    << endl << endl << endl;
}

/////////////Board Reset/////////////////////

void resetboard()
{
  for( int i = 1; i < 10; ++i )
  {
    toe[i] = ' ';
  }
}

/////////////HUMAN INPUT/////////////////////

void human()
{
  int num;
  cout << name << ": ";
  cin >> num;
  //the valid result in integrated in the if statements
  while(!valcheck(num))
  {
    cout<<"Invalid move! Try again."<<endl;
    cout << name << ": ";
    cin >> num;
  }
  toe[num] = 'X';
}

//////////////////////VALIDATOR////////////////////////

bool valcheck(int entry)
{
  // because all possible moves were set to spaces,
  //this enables me to use an if statement say
  //"if toe[?] == to a blank spot...." instead of "if toe[?] != to X or O
  if(toe[entry] == ' ')
  {
    return true;
  }  
  return false;
}   
 
///////////////WIN CHECK/////////

bool win(Player x)
{
  char symb;
  if(x==HUMAN)
    symb = 'X';
  else
    symb = 'O';
    
  if
  (
   (toe[1] == symb && ((toe[2] == symb && toe[3] == symb)    
   || (toe[4] == symb && toe[7] == symb))) 
   || (toe[5] == symb && ((toe[4] == symb && toe[6] == symb) 
   || (toe[2] == symb && toe[8] == symb))) 
   || (toe[3] == symb && ((toe[6] == symb && toe[9] == symb) 
   || (toe[5] == symb && toe[7] == symb))) 
   || (toe[9] == symb && ((toe[7] == symb && toe[8] == symb) 
   || (toe[1] == symb && toe[5] == symb)))
  )
  {
    //Somebody won.
    return true;
  }  
  return false;
}

//--------------------------------

bool force_win_lose()
{
  char comp;
  int turn(1);
  
  //Just making it readable a bit.
  char a, b, c, d, e, f, g, h, i;
   a = toe[1];  b = toe[2];  c = toe[3];  d = toe[4];  e = toe[5];
   f = toe[6];  g = toe[7];  h = toe[8];  i = toe[9];
    
  
  while(turn != 3)
  {
    //Check for win first.
    if(turn == 1)
    {
      comp = 'O';
    }
    //Check for danger.
    if(turn == 2)
    {
      comp = 'X';
    }
    
    //Check if field 1...9 is a winning field. 
    //If winning, AI makes the winning move and breaks out of loop. 
    //Returns true.
    //If not winning then next iteration begins: checks for a forced defence. 
    //Returns true.
    //If not winning or losing, then return false.
    
    if((equal(b, c, comp) || equal(d, g, comp) 
    || equal(e, i, comp)) && toe[1] == ' ' )
    {
      toe[1]='O';
      return true;
    } 
    if((equal(a, c, comp) || equal(e, h, comp)) && toe[2] == ' ' )
    {
      toe[2]='O';
      return true;
    }
    if((equal(a, b, comp) || equal(f, i, comp) 
    || equal(g, e, comp)) && toe[3] == ' ' )
    {
      toe[3]='O';
      return true;
    }
    if((equal(a, g, comp) || equal(e, f, comp)) && toe[4] == ' ' )
    {
      toe[4]='O';
      return true;
    }
    if((equal(a, c, comp) || equal(b, h, comp) 
    || equal(c, g, comp) || equal(d, f, comp)) && toe[5] == ' ' )
    {
      toe[5]='O';
      return true;
    }
    if((equal(c, i, comp) || equal(d, e, comp)) && toe[6] == ' ' )
    {
      toe[6]='O';
      return true;
    }
    if((equal(a, d, comp) || equal(c, e, comp) 
    || equal(h, i, comp)) && toe[7] == ' ' )
    {
      toe[7]='O';
      return true;
    }
    if((equal(b, e, comp )|| equal(g, i, comp)) && toe[8] == ' ' )
    {
      toe[8]='O';
      return true;
    }
    if((equal(a, e, comp) || equal(c, f, comp) 
    || equal(g, h, comp)) && toe[9] == ' ' )
    {
      toe[9]='O';
      return true;
    }
    ++turn;
  }  
  //No forced defence or winning move.
  return false;  
}

//----------------------------------------

bool equal(char x, char y, char compare)
{
  if(x==compare)
  {
    if(x==y)
    {
      return true;
    }
  }
  return false;
}  

//----------------------------------------

void do_random()
{
  if(toe[5]==' ')
  {
    toe[5]='O';
    return;
  }
  
  int r;
  
  //Place in a corner preferably. 
  while(1 && (toe[1]==' '|| toe[3]==' ' || toe[7]==' ' || toe[9]==' ') )
  {    
    r = (int)(double(rand())/( ((double)RAND_MAX+1)/(double)9.0 )+1);
    if( toe[r] == ' ' && ((r&1)==1))
    {
      toe[r]='O';
      return;
    }  
  }
  
  //Otherwise place on a side.
  while(1)
  {
    r = (int)(double(rand())/( ((double)RAND_MAX+1)/(double)9.0 )+1);
    if( toe[r] == ' ')
    {
      toe[r]='O';
      return;
    }  
  }
}

//------------------------------------------

bool board_full()
{
  for(int i = 1; i < 10; ++i)
  {
    if(toe[i]==' ')
    {
      return false;
    }  
  }
  return true;  
}

//-------------------------------------------

void swap_player(Player& plr)
{
  if(plr==HUMAN)
  {
    plr=AI;
  }
  else
  {
    plr=HUMAN;
  }  
}

//-----------------------------------------

void wrap_up()
{
  cout << endl << endl << endl << "You lost " << losecount << " times." 
   << endl << "You tied "<< tiecount << " times." << endl 
   << "You won " << wincount << " times." << endl;
}
__________________
Valmont is offline   Reply With Quote