2016-04-13 15 views
0

Konsol tabanlı bir arayüz kullanarak C'deki Tic Tac Toe oyununu oluşturuyorum. İki oyuncu, tahtaya parçalarını yerleştirmek için 1-9 arasında bir sayı seçerek birbirlerine karşı çıkıyorlar (Örneğin, eğer bir tane yazıyorsanız, o zaman parçanızı sol üst köşeye yerleştirecek, iki harfle yazacaksınız. üst orta, üç yazarak onu sağ üst köşeye yerleştirin ve böylece). Ancak benim kodumla ilgili asıl sorunum, bir kişi bir mektupta yazdığı zaman, program kapanana kadar temelde sonsuz bir döngüde sıkışmış olacaktı, birçok çözüm denedim (bir anahtar kutusu kullanarak, bir giriş yapmak gibi, bir .) ama nasıl tamir edeceğimi bilmiyorum. Teşekkür ederim. Bir kullanıcı yanlış girişi girdiğindeTic Tac Toe c sürümümde giriş onaylamam nasıl düzeltilir?

//Libaries 
#include <iostream> 
#include <string> 
#include <array> 

using namespace std; 
//Indentifers 
void gamescreen(); //Used to display the board 
char gamecondition(); //This is indentifer is used to check the game is won lost/draw 
void playerturn(); 
void playernames(); 
int resultsscreen(); 
int turn; 
int playerinput(int playerchoice); 
int Player1Score, Player2Score; 

//Variables 
//int menuchoice; //Not Neeeded for now 
char PlayerPiece = 'X'; 
char GameWinner; 
char board[3][3] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' }; //Creates a 3 by 3 matrix, which is basically the board. 
int playerchoice; //Reason why playerchoice is a int rather than a char is because 
string Player1Name, Player2Name; 
char finalchoice; 

void playernames() 
{ 
    cout << "Player 1 please enter your name" << endl; //Asks for the first username 
    cin >> Player1Name; // Gets the first user name 
    cout << "Player 2 please enter your name" << endl; //Asks for the second username 
    cin >> Player2Name; // Gets the second user name 
    cout << "Player 1 Name is: " << Player1Name << " " << "and Player 2 name is: " << Player2Name << endl; //Displays Usernames 
} 

void gamescreen() //Displays the board on the screen to the players 
{ 
    system("cls"); //CLears the screen again, to make the game clean and tidy 
    cout << "SCOREBOARD: " << Player1Name << ": " << Player1Score << " " << Player2Name << ": " << Player2Score << endl; 
    cout << "\n" << endl; 

    cout << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << endl; 
    cout << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << endl; 
    cout << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << endl; 
} 

void playercheck() 
{ 
    cout << "It is Player: " << PlayerPiece << " Turn, please put select a piece on the board" << endl; 
    cin >> playerchoice; 
    playerinput(playerchoice); 
} 
int playerinput(int playerchoice) 
{ 
    if (playerchoice > 9 || playerchoice < 1 || cin.fail()) 
    { 
     cout << "Please enter a number from 1-9!" << endl; 
     cin.clear(); 
     playercheck(); 
    } 
    else 
    { 
     if (playerchoice == 1) //If the player chose this one then 
     { 
      if (board[0][0] == '1') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down 
       board[0][0] = PlayerPiece; //If the condition is true, then it replaces that board space with the player piece 
      else 
      { 
       cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up 
       playercheck(); //This function is called again to elimate the need for loops. 
      } 
     } 
     else if (playerchoice == 2) //If the player chose this one then 
     { 
      if (board[0][1] == '2') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down 
       board[0][1] = PlayerPiece; 
      else 
      { 
       cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up 
       playercheck(); //This function is called again to elimate the need for loops. 
      } 
     } 
     else if (playerchoice == 3) //If the player chose this one then 
     { 
      if (board[0][2] == '3') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down 
       board[0][2] = PlayerPiece; 
      else 
      { 
       cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up 
       playercheck(); //This function is called again to elimate the need for loops. 
      } 
     } 
     else if (playerchoice == 4) //If the player chose this one then 
     { 
      if (board[1][0] == '4') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down 
       board[1][0] = PlayerPiece; 
      else 
      { 
       cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up 
       playercheck(); //This function is called again to elimate the need for loops. 
      } 
     } 
     else if (playerchoice == 5) //If the player chose this one then 
     { 
      if (board[1][1] == '5') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down 
       board[1][1] = PlayerPiece; 
      else 
      { 
       cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up 
       playercheck(); //This function is called again to elimate the need for loops. 
      } 
     } 
     else if (playerchoice == 6) //If the player chose this one then 
     { 
      if (board[1][2] == '6') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down 
       board[1][2] = PlayerPiece; 
      else 
      { 
       cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up 
       playercheck(); //This function is called again to elimate the need for loops. 
      } 
     } 
     else if (playerchoice == 7) //If the player chose this one then 
     { 
      if (board[2][0] == '7') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down 
       board[2][0] = PlayerPiece; 
      else 
      { 
       cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up 
       playercheck(); //This function is called again to elimate the need for loops. 
      } 
     } 
     else if (playerchoice == 8) //If the player chose this one then 
     { 
      if (board[2][1] == '8') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down 
       board[2][1] = PlayerPiece; 
      else 
      { 
       cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up 
       playercheck(); //This function is called again to elimate the need for loops. 
      } 
     } 
     else if (playerchoice == 9) //If the player chose this one then 
     { 
      if (board[2][2] == '9') //This turns the number into a position on the board, it checks if the place is valid and there isn't a position on the board. If so then it places the player piece down 
       board[2][2] = PlayerPiece; 
      else 
      { 
       cout << "This move is invalid because this space has been claimed" << endl; //However if there was not a space or the player just decides to put a number other than 1-9 then this message pops up 
       playercheck(); //This function is called again to elimate the need for loops. 
      } 
     } 
     else 
     { 
      cout << "Please enter in a valid number!" << endl; 
      playercheck(); 
      //Fail safe just in case the first one failed somehow. 
     } 
    } 
    //The if statements about choices, etc. Checking if this space has not been picked yet 

    //NEED TO CHANGE ALL OF THE NUMBERS 
    return 1; 
} 

void playerturn() 
{ 
    if (PlayerPiece == 'X') 
     PlayerPiece = 'O'; 
    else 
     PlayerPiece = 'X'; 
} 

char gamecondition() //This is used to check the win conidtion aka who won or if not how does this game draw? 
{ 
    //Checks for the first player 
    if (board[0][0] == 'X' && board[0][1] == 'X' && board[0][2] == 'X') 
     return 'X'; //Basically this checks if the there is three in a row in the board, if show it returns the value X, which will be shown in the main. (Basically if GameWinner == X, cout << "Player1 wins!" << endl; 
    if (board[1][0] == 'X' && board[1][1] == 'X' && board[1][2] == 'X') 
     return 'X'; 
    if (board[2][0] == 'X' && board[2][1] == 'X' && board[2][2] == 'X') 
     return 'X'; 
    if (board[0][0] == 'X' && board[1][0] == 'X' && board[2][0] == 'X') 
     return 'X'; 
    if (board[0][1] == 'X' && board[1][1] == 'X' && board[2][1] == 'X') 
     return 'X'; 
    if (board[0][2] == 'X' && board[1][2] == 'X' && board[2][2] == 'X') 
     return 'X'; 
    if (board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X') 
     return 'X'; 
    if (board[2][0] == 'X' && board[1][1] == 'X' && board[0][2] == 'X') 
     return 'X'; //Returns X to the gamecondition() 

        //Checks for the second player 
    if (board[0][0] == 'O' && board[0][1] == 'O' && board[0][2] == 'O') 
     return 'O'; //Basically this checks if the there is three in a row in the board, if show it returns the value X, which will be shown in the main. (Basically if gameconidition == X, cout << "Player1 wins!" << endl; 
    if (board[1][0] == 'O' && board[1][1] == 'O' && board[1][2] == 'O') 
     return 'O'; 
    if (board[2][0] == 'O' && board[2][1] == 'O' && board[2][2] == 'O') 
     return 'O'; 
    if (board[0][0] == 'O' && board[1][0] == 'O' && board[2][0] == 'O') 
     return 'O'; 
    if (board[0][1] == 'O' && board[1][1] == 'O' && board[2][1] == 'O') 
     return 'O'; 
    if (board[0][2] == 'O' && board[1][2] == 'O' && board[2][2] == 'O') 
     return 'O'; 
    if (board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O') 
     return 'O'; 
    if (board[2][0] == 'O' && board[1][1] == 'O' && board[0][2] == 'O') 
     return 'O'; 

    else 
     return '/'; //If it isn't either O or X then returns '/' which shows it's a draw 
} 



int main() 
{ 
    playernames(); 
    turn = 0; //This is a turn counter, this will be used to determine the draw (Without it the game will keep on going) 
    gamescreen(); //Displays the game screen again 
    while (1) 
    { 
     turn++; //If the game hasn't been completed yet then adds 1 to the number counter 
     playercheck(); 
     gamescreen(); 
     if (gamecondition() == 'X') 
     { 
      cout << Player1Name << "X wins!" << endl; 
      Player1Score++; 
      resultsscreen(); 
     } 
     else if (gamecondition() == 'O') 
     { 
      cout << Player2Name << " wins!" << endl; 
      Player2Score++; 
      resultsscreen(); 
     } 
     else if (gamecondition() == '/' && turn == 9) 
     { 
      cout << "It's a draw!" << endl; 
      resultsscreen(); 
     } 
     playerturn(); 
    } 
} 
int resultsscreen() 
{ 
    cout << "The current score is:" << endl; 
    cout << Player1Name << ":" << Player1Score << endl; 
    cout << Player2Name << ":" << Player2Score << endl; 
    cout << "Would you like to play again, Y/N?" << endl; 

    cin >> finalchoice; 

    if (finalchoice == 'Y' || finalchoice == 'y') 
    { 
     turn = 0; 
     board[0][0] = '1', board[0][1] = '2', board[0][2] = '3'; 
     board[1][0] = '4', board[1][1] = '5', board[1][2] = '6'; 
     board[2][0] = '7', board[2][1] = '8', board[2][2] = '9'; 
     system("cls"); 
     gamescreen(); 
     playercheck(); 
     playerturn(); 
     playerinput(playerchoice); 
    } 
    if (finalchoice == 'N' || finalchoice == 'n') 
    { 
     if (Player1Score > Player2Score) 
     { 
      cout << Player1Name << " wins!" << endl; 
      system("pause"); 
      exit(0); 
     } 
     if (Player1Score < Player2Score) 
     { 
      cout << Player2Name << " wins!" << endl; 
      system("pause"); 
      exit(0); 
     } 
     else if (Player1Score == Player2Score) 
     { 
      cout << "It's a draw!" << endl; 
      system("pause"); 
      exit(0); 
     } 
    } 
    return 0; 
} 
+0

aşağı bu http://stackoverflow.com/questions/9855649/check-if-input-is-a-number-and-if-not-return-to-input –

+1

Globaller tüm yol görün! – Olaf

+0

Tüm global değişkenlerinizi bir yapıda yerleştirin ve referans olarak iletin, daha temiz olacaktır. – Boiethios

cevap

2

, iki şey yapmanız gerekir:

  1. Temizle programınızda var giriş akışı, devlet.
  2. Sahip olmadığınız satırın kalanını yoksayın.

İhtiyacın olan:

if (playerchoice > 9 || playerchoice < 1 || cin.fail()) 
{ 
    cin.clear(); 
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    cout << "Please enter a number from 1-9!" << endl; 
    playercheck(); 
} 

emin

#include <limits> 

std::numeric_limits kullanabilmek için eklemek olun.

0

Eğer cin uygulayabileceğiniz bir yöntem fail() denilen yoktur: bir değişkene giriş o değişkeni olarak aynı tip

  • döner false eğer varsa

    • döner true bir değişkene giriş Eğer giriş ve playerchoice edilir alıyorsun nerede değişken senin playercheck() işlevinde Yani

    , aynı türde değil Uygun bir yanıt elde edene kadar

    void playercheck() 
    { 
        cout << "It is Player: " << PlayerPiece << " Turn, please put select a piece on the board" << endl; 
        cin >> playerchoice; 
        playerinput(playerchoice); 
    } 
    

    o yukarıda bir süre döngü eklemek tip int olarak tanımlanan defalarca bir tamsayı ve sayılar 1-9 için denetler.

    void playercheck() 
    { 
        cout << "It is Player: " << PlayerPiece << " Turn, please put select a piece on the board" << endl; 
        cin >> playerchoice; 
    
        //while the input it less than 1, more than 9, or NOT an integer 
        while (playerchoice < 1 || playerchoice > 9 || cin.fail()) 
        { 
         cout << "You did not enter an appropriate response." << endl; 
         cout << "Please, enter in a digit between 1 and 9." << endl; 
    
    
    
         //clear the input flag on the stream so we can recheck cin.fail() 
         cin.clear(); 
         //skip up to 256 characters in the pursuit of skipping to the next newline 
         cin.ignore(256, '\n'); 
    
         cin >> playerchoice; 
        } 
    
        playerinput(playerchoice); 
    } 
    
  • İlgili konular