Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 9 of 9

Thread: Logic Error in noughts and crosses game

  1. #1
    Junior Member
    Join Date
    Apr 2012
    Posts
    13
    My Mood
    Cheerful
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Logic Error in noughts and crosses game

    Here is a nought and crosses game I have been working on today.

    Its based on the user playing the computer, where the computers moves are based on a random number generation. However for some reason the computer player can place a piece over the top of the players piece, and I can't understand why this is happening.

    The checkWin() method still isn't complete, it only checks three pieces in a row next to each other, not diagonals.

    Just trying to fix the problem that I mentioned earlier, any help with be much appreciated. Thanks guys.

    import java.util.Scanner;
    import java.util.Random;
     
    class noughtsAndCrosses {
    	public static void main(String args[]){
     
    		// Game title
     
    		System.out.println("Noughts And Crosses\n");
     
    		// Declare all ints and objects to use in the game
     
    		boolean gameOver = false;
    		Scanner keyboard = new Scanner(System.in);
    		char[][] gameBoard = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
     
    		gameStart(keyboard);
    		// Main game methods
     
    		while (!gameOver){
    			display(gameBoard);
    			userInput(keyboard, gameBoard);
    			computerInput(keyboard, gameBoard);
    			gameOver = checkWin(gameBoard);
    		}
    	}
     
    	public static void display(char[][] a){
    		for (int row = 0; row < a.length; row++){
    			for (int column = 0; column < a[row].length; column++){
    				System.out.print(a[row][column] + "\t");
    			}
    			System.out.println("\n\n");
    		}
    	}
     
    	public static void gameStart(Scanner keyboard){
    		System.out.println("Please enter your first name: ");
    		String name = keyboard.next();
    		System.out.println("\nThanks, " + name + " it's your turn, choose a number to place an X!\n");
    	}
     
    	public static void userInput(Scanner keyboard, char[][] gameBoard){
     
    		int playerMove = 0;
    		char playerPiece = 'x';
    		boolean validMove = false;
     
    		while (validMove == false){
    			playerMove = keyboard.nextInt();
    			if (playerMove < 1 || playerMove > 9)
    				System.out.print("Invalid number, try again");
    			else
    				validMove = true;
    		}
     
    		placeMove(gameBoard, playerMove, playerPiece);
    	}
     
    	public static void placeMove(char[][] gameBoard, int move, char movePiece){
     
    		switch (move) {
    		case 1:
    			if(gameBoard[0][0] != 'x' || gameBoard[0][0] != 'o')
    				gameBoard[0][0] = movePiece;
    			else
    				System.out.print("Invalid move, try again");
    			break;
    		case 2:
    			if(gameBoard[0][1] != 'x' || gameBoard[0][1] != 'o')
    				gameBoard[0][1] = movePiece;
    			else
    				System.out.print("Invalid move, try again");
    			break;
    		case 3:
    			if(gameBoard[0][2] != 'x' || gameBoard[0][2] != 'o')
    				gameBoard[0][2] = movePiece;
    			else
    				System.out.print("Invalid move, try again");
    			break;
    		case 4:
    			if(gameBoard[1][0] != 'x' || gameBoard[1][0] != 'o')
    				gameBoard[1][0] = movePiece;
    			else
    				System.out.print("Invalid move, try again");
    			break;
    		case 5:
    			if(gameBoard[1][1] != 'x' || gameBoard[1][1] != 'o')
    				gameBoard[1][1] = movePiece;
    			else
    				System.out.print("Invalid move, try again");
    			break;
    		case 6:
    			if(gameBoard[1][2] != 'x' || gameBoard[1][2] != 'o')
    				gameBoard[1][2] = movePiece;
    			else
    				System.out.print("Invalid move, try again");
    			break;
    		case 7:
    			if(gameBoard[2][0] != 'x' || gameBoard[2][0] != 'o')
    				gameBoard[2][0] = movePiece;
    			else
    				System.out.print("Invalid move, try again");
    			break;
    		case 8:
    			if(gameBoard[2][1] != 'x' || gameBoard[2][1] != 'o')
    				gameBoard[2][1] = movePiece;
    			else
    				System.out.print("Invalid move, try again");
    			break;
    		case 9:
    			if(gameBoard[2][2] != 'x' || gameBoard[2][2] != 'o')
    				gameBoard[2][2] = movePiece;
    			else
    				System.out.print("Invalid move, try again");
    			break;
     
    		}
    	}
     
    	public static void computerInput(Scanner keyboard, char[][] gameBoard){
    		Random rand = new Random();
    		char computerPiece = 'o';
    		int computerMove = 1+rand.nextInt(6);
     
    		placeMove(gameBoard, computerMove, computerPiece);
     
    	}
     
    	public static boolean checkWin(char[][] gameBoard){
     
    		boolean result = false;
     
    		if (gameBoard[0][0] == 'x' && gameBoard[0][1] == 'x' && gameBoard[0][2] == 'x' ||
    				gameBoard[1][0] == 'x' && gameBoard[1][1] == 'x' && gameBoard[1][2] == 'x' ||
    						gameBoard[2][0] == 'x' && gameBoard[2][1] == 'x' && gameBoard[2][2] == 'x'){
    			System.out.println("Congratulations, you win!");
    			result = true;
    		}
     
    		if (gameBoard[0][0] == 'o' && gameBoard[0][1] == 'o' && gameBoard[0][2] == 'o' ||
    				gameBoard[1][0] == 'o' && gameBoard[1][1] == 'o' && gameBoard[1][2] == 'o' ||
    						gameBoard[2][0] == 'o' && gameBoard[2][1] == 'o' && gameBoard[2][2] == 'o'){
    			System.out.println("Too bad, you lose!");
    			result = true;
    		}
    		return result;		
    	}
    }


  2. #2
    Banned
    Join Date
    May 2010
    Location
    North Central Illinois
    Posts
    1,631
    My Mood
    Sleepy
    Thanks
    390
    Thanked 112 Times in 110 Posts

    Default Re: Logic Error in noughts and crosses game

    Where did you work on this earlier? I suggest you post the link to the other threads so that people can follow your old ones.

    As for your code, it might be operator precedence that could be doing it.

    Also, in effect, assuming that all values are in here, your code should only need to check that

    ((x,y), AND (x, y+1), AND (x,y+2) )are all hit OR that ((x,y), AND (x+1, y), AND (x+2, y) ) OR ((x,y) , AND (x+1, y+1), AND (x+2, y+2) )are all in OR ((x, y+2), AND (x+1, y+1), AND (x+2, y)) OR are all in there (And valid.)

    (Note, you should also apply the the values of x and y to also include the ones going down the right hand side as well.) Forgot to mention that.

    Also, that would apply for the lower side as well going across. Forgot those two.

    And of course the very middle itself too, not just the top.
    Last edited by javapenguin; June 13th, 2012 at 12:17 AM.

  3. #3
    Member
    Join Date
    Jun 2012
    Location
    Left Coast, USA
    Posts
    451
    My Mood
    Mellow
    Thanks
    1
    Thanked 97 Times in 88 Posts

    Default Re: Logic Error in noughts and crosses game

    Quote Originally Posted by eyesackery View Post
    ...for some reason the computer player can place a piece over the top of the players piece, and I can't understand why this is happening.
    Here's a way that you can get to the bottom of things. You already know there is a problem in a certain function, placeMove(), right?

    So...

    Modify the program so that the computer move is always 1. That is the value that placeMove() will be working on.

    Put some print statements in placeMove() so that you can see what the program is seeing.

    Start a game and enter a user move of 1.

    Look at the printed results and see if you can figure out how the program got to that point:


    .
    .  // Your other stuff
    .
    	public static void computerInput(Scanner keyboard, char[][] gameBoard){
    		Random rand = new Random();
    		char computerPiece = 'o';
    		//int computerMove = 1+rand.nextInt(6);
    		int computerMove = 1;// For debugging purposes
    		System.out.println("In computerInput: computerMove = " + computerMove);
     
    		placeMove(gameBoard, computerMove, computerPiece);
     
    	}
    .
    .  // Your other stuff
    .
    	public static void placeMove(char[][] gameBoard, int move, char movePiece){
     
    		System.out.println("In placeMove: move = " + move +
    			           ", movePiece = " + movePiece);
    		switch (move) {
    		case 1:
    			if(gameBoard[0][0] != 'x' || gameBoard[0][0] != 'o')
    			{
    				System.out.println("  case 1: gameBoard[0][0] = " +
    					gameBoard[0][0]);
    				gameBoard[0][0] = movePiece;
    			}
    			else
    				System.out.print("Invalid move, try again");
    			break;
    		case 2:
    .
    .  //Your other stuff
    .

    A run:

    Noughts And Crosses

    Please enter your first name:
    Zaphod

    Thanks, Zaphod it's your turn, choose a number to place an X!

    1 2 3


    4 5 6


    7 8 9


    1
    In placeMove: move = 1, movePiece = x
    case 1: gameBoard[0][0] = 1
    In computerInput: computerMove = 1
    In placeMove: move = 1, movePiece = o
    case 1: gameBoard[0][0] = x
    o 2 3


    4 5 6


    7 8 9



    Now, for the computer move, look, (really look) at the logic that leads the switch statement to case 1 (and the corresponding logic for the other cases).

    See how it goes? Make the program show you what it is seeing. By forcing the computer move to a particular value, you don't have to put debugging stuff in all of the cases; just the one place.

    Once you get past this point, you can proceed to make the program "smart" enough to actually play a game. (Ask yourself ---and make the program tell you---what happens if the computer move is invalid? How should the program deal with it? Stuff like that.)

    After you fix this problem, comment out the statement that forces the computer move to be 1, but, for now, you might want to leave in the statement that prints the computer move each time. You very well might be working in this area for further analysis and debugging of the game.


    Cheers,

    Z
    Last edited by Zaphod_b; June 13th, 2012 at 04:55 PM.

  4. The Following User Says Thank You to Zaphod_b For This Useful Post:

    eyesackery (June 14th, 2012)

  5. #4
    Junior Member
    Join Date
    Apr 2012
    Posts
    13
    My Mood
    Cheerful
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Logic Error in noughts and crosses game

    Hey Zaphod_b!

    Thanks for the in depth and helpful reply! Putting those print statements throughout the code was such a good idea.

    Being able to see what data the program was working with definitely helped me to pinpoint the problem.

    So now the program works, the user can win, the computer can win, and there can be a 'draw'.

    Now I'm just working on a algorithm to make the computer move with a bit more intelligence, not just with randomly generated numbers.

    I was kinda thinking to do something where the computer will always place it's move in a 1 square radius around the player if that block is available. Still trying to come up with how I am going to do this.....

    1 2 3

    X 5 6

    7 8 9

    OR


    1 2 3

    4 X 6

    7 8 9


    And here's the working code so far...

    //-------------------------------------//
    // Isaac Johnson - Noughts and Crosses //
    //-------------------------------------//
     
    import java.util.Scanner;
    import java.util.Random;
     
    class noughtsAndCrosses {
    	public static void main(String args[]){
     
    		//Game title
     
    		System.out.println("Noughts And Crosses\n");	
     
    		//Declaring all objects and integers to be used in the game
     
    		boolean gameOver = false;
    		Scanner keyboard = new Scanner(System.in);
    		int gameCount = 0;
    		char[][] gameBoard = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
     
    		gameStart(keyboard);
     
    		// Main game methods inside the game loop
     
    		while (!gameOver){
    			gameCount++;
    			display(gameBoard);
    			userInput(keyboard, gameBoard);
     
    			//This if statement checks to see if the game is a draw
     
    			if (gameCount == 5)
    			{
    				gameOver = checkWin(gameBoard);
    				if (!gameOver)
    				{
    					System.out.println("The game ends in a draw!");
    					break;
    				}
    				else
    					break;
    			}
    			computerInput(gameBoard, keyboard);
    			gameOver = checkWin(gameBoard);
     
    		}
     
    		display(gameBoard);
    	}
     
    	//Method for displaying the game board, which is a two dimensional array using characters
     
    	public static void display(char[][] a){
    		for (int row = 0; row < a.length; row++){
    			for (int column = 0; column < a[row].length; column++){
    				System.out.print(a[row][column] + "\t");
    			}
    			System.out.println("\n\n");
    		}
    	}
     
    	//This method gets the players name and gives the player the first move
     
    	public static void gameStart(Scanner keyboard){
    		System.out.println("Please enter your first name: ");
    		String name = keyboard.next();
    		System.out.println("\nThanks, " + name + " it's your turn, choose a number to place an X!\n");
    	}
     
    	//Method for getting the users move
     
    	public static void userInput(Scanner keyboard, char[][] gameBoard){
     
    		int playerMove = 0;
    		char playerPiece = 'x';
    		boolean validMove = false;
     
    		while (validMove == false){
    			playerMove = keyboard.nextInt();
    			if (playerMove < 1 || playerMove > 9)
    				System.out.print("Invalid number, try again");
    			else
    				validMove = true;
    		}
     
    		placeMove(gameBoard, playerMove, playerPiece, keyboard);
    	}
     
    	//Method to place corresponding move on the game board, works for the player and computer moves
     
    	public static void placeMove(char[][] gameBoard, int move, char movePiece, Scanner keyboard){
     
     
    		switch (move) {
    		case 1:
    			if(gameBoard[0][0] != 'x' && gameBoard[0][0] != 'o')
    			{
    				gameBoard[0][0] = movePiece;
    			}
    			else
    			{
    				System.out.print("Invalid move " + movePiece + ", try again\n");
     
    				if(movePiece == 'o')
    					computerInput(gameBoard, keyboard);
    				else
    					userInput(keyboard, gameBoard);
    			}
    			break;
    		case 2:
    			if(gameBoard[0][1] != 'x' && gameBoard[0][1] != 'o')
    			{
    				gameBoard[0][1] = movePiece;
    			}
    			else
    			{
    				System.out.print("Invalid move " + movePiece + ", try again\n");
     
    				if(movePiece == 'o')
    					computerInput(gameBoard, keyboard);
    				else
    					userInput(keyboard, gameBoard);
    			}
    			break;
    		case 3:
    			if(gameBoard[0][2] != 'x' && gameBoard[0][2] != 'o')
    			{
    				gameBoard[0][2] = movePiece;
    			}
    			else
    			{
    				System.out.print("Invalid move " + movePiece + ", try again\n");
     
    				if(movePiece == 'o')
    					computerInput(gameBoard, keyboard);
    				else
    					userInput(keyboard, gameBoard);
    			}
    			break;
    		case 4:
    			if(gameBoard[1][0] != 'x' && gameBoard[1][0] != 'o')
    			{
    				gameBoard[1][0] = movePiece;
    			}
    			else
    			{
    				System.out.print("Invalid move " + movePiece + ", try again\n");
     
    				if(movePiece == 'o')
    					computerInput(gameBoard, keyboard);
    				else
    					userInput(keyboard, gameBoard);
    			}
    			break;
    		case 5:
    			if(gameBoard[1][1] != 'x' && gameBoard[1][1] != 'o')
    			{
    				gameBoard[1][1] = movePiece;
    			}
    			else
    			{
    				System.out.print("Invalid move " + movePiece + ", try again\n");
     
    				if(movePiece == 'o')
    					computerInput(gameBoard, keyboard);
    				else
    					userInput(keyboard, gameBoard);
    			}
    			break;
    		case 6:
    			if(gameBoard[1][2] != 'x' && gameBoard[1][2] != 'o')
    			{
    				gameBoard[1][2] = movePiece;
    			}
    			else
    			{
    				System.out.print("Invalid move " + movePiece + ", try again\n");
     
    				if(movePiece == 'o')
    					computerInput(gameBoard, keyboard);
    				else
    					userInput(keyboard, gameBoard);
    			}
    			break;
    		case 7:
    			if(gameBoard[2][0] != 'x' && gameBoard[2][0] != 'o')
    			{
    				gameBoard[2][0] = movePiece;
    			}
    			else
    			{
    				System.out.print("Invalid move " + movePiece + ", try again\n");
     
    				if(movePiece == 'o')
    					computerInput(gameBoard, keyboard);
    				else
    					userInput(keyboard, gameBoard);
    			}
    			break;
    		case 8:
    			if(gameBoard[2][1] != 'x' && gameBoard[2][1] != 'o')
    			{
    				gameBoard[2][1] = movePiece;
    			}
    			else
    			{
    				System.out.print("Invalid move " + movePiece + ", try again\n");
     
    				if(movePiece == 'o')
    					computerInput(gameBoard, keyboard);
    				else
    					userInput(keyboard, gameBoard);
    			}
    			break;
    		case 9:
    			if(gameBoard[2][2] != 'x' && gameBoard[2][2] != 'o')
    			{
    				gameBoard[2][2] = movePiece;
    			}
    			else
    			{
    				System.out.print("Invalid move " + movePiece + ", try again\n");
     
    				if(movePiece == 'o')
    					computerInput(gameBoard, keyboard);
    				else
    					userInput(keyboard, gameBoard);
    			}
    			break;
     
    		}
    	}
     
    	//This method generates the computers move, which is based off a random number
     
    	public static void computerInput(char[][] gameBoard, Scanner keyboard){
    		Random rand = new Random();
    		char computerPiece = 'o';
     
    		int computerMove = 1+rand.nextInt(9);
    		System.out.println("The computer's move was " + computerMove + "\n");
     
    		placeMove(gameBoard, computerMove, computerPiece, keyboard);
     
    	}
     
    	//The check win method that checks to see if a player has one based on piece combinations
     
    	public static boolean checkWin(char[][] gameBoard){
     
    		boolean result = false;
     
    		for (int i = 0; i < gameBoard.length; i++)
    			if(gameBoard[i][0] == 'x' && gameBoard[i][1] == 'x' && gameBoard[i][2] == 'x' ||
    			   gameBoard[0][i] == 'x' && gameBoard[1][i] == 'x' && gameBoard[2][i] == 'x' ||
    			   gameBoard[0][0] == 'x' && gameBoard[1][1] == 'x' && gameBoard[2][2] == 'x' ||
    			   gameBoard[0][2] == 'x' && gameBoard[1][1] == 'x' && gameBoard[2][0] == 'x')
    			{
    				System.out.println("Congratulations you win!\n");
    				result = true;
    				break;
    			}
     
    		for (int i = 0; i < gameBoard.length; i++)
    			if(gameBoard[i][0] == 'o' && gameBoard[i][1] == 'o' && gameBoard[i][2] == 'o' ||
    			   gameBoard[0][i] == 'o' && gameBoard[1][i] == 'o' && gameBoard[2][i] == 'o' ||
    			   gameBoard[0][0] == 'o' && gameBoard[1][1] == 'o' && gameBoard[2][2] == 'o' ||
    			   gameBoard[0][2] == 'o' && gameBoard[1][1] == 'o' && gameBoard[2][0] == 'o')
    			{
    				System.out.println("You lose!\n");
    				result = true;
    				break;
    			}
     
    		return result;
    	}
    }

  6. #5
    Junior Member
    Join Date
    Apr 2012
    Posts
    13
    My Mood
    Cheerful
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Logic Error in noughts and crosses game

    After a bit more thought that method won't be much more intelligent than the random generated moves.

    Does anyone have any suggestions how I can write the computer AI? At the moment the only option I can think of is to hard code every possible player combination with a corresponding computer move.

    There must be a smarter way!

  7. #6
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    22,253
    Thanks
    56
    Thanked 2,372 Times in 2,343 Posts

    Default Re: Logic Error in noughts and crosses game

    Have an array of all possible winning combinations and use that to determine if a defensive move needs to be made or if an offensive move can be made.
    If you don't understand my answer, don't ignore it, ask a question.

  8. #7
    Junior Member
    Join Date
    Apr 2012
    Posts
    13
    My Mood
    Cheerful
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Logic Error in noughts and crosses game

    Quote Originally Posted by Norm View Post
    Have an array of all possible winning combinations and use that to determine if a defensive move needs to be made or if an offensive move can be made.
    I'm not sure what you mean by creating an array with the winning combinations? Couldn't I just use the existing array and check where pieces have been placed on the board?

    I came up with a solution, but it's not very elegant. Here is an example, it checks whether a winning move is possible for the player on the vertical and then blocks that winning move. I have this set up for horizontal and vertical possibilities also.

    My question is, how can I simplify those if statements, so they all fit into one? I know it's definitely doable, just having a hard time trying to figure out how I'm going to achieve it.

    	// Check if the player is about to win a vertical move and place a blocking move. If not place a random move
     
    			for(int k = 0; k < gameBoard.length; k++)
    			{
    				if((gameBoard[2][k] != 'o' && gameBoard[2][k] != 'x') && (gameBoard[0][k] == 'x' && gameBoard[1][k] == 'x'))
    				{
    					computerMove = Character.digit(gameBoard[2][k], 10);
    					break;
    				}
    				if((gameBoard[1][k] != 'o' && gameBoard[1][k] != 'x') && (gameBoard[0][k] == 'x' && gameBoard[2][k] == 'x'))
    				{
    					computerMove = Character.digit(gameBoard[1][k], 10);
    					break;
    		 	    }
    				if((gameBoard[0][k] != 'o' && gameBoard[0][k] != 'x') && (gameBoard[1][k] == 'x' && gameBoard[2][k] == 'x'))
    				{
    					computerMove = Character.digit(gameBoard[0][k], 10);
    					break;
    		 	    }
    				else
    					computerMove = 1+rand.nextInt(9);
    			}

  9. #8
    Junior Member
    Join Date
    Oct 2011
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Logic Error in noughts and crosses game

    what he means is make an array for offensive moves and have each move the computer can do in the offensive moves based on what the player does and do the same for defensive moves the computer can do based on what the player does and then use ifs to tell when to use each item in each array

  10. #9
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    22,253
    Thanks
    56
    Thanked 2,372 Times in 2,343 Posts

    Default Re: Logic Error in noughts and crosses game

    How many winning combinations are there? Can they be put in an array and used in a loop?
    I'm thinking of the game of tictactoe played on and 3x3 board. The 9 winning combos: 012,345,678,036,147,258,048, etc
    If you don't understand my answer, don't ignore it, ask a question.

Similar Threads

  1. Lotto Problem logic error
    By ippo in forum What's Wrong With My Code?
    Replies: 8
    Last Post: May 10th, 2012, 11:18 AM
  2. Let's build tic-tac-toe (noughts and crosses) together...
    By 2by4 in forum What's Wrong With My Code?
    Replies: 34
    Last Post: December 30th, 2011, 11:52 PM
  3. Serial Programming Logic Error???
    By bczm8703 in forum File I/O & Other I/O Streams
    Replies: 3
    Last Post: September 27th, 2011, 04:28 AM
  4. logic error somewhere.. working with try & catch, simple array.. please help
    By basketball8533 in forum What's Wrong With My Code?
    Replies: 2
    Last Post: December 9th, 2010, 12:40 PM
  5. [SOLVED] logic error: cpu assigning incorrect values in for loop
    By Perd1t1on in forum What's Wrong With My Code?
    Replies: 5
    Last Post: July 25th, 2010, 09:13 PM