简体   繁体   中英

How do I make a function to check for the winning move in tic-tac-toe if the user chooses the size of the game board?

I have changed a Tic-Tac-Toe program from using a normal 3x3 grid to a grid-size chosen by the user (between 3 and 9). I am using a global constant 'SIZE' to hold the value the user chooses. My issue is adapting my winMove(); function so that it adjusts to check for the winning move based on the current board size chosen by the user(SIZE). I have tried different loops but can't get it to work. Right now it will only work with a 3x3 board.

I am still learning c++ and I have been stuck on this for a few days so I'm hoping a friendly person can help. This is my full program so far, hope it's not too much of a mess!

#include <iostream>
using namespace std;
 
struct TicTacToe
{
  char **board;  
};

void makeBoard(TicTacToe&);
void deallocBoard(TicTacToe&);
void printBoard(TicTacToe);
bool isDraw(TicTacToe);
void convertInput(char, char, int&, int&);
char winMove(TicTacToe, int, int);
bool validateSIZE(int);
int SIZE = 1;

int main(){
  while(SIZE < 3 || SIZE > 9)
  {
    cout << "Enter number between 3 and 9 for the length of board.\n";
    cout << "Example: 4 will make a board with 4 rows and 4 columns: ";
    cin >> SIZE;
    validateSIZE(SIZE);
  }

  TicTacToe game;
  makeBoard(game);
  char winner = 0;               
  char turn = 'X';               
  char rowIn, colIn;  
  int row, column; 

  while(!winner && !isDraw(game))
  {
    printBoard(game);
    cout << "\nPlayer " << turn << "'s move (input format: a1): ";
    cin >> rowIn >> colIn;
    convertInput(rowIn, colIn, row, column); 

    if (game.board[row][column]==' ')           
    {                   
      game.board[row][column] = turn;
      if (turn == 'X')                           
        {turn = 'O';}
      else                
        {turn = 'X';}
      winner = winMove(game, row, column);  
    }                               
      else
          cout << "Taken, try again!\n";     
  } 
  printBoard(game);

  if (winner == 'X' || winner == 'O')
    {cout << " Congrats, the winner is " << winner << '.' << endl;}
  else
    {cout << " Game ends in a draw." << endl;}

  cout << endl << "Game Over!" << endl << endl;
  deallocBoard(game);
  
  return 0;
}

// Need help with this function.
char winMove(TicTacToe gameIn, int i, int j) 
{
  //row win
  if (gameIn.board[i][0]==gameIn.board[i][1] &&
      gameIn.board[i][0]==gameIn.board[i][2]) 
  {
    return gameIn.board[i][j];   
  }
  //column win
  if (gameIn.board[0][j]==gameIn.board[1][j] &&
      gameIn.board[0][j]==gameIn.board[2][j])  
  {
    return gameIn.board[i][j]; 
  }
  //left diagonal win
  if (gameIn.board[0][0] != ' ' && 
      gameIn.board[0][0] == gameIn.board[1][1] && 
      gameIn.board[0][0] == gameIn.board[2][2])
  {
    return gameIn.board[i][j]; 
  }
  //right diagonal win
  if (gameIn.board[0][2] != ' ' && 
      gameIn.board[0][2] == gameIn.board[1][1] && 
      gameIn.board[0][2] == gameIn.board[2][0])
  {
    return gameIn.board[i][j]; 
  }
  return 0;
}

bool validateSIZE(int SIZE)
{
  if(SIZE < 3 || SIZE > 9)
  {
    cout << "\n\nNumber must be between 3 and 9!\nTry again!\nPlease ";
    return false;
  }
  return true;
};

void makeBoard(TicTacToe& gameIn) 
{                               
  gameIn.board = new char*[SIZE];    
  for(int i = 0; i < SIZE; i++)
    {gameIn.board[i] = new char[SIZE];}
                            
  for(int j =0; j < SIZE; j++)      
    for(int k = 0; k < SIZE; k++)  
      {gameIn.board[j][k] = ' ';}
} 

void deallocBoard(TicTacToe& gameIn)
{
  for(int i = 0; i < SIZE; i++)  
    delete [] gameIn.board[i];    
  delete [] gameIn.board;          
  gameIn.board = NULL;             
} 

void printBoard(TicTacToe gameIn) 
{
  int temp = 1;
  cout << "  ";
  
  while(temp < SIZE + 1)
  {
    cout << temp << " "; 
    temp++;
  }
  temp = 1;
  cout << endl;

  for(int i = 0; i < SIZE; i++)
    {
      cout << char(i + 'a') << '|';      
        for(int j = 0; j < SIZE; j++)
        {
            cout << gameIn.board[i][j] << '|';  
        }
      cout << endl;
    }
} 

bool isDraw(TicTacToe gameIn) 
{
  bool full = true;                    
  for(int i = 0; full && i < SIZE; i++)
    for(int j = 0; full && j < SIZE; j++)
      full = gameIn.board[i][j] != ' ';   
  return full;
} 

void convertInput(char rowIn, char colIn, int& row, int& column)
{
  row = toupper(rowIn) - 'A';  
  column = colIn - '1';    
} 

You can easily use 2 for loops to iterate every starting point and its direction to preform victory checking. Something that would look like this:

 //           hor ver diagonals
 //    dx[4] = {1, 0, 1, 1};
 //    dy[4] = {0, 1, 1, -1};

// check horizontal win
    for(int i = 0; i < SIZE; ++i)
    {
      bool win = true;
      for(int j = 1; j < SIZE; ++j)
      {
         if(gameIn.board[j][i] != gameIn.board[j - 1][i])
         {
             win = false;
             break;
         }
      }
      if(win == true){return  ;}
    }
// check vertical win
.
.
.
// check diagonal 1 win
   for(int i = 1; i < SIZE; ++i)
   {
      if(gameIn.board[i][i] != gameIn.board[i - 1][i - 1])
          break;
      if(i == SIZE - 1)return   ;
   }
// check diagonal 2 win
   for(int i = 1; i < SIZE; ++i)
   {
      if(gameIn.board[i][SIZE - i - 1] != gameIn.board[i - 1][SIZE - i])
          break;
      if(i == SIZE - 1)return   ;
   }

I'll leave the vertical win for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM