0

Using C++ (g++-4.7 on Mint 16).

Code is a unrefined (and unfinished) Tic-Tac-Toe game.

#include <iostream>
using namespace std;
int main() 
{   
    //initial data
    char turn='A';
    char ttt[] = {'1','2','3','4','5','6','7','8','9'};
    int move;
    int over=0; //0 is no, 1 is yes
    int valid=0; 

    while ( over == 0)
    {
        //display
        cout << "\n" << ttt[0] << "|" << ttt[1] << "|" << ttt[2] <<"\n-----\n";
        cout <<         ttt[3] << "|" << ttt[4] << "|" << ttt[5] <<"\n-----\n";
        cout <<         ttt[6] << "|" << ttt[7] << "|" << ttt[8] <<"\n\n Choose a number (Player " << turn << "):";

        //ask enter for play with turn
        cin >> move;
        cout << "\n";
        valid = 0;

        while (valid == 0)
        {
             //check if input is valid
             if  (((move > 0) and (move < 10)) and 
             ((ttt[move-1] != 'A') and (ttt[move-1] != 'B')) and
             (cin))
             {
                  ttt[move-1] = turn;
                  valid=1;  
             }
             else
             {
                  cout << "Invalid slot. Choose a number (Player " << turn << "):";
                  cin >> move;
                  cout << "\n";
             }
        }   

        //check if done if no //change turn then goto //display
        if (((ttt[0]==ttt[1]) and (ttt[1]==ttt[2])) or 
            ((ttt[3]==ttt[4]) and (ttt[4]==ttt[5])) or
            ((ttt[6]==ttt[7]) and (ttt[7]==ttt[8])) or

            ((ttt[0]==ttt[3]) and (ttt[3]==ttt[6])) or
            ((ttt[1]==ttt[4]) and (ttt[4]==ttt[7])) or
            ((ttt[2]==ttt[5]) and (ttt[5]==ttt[8])) or

            ((ttt[0]==ttt[4]) and (ttt[4]==ttt[8]))or
            ((ttt[2]==ttt[4]) and (ttt[4]==ttt[6])))
        {
            //display winner or say draw
            cout << "Player " << turn << " wins!\n";
            over=1;
        } 
        else
        {
            //change turn
            if (turn=='A')
            {  turn='B';
            }
            else
            {  turn='A';
            }
        }       
    } 
    return 0;
} 

There seem to be a bug on the code. On the part where check if input is valid the and (cin) seem to be failing.

When entering a character, (Instead of a number) it output continuously stacks of:

Invalid slot. Choose a number (Player A or B):

I tested the rest of condition without it, it was all working well. Is there a problem on the code or is this really "cin" problem? I've also tried out !(!cin) but it's the same scenario.

Ace Caserya
  • 2,825
  • 3
  • 25
  • 35
  • Why are you checking `... and cin`? – Mad Physicist Apr 15 '15 at 02:45
  • `and` is not a valid C++ operator, unless you #define it. This code won't compile. Use `&&` (and `||` for `or`). Otherwise please show your actual code. – The Dark Apr 15 '15 at 02:47
  • MadPhysicist, I wanna test if it's a valid int input since (!cin) is satisfied for invalid entry type. The Dark, "and" also "or" are valid on my compiler. The program is working fine, this is the actual code. – Ace Caserya Apr 15 '15 at 02:54
  • I stand corrected, they are valid tokens which mean the same as && and ||. Sorry about that. – The Dark Apr 15 '15 at 04:24

1 Answers1

1

You must clear the fail bit from the cin stream in your else block.

When you enter a character that isn't an integer, the cin stream sets the fail bit, which you correctly check for in your if statement, but you never clear it afterward. This causes your input validity check to be false forever.

#include <limits>
...
else
{
   cin.clear(); // Add this line
   cin.ignore(numeric_limits<streamsize>::max(), '\n'); // And this one
   cout << "Invalid slot. Choose a number (Player " << turn << "):";
   cin >> move;
   cout << "\n";
}

For additional information, see the documentation for std::basic_ios::clear

Update: see this question and this question for similar problems.

Essentially, you also need to tell cin to ignore whatever is in the stream or it will continually set the fail bit with its bad contents you haven't cleared yet. I modified the above snippet to work.

Community
  • 1
  • 1
John Drouhard
  • 1,209
  • 2
  • 12
  • 18