2016-04-13 5 views
0

Ich erstelle ein Spiel von Tic Tac Toe in C mit einer Konsole-basierten Schnittstelle. Zwei Spieler gehen gegeneinander, indem sie eine Zahl zwischen 1 und 9 wählen, um ihre Steine ​​auf das Brett zu legen. Wenn du zum Beispiel einen Buchstaben eingibst, dann platzierst du deinen Stein in der oberen linken Ecke und tippst ihn in den zweiten oben in der Mitte, tippen Sie in drei würde es in der rechten oberen Ecke und so weiter). Allerdings ist mein Hauptproblem mit meinem Code, dass, wenn jemand einen Buchstaben eintippt, das Spiel im Grunde in einer ewigen Schleife stecken würde, bis Sie das Programm schließen, habe ich viele Lösungen ausprobiert (wie einen Schalterfall zu verwenden, eine Eingabe zu machen, usw.) .) aber ich weiß nicht, wie ich es beheben kann. Vielen Dank.Wie fixiere ich meine Eingabe-Validierung in meiner c-Version von Tic Tac Toe?

//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

sehen diese http://stackoverflow.com/questions/9855649/check-if-input-is-a-number-and-if-not-return-to-input –

+1

Globals den ganzen Weg nach unten! – Olaf

+0

Setzen Sie alle Ihre globalen Variablen in eine Struktur und übergeben Sie sie als Referenz, es wird viel sauberer sein. – Boiethios

Antwort

2

Wenn ein Benutzer falsche Eingabe eintritt, müssen Sie zwei Dinge tun:

  1. Löschen Sie den Zustand des Eingangsstroms, die Sie in Ihrem Programm haben.
  2. Ignorieren Sie den Rest der Zeile, die Sie nicht haben.

Was Sie brauchen, ist:

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(); 
} 

Stellen Sie sicher,

#include <limits> 

hinzufügen zu können std::numeric_limits verwenden.

0

Es gibt eine Methode, die Sie cinfail(), die aufgerufen anwenden können:

  • kehrt true, wenn der Eingang zu einer Variablen vom selben Typ wie die Variable ist
  • kehrt false, wenn die Eingabe einer Variablen nicht vom selben Typ ist wie die Variable

Also in Ihrer playercheck() Funktion, in der Sie die Eingabe und playerchoice nimmst sind definiert als Typ int,

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

eine while-Schleife in der hinzufügen, die oben prüft wiederholt für eine ganze Zahl und Zahlen 1-9, bis Sie die entsprechende Antwort erhalten.

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); 
}