Hi!

I have a problem with an unintentionally exiting of a while loop. I'm trying to do a simple tic tac toe program. When one player has won the game, for example three X:s in a row, the program says "X wins!". So far OK. And thereafter I want the program to say "Do you want to play? y(yes) or n(no): ". But this doesn't happen. The process is shut down ie the monitor says "Process completed" and I'm out of the program.

I've been trying all different kind of possibilities but nothing works. I would be very pleased if someone could take a look at this.

Thankyou, anders

Here is the Game class:

import java.util.Scanner;
import java.lang.Object;

class Game 
{
	

  public static void main(String args[])
  {
  	String answer = "y";
  	int  w ;
  	
    LuffarSchack t = new LuffarSchack();

    Scanner scan = new Scanner (System.in);
   
   while (answer.equalsIgnoreCase("y") )
   {
   System.out.println("Give position: " );
   
   int pos = scan.nextInt();
   System.out.println("Give player: " );
   
   int player = scan.nextInt();
   
   t.setVal(pos, player);
   
   t.showGame();
   
   w = t.winner();
   
   if(w == 1)
    {
    System.out.println("X is wins!");t.resetGame();
    System.out.println("Do you want to play? y(yes) or n(no): ");
    answer = scan.nextLine();
  	}
   if(w == 2)
     {
     System.out.println("O wins!");t.resetGame();
     System.out.println(" Do you want to play? y(yes) or n(no):");
   	 answer = scan.nextLine();
   	 }
    
   if(w == -1)
     System.out.println("Next player!");
     
   	}
   }

}

and here is the tic tac toe class:

class LuffarSchack
{
  private int s1,
              s2,
              s3,
              s4,
              s5,
              s6,
              s7,
              s8,
              s9;
   
  public LuffarSchack() 
  {
    /* initialize all squares to default value of 0 */
    s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = s9 = 0; 
  }

  /*
    Method: getVal(int square)
    Parameters: square; the number of a square
    Return value: int; the value of that square (-1 if error)
  */

  public int getVal(int square)
  {

    /* 
      note: a return statement exits the method, so no
            break statements are needed.
    */

    switch(square)
    {  
      case 1: return s1;
      case 2: return s2;
      case 3: return s3;
      case 4: return s4;
      case 5: return s5;
      case 6: return s6;
      case 7: return s7;
      case 8: return s8;
      case 9: return s9;

      // if they give an invalid square number, return an error code of -1
      default: return -1; 
   }
  }
    
  /*
    Method: setVal(int square, int value)
    Parameters: square; square number, value; value to set that square
    Return: boolean; whether the square was set correctly
  */

  public boolean setVal(int square, int value)
  {
   
    // if they give an invalid value, then return an error
    if(value < 1 || value > 2)
      return false;

    /* 
      switch requires a variable of type char, byte, short, or int as
      input.
    */

    switch(square)
    {
      /*
        check each case below to see if it is the variable
        sent to us in square. if so, check to see if the square is
        already set. if not, set it's value.

      */

      case 1: if(s1 < 1) { s1 = value; return true; } break;
      case 2: if(s2 < 1) { s2 = value; return true; } break; 
      case 3: if(s3 < 1) { s3 = value; return true; } break;
      case 4: if(s4 < 1) { s4 = value; return true; } break;
      case 5: if(s5 < 1) { s5 = value; return true; } break;
      case 6: if(s6 < 1) { s6 = value; return true; } break;
      case 7: if(s7 < 1) { s7 = value; return true; } break;
      case 8: if(s8 < 1) { s8 = value; return true; } break;
      case 9: if(s9 < 1) { s9 = value; return true; } break;
    }


    /*
      if we haven't set a value, the user has either given an
      invalid square number of the value of that square is already
      set. return false (ie. no we didn't set the square's value)
    */

    return false;
  }

  /*
   Method: resetGame()
   Parameters: none
   Return: none
   Purpose: reset the game to it's initial state
  */

  public void resetGame()
  {
    s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = s9 = 0;
  }

 /*
   Method: winner()
   Parameters: none
   Return: int; value of winner
   Purpose: 
     this function determines the winner of the tic tac toe game, if any
     and returns 1 if it's X and 2 if it's O and 0 if no winner.*/

  public int  winner()
  {
     
    if((s1==2) && (s2==2) &&(s3==2))
    {	int w = 2;
      return w;}
    else if((s1==1) && (s2==1) &&(s3==1))
    { int 	w = 1;
      return w;}
 
    
    if((s4==2) && (s5==2) &&(s6==2))
      {	int w = 2;
      return w;}
    else if((s4==1) && (s5==1) &&(s6==1))
      { int w = 1;
      return w;}
    
    if((s7==2) && (s8==2) &&(s9==2))
      {	int w = 2;
      return w;}
    else if((s7==1) && (s8==1) &&(s9==1))
      { int w = 1;
      return w;}
    

    // check columns
	if((s1==2) && (s4==2) &&(s7==2))
    {	int w = 2;
      return w;}
    else if((s1==1) && (s4==1) &&(s7==1))
    { int 	w = 1;
      return w;}
 
    
    if((s2==2) && (s5==2) &&(s8==2))
      {	int w = 2;
      return w;}
    else if((s2==1) && (s5==1) &&(s8==1))
      { int w = 1;
      return w;}
    
    if((s3==2) && (s6==2) &&(s9==2))
      {	int w = 2;
      return w;}
    else if((s3==1) && (s6==1) &&(s9==1))
      { int w = 1;
      return w;}
      
      // check diagonals
    
    if((s1==2) && (s5==2) &&(s9==2))
      {	int w = 2;
      return w;}
    else if((s1==1) && (s5==1) &&(s9==1))
      { int w = 1;
      return w;}
    
    if((s3==2) && (s5==2) &&(s7==2))
      {	int w = 2;
      return w;}
    else if((s3==1) && (s5==1) &&(s7==1))
      { int w = 1;
      return w;}
      
      
      int w = -1;
    return w;
  }

 public void showGame()
  {
    System.out.println("");
    System.out.println(" " + toPiece(s1) + " | " + toPiece(s2) + " | " +
                       toPiece(s3));
    System.out.println("---+---+---");
    System.out.println(" " + toPiece(s4) + " | " + toPiece(s5) + " | " +
                       toPiece(s6));
    System.out.println("---+---+---");
    System.out.println(" " + toPiece(s7) + " | " + toPiece(s8) + " | " +
                       toPiece(s9));
    System.out.println("");
  }

  /*
   Method: toPiece
   Parameters: piece; an integer representing an X or O
   Return: String; the corresponding piece
  */

  private String toPiece(int piece)
  {
    if(piece == 1)
    {
    	return "X";
    }
    else 
    	if(piece == 2)
    	{
    		return "O";
    	}
    else
      return " ";
  }

}

because the answer does not read y, it reads a whitespace character from the last read line, then it doesnt read the "y" entered.
Change the following portion as this:

if (w == 1) {
				System.out.println("X is wins!");
				t.resetGame();
				scan.nextLine();
				System.out.println("Do you want to play? y(yes) or n(no): ");
				answer = scan.nextLine();
			}
			if (w == 2) {
				System.out.println("O wins!");
				t.resetGame();
				scan.nextLine();
				System.out.println(" Do you want to play? y(yes) or n(no):");
				answer = scan.nextLine();
			}

Also, please use code tags to make your code more readable.

because the answer does not read y, it reads a whitespace character from the last read line, then it doesnt read the "y" entered.
Change the following portion as this:

if (w == 1) {
				System.out.println("X is wins!");
				t.resetGame();
				scan.nextLine();
				System.out.println("Do you want to play? y(yes) or n(no): ");
				answer = scan.nextLine();
			}
			if (w == 2) {
				System.out.println("O wins!");
				t.resetGame();
				scan.nextLine();
				System.out.println(" Do you want to play? y(yes) or n(no):");
				answer = scan.nextLine();
			}

Thanks a lot for your answer. I actually solved the problem a few hours after I posted it. But still I'm not really sure if I understand what I've been doing. I e you say "because the answer does not read y, it reads a whitespace character from the last read line, then it doesnt read the "y" entered." But why doesn't it read y, why does it read a whitespace character from the last read line??

this is a position:

you enter 1 and press enter:
1

the buffer is like this : "1+cr". then you read it with nextInt() which only reads 1 and leaves carriage return(rc) in the buffer.

then you enter 2 as the move and press enter:

2

now, from last time, there was carriage return/newline left in the buffer, now you add 2 and carriage return/newline. Its now something like this "cr+2+cr". But nextInt succeeds reading only 2, because it searches next integer, it skips first cr and catches 2, but leaving last cr in the buffer.

As long as you you nextInt() function to read moves and positions, they succeed. But when you you finish them and use nextLine() function, it searches a new line(it reads until a carriage return/newline), and it reads the last cr in the buffer. Thus it doesnt read "y" you entered.

I suggest you to use always nextLine() function to successfully read the whole line and clean the buffer. Then you use Integer.parseInt() (or Double,Long) to convert it to number.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.