TicTacToe using 2D array in java - java

Hello Everyone I need help.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
char[][] board = {
{'?','?','?'},
{'?','?','?'},
{'?','?','?'}
};
System.out.print("Type any key to play the game and type 'n' to stop the game: ");
String Stop = sc.nextLine();
while(true){
if(Stop.equals("n"))break;
System.out.print("Player" + "[" + "X" + "]: ");
int PlayerX = sc.nextInt();
if(PlayerX == 1){
board[2][0] = 'x';
}
if(PlayerX == 2){
board[2][1] = 'x';
}
if(PlayerX == 3){
board[2][2] = 'x';
}
if(PlayerX == 4){
board[1][0] = 'x';
}
if(PlayerX == 5){
board[1][1] = 'x';
}
if(PlayerX == 6){
board[1][2] = 'x';
}
if(PlayerX == 7){
board[0][0] = 'x';
}
if(PlayerX == 8){
board[0][1] = 'x';
}
if(PlayerX == 9){
board[0][2] = 'x';
}
for(char[] x1 : board){
for(char x2 : x1){
System.out.print(x2 + "\t");
}
System.out.println();
}
System.out.print("Player" + "[" + "O" + "]: ");
int PlayerO = sc.nextInt();
if(PlayerO == 1){
board[2][0] = 'o';
}
if(PlayerO == 2){
board[2][1] = 'o';
}
if(PlayerO == 3){
board[2][2] = 'o';
}
if(PlayerO == 4){
board[1][0] = 'o';
}
if(PlayerO == 5){
board[1][1] = 'o';
}
if(PlayerO == 6){
board[1][2] = 'o';
}
if(PlayerO == 7){
board[0][0] = 'o';
}
if(PlayerO == 8){
board[0][1] = 'o';
}
if(PlayerO == 9){
board[0][2] = 'o';
}
for(char[] x1 : board){
for(char x2 : x1){
System.out.print(x2 + "\t");
}
System.out.println();
}
}
}
}
I am trying to make a simple tictactoes program in java. I am already done in placing the X and O, but I am struggling on checking of wether there is a winner or not.
I am confused on what code I will type o check the winner of the program.

You simply just need to write some code to check if there are 3 matches in each row column and diagonal.
You can utilise for loops to do this more efficiently
public static char checkWinner(char[][] board) {
// Check rows
for (int i = 0; i < 3; i++) {
if (board[i][0] != '?' && board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
return board[i][0];
}
}
// Check columns
for (int j = 0; j < 3; j++) {
if (board[0][j] != '?' && board[0][j] == board[1][j] && board[1][j] == board[2][j]) {
return board[0][j];
}
}
// Check diagonal
if (board[0][0] != '?' && board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
return board[0][0];
}
// Check anti-diagonal
if (board[0][2] != '?' && board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
return board[0][2];
}
// No winner
return '?';
}
If you havent come accross for loops yet, there are plenty of good tutorials out there such as https://www.w3schools.com/java/java_for_loop.asp
(Note, you can also use loops to clean up some of your pre-existing code)

Related

Sorting through 2D array for Tic Tac Toe winner

I have made this very obnoxious way of finding the winner in a tic tac toe game and I was just wondering if there is a simpler way of doing this.
This is the method I currently have, and as you can see it is very redundant and repetitive. Any tips to narrow this down would be amazing. I'm thinking maybe a nested for-loop might work but not entirely sure how to set that up within this.
public static boolean isGameOver(char[][] gameBoard) {
//Testing for Horizontal Win
if(gameBoard[0][0] == 'X' && gameBoard[0][2] == 'X' && gameBoard [0][4] == 'X') {
System.out.println("Player Wins!\n");
playerScore++;
return true;
}
if(gameBoard[0][0] == 'O' && gameBoard[0][2] == 'O' && gameBoard [0][4] == 'O') {
System.out.println("CPU Wins!\n");
cpuScore++;
return true;
}
if(gameBoard[2][0] == 'X' && gameBoard[2][2] == 'X' && gameBoard [2][4] == 'X') {
System.out.println("Player Wins!\n");
playerScore++;
return true;
}
if(gameBoard[2][0] == 'O' && gameBoard[2][2] == 'O' && gameBoard [2][4] == 'O') {
System.out.println("CPU Wins!\n");
cpuScore++;
return true;
}
if(gameBoard[4][0] == 'X' && gameBoard[4][2] == 'X' && gameBoard [4][4] == 'X') {
System.out.println("Player Wins!\n");
playerScore++;
return true;
}
if(gameBoard[4][0] == 'O' && gameBoard[4][2] == 'O' && gameBoard [4][4] == 'O') {
System.out.println("CPU Wins!\n");
cpuScore++;
return true;
}
//Testing for Vertical Win
if(gameBoard[0][0] == 'X' && gameBoard[2][0] == 'X' && gameBoard [4][0] == 'X') {
System.out.println("Player Wins!\n");
playerScore++;
return true;
}
if(gameBoard[0][0] == 'O' && gameBoard[2][0] == 'O' && gameBoard [4][0] == 'O') {
System.out.println("CPU Wins!\n");
cpuScore++;
return true;
}
if(gameBoard[0][2] == 'X' && gameBoard[2][2] == 'X' && gameBoard [4][2] == 'X') {
System.out.println("Player Wins!\n");
playerScore++;
return true;
}
if(gameBoard[0][2] == 'O' && gameBoard[2][2] == 'O' && gameBoard [4][2] == 'O') {
System.out.println("CPU Wins!\n");
cpuScore++;
return true;
}
if(gameBoard[0][4] == 'X' && gameBoard[2][4] == 'X' && gameBoard [4][4] == 'X') {
System.out.println("Player Wins!\n");
playerScore++;
return true;
}
if(gameBoard[0][4] == 'O' && gameBoard[2][4] == 'O' && gameBoard [4][4] == 'O') {
System.out.println("CPU Wins!\n");
cpuScore++;
return true;
}
//Testing for Diagonal Win
if(gameBoard[0][0] == 'X' && gameBoard[2][2] == 'X' && gameBoard [4][4] == 'X') {
System.out.println("Player Wins!\n");
playerScore++;
return true;
}
if(gameBoard[0][0] == 'O' && gameBoard[2][2] == 'O' && gameBoard [4][4] == 'O') {
System.out.println("CPU Wins!\n");
cpuScore++;
return true;
}
if(gameBoard[4][0] == 'X' && gameBoard[2][2] == 'X' && gameBoard [0][4] == 'X') {
System.out.println("Player Wins!\n");
playerScore++;
return true;
}
if(gameBoard[4][0] == 'O' && gameBoard[2][2] == 'O' && gameBoard [0][4] == 'O') {
System.out.println("CPU Wins!\n");
cpuScore++;
return true;
}
//Testing for Tie
if(gameBoard[0][0] != ' ' && gameBoard[0][2] != ' ' && gameBoard[0][4] != ' ' &&
gameBoard[2][0] != ' ' && gameBoard[2][2] != ' ' && gameBoard[2][4] != ' ' &&
gameBoard[4][0] != ' ' && gameBoard[4][2] != ' ' && gameBoard[4][4] != ' ') {
System.out.println("It's a tie!!!\n");
numOfTies++;
return true;
}
return false;
}
Ok, I got a little carried away. But perhaps you could use some ideas presented here. My main goal was to make it so the entire board need not be checked after each move. This is the type of issue that is best considered during the design phase of a program.
I created a TriGroup class (which is essentially a mutable string to hold successive moves.
Then a map is used to hold all the groupings which have a common coordinate.
when a move is made, those groupings have the current player appended.
and check is done to see if that player won.
this program will run by itself using random moves resulting in a victory or a tie.
Some border cases may have been overlooked.
public class TicTacToeCheck {
int moveCount = 0;
static int MAX_MOVES = 27;
class TriGroup {
public String group = "";
#Override
public String toString() {
return group;
}
}
TriGroup row1 = new TriGroup();
TriGroup row2 = new TriGroup();
TriGroup row3 = new TriGroup();
TriGroup col1 = new TriGroup();
TriGroup col2 = new TriGroup();
TriGroup col3 = new TriGroup();
TriGroup diag1 = new TriGroup();
TriGroup diag2 = new TriGroup();
Map<String, List<TriGroup>> commonGroupings = new HashMap<>();
{
commonGroupings.put("00", List.of(row1, col1, diag1));
commonGroupings.put("02", List.of(row1, col2));
commonGroupings.put("04", List.of(row1, col3));
commonGroupings.put("20", List.of(row2, col1));
commonGroupings.put("22", List.of(row2, col2, diag1, diag2));
commonGroupings.put("24", List.of(row2, col3));
commonGroupings.put("40", List.of(row3, col1, diag1));
commonGroupings.put("42", List.of(row3, col2));
commonGroupings.put("44", List.of(row3, col3));
}
public static void main(String[] args) {
new TicTacToeCheck().start();
}
public void start() {
char player = 'X';
Random r = new Random();
outer: while (moveCount < MAX_MOVES) {
commonGroupings.entrySet().forEach(System.out::println);
System.out.println();
int row = r.nextInt(3) * 2;
int col = r.nextInt(3) * 2;
System.out.println("Move: " + row + ", " + col);
player = player == 'X' ? 'O' : 'X';
char val;
switch (val = recordMove(row, col, player)) {
case 'X' -> {
System.out.println("X wins!");
break outer;
}
case 'O' -> {
System.out.println("O wins!");
break outer;
}
case 0 -> {
System.out.println("Tie!");
break outer;
}
default -> {
}
}
}
commonGroupings.entrySet().forEach(System.out::println);
}
public char recordMove(int row, int col, char c) {
moveCount++;
for (TriGroup tri : commonGroupings.get(row + "" + col)) {
if (tri.group.length() > 2) {
// just ignore the row/col and try the next
continue;
}
// update group
tri.group += c;
if (tri.group.equals(c + "" + c + "" + c)) {
return c;
}
}
if (moveCount == MAX_MOVES) {
return 0;
}
return '#';
}
}
This version uses 2 auxiliary, private methods to make the code less repetitive, without changing the behavior of calling isGameOver. The main observation is that there is very little difference between checking for a win by O or checking for one by X - only a single character. So that becomes checkWins. The next observation is that there is a lot of repetition involved in checking 3 positions of the board that are next to each other. If you give me the char to expect, where to start, and where to look next (dcol and drow), that becomes allEqual.
Your code skips over uneven positions of the board; my code does not. I feel that it is an error to mix presentation ("how you show things to users") with model ("how you represent things internally"); so my code is not currently a drop-in replacement for yours, but can quickly be fixed to be such a replacement by tweaking values in checkWins (diagonal down would be 0, 0, 2, 2, and so on).
Note that, efficiency-wise, your code is probably faster. But I find this version to be much shorter, more readable, and therefore easier to debug & maintain.
private static boolean allEqual(char expected, char[][] b,
int row, int col, int drow, int dcol) {
for (int i=0; i<b[0].length; i++) {
if (b[row][col] != expected) return false;
row += drow;
col += dcol;
}
return true;
}
private static boolean checkWins(char playerChar, char[][]b) {
boolean win = allEqual(playerChar, b, 0, 0, 0, 1) // 1st row
|| allEqual(playerChar, b, 1, 0, 0, 1)
|| allEqual(playerChar, b, 2, 0, 0, 1) // 3rd row
|| allEqual(playerChar, b, 0, 0, 1, 0) // 1st col
|| allEqual(playerChar, b, 0, 1, 1, 0)
|| allEqual(playerChar, b, 0, 2, 1, 0) // 3rd col
|| allEqual(playerChar, b, 0, 0, 1, 1) // diagonal down
|| allEqual(playerChar, b, 2, 0, 1,-1); // diagonal up
return win;
}
public static boolean isGameOver(char[][] gameBoard) {
if (checkWins('X', gameBoard)) {
System.out.println("Player Wins!\n");
playerScore ++;
return true;
} else if (checkWins('O', gameBoard)) {
System.out.println("CPU Wins!\n");
cpuScore ++;
return true;
} else {
return false;
}
}
Take a look at this:
https://www.geeksforgeeks.org/tic-tac-toe-game-in-java/
Add the strings of gameBoard[x][y] and check them in a switch statement.
If the compound strings are equals to XXX or OOO, you can return the winner.
For your code something like this:
for (int a = 0; a < 8; a++) {
String line = null;
switch (a) {
case 0:
line = gameBoard[0][0] + gameBoard[0][1] + gameBoard[0][2];
break;
case 1:
line = gameBoard[1][0] + gameBoard[1][1] + gameBoard[1][2];
break;
case 2:
line = gameBoard[2][0] + gameBoard[2][1] + gameBoard[2][2];
break;
case 3:
line = gameBoard[0][0] + gameBoard[1][0] + gameBoard[2][0];
break;
case 4:
line = gameBoard[0][1] + gameBoard[1][1] + gameBoard[2][1];
break;
case 5:
line = gameBoard[0][2] + gameBoard[1][2] + gameBoard[2][2];
break;
case 6:
line = gameBoard[0][0] + gameBoard[1][1] + gameBoard[2][2];
break;
case 7:
line = gameBoard[0][2] + gameBoard[1][1] + gameBoard[2][0];
break;
}
//For X winner
if (line.equals("XXX")) {
return "X";
}
// For O winner
else if (line.equals("OOO")) {
return "O";
}
}

How can I shrink down all of these if statements?

This part of the code is from a school assignment. I got it to work, but I feel like I can simplify it or at least make it look cleaner. However, I have not yet been able to do so. Any suggestions? (It is from a tic tac toe game)
if (board[0][0] == board[0][1] && board[0][1] == board[0][2] && board[0][0] != '-') {
winner = board[0][0];
} else if (board[1][0] == board[1][1] && board[1][1] == board[1][2] && board[1][0] != '-') {
winner = board[1][0];
} else if (board[2][0] == board[2][1] && board[2][1] == board[2][2] && board[2][0] != '-') {
winner = board[2][0];
} else if (board[0][0] == board[1][0] && board[1][0] == board[2][0] && board[0][0] != '-') {
winner = board[0][0];
} else if (board[0][1] == board[1][1] && board[1][1] == board[2][1] && board[0][1] != '-') {
winner = board[0][1];
} else if (board[0][2] == board[1][2] && board[1][2] == board[2][2] && board[0][2] != '-') {
winner = board[0][2];
} else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[2][0] != '-') {
winner = board[2][0];
} else if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != '-') {
winner = board[0][0];
}
try
if(check(board[0][0],board[0][1],board[0][2]) && board[0][2]!='-')
.....
private boolean check(a,b,c){
return a==b && b==c;
}
also you can see a better solution here
Here is another way of doing it:
int[][] checks = {{0,0,0,1},{1,0,0,1},{2,0,0,1}, // horizontals
{0,0,1,0},{0,1,1,0},{0,2,1,0}, // verticals
{0,0,1,1},{2,0,-1,1}}; // diagonals
char winner = '-';
for (int[] check : checks)
if ((winner = checkWinner(board, check[0], check[1], check[2], check[3])) != '-')
break;
private static char checkWinner(char[][] board, int y, int x, int dy, int dx) {
char c = board[y][x];
return (board[y + dy][x + dx] == c && board[y + dy * 2][x + dx * 2] == c ? c : '-');
}
What about following approach. As I can see, you have limited number of winners: board[0][0], board[1][0], board[2][0], board[0][1], board[2][0]. You can create separate Predicate for each winnger with appropriate name.
Predicate<char[][]> isZeroOneWinner = new Predicate<char[][]>() {
#Override
public boolean test(char[][] board) {
return board[0][1] == board[1][1] && board[1][1] == board[2][1] && board[0][1] != '-';
}
};
I think is is better that multiple if...else.

Tic-tac-toe java: what to do if the user inputs a position that's already taken?

Here is the code I have written so far. My game works just fine but the problem I have is if the user inputs a position that's already taken, yes it keeps asking the user for input, but what i would want it to do it say: This position is unavailable and then reask the user until it's good. I thought about a for loop, but with the loop I have, it says it's unavailable even if it is not...I have been on this for days. If someone could give me some hints I would appreciate it.
import java.util.Scanner;
public class A3Q1_40011419 {
//Creating the board for the user input
static char [][] board = {{'1','2','3'}, {'4','5','6'},{'7','8','9'}};
static Scanner keyboard = new Scanner (System.in);
//Keeping track of the turns
public static int turns = 0;
//Drawing the board
public static void drawBoard() {
int row = 0;
int col = 0;
int turn = 0;
for (row = 0; row < board.length; row++){
for (col = 0; col < board[row].length; col++){
System.out.print(board[row][col]);
System.out.print(" ");
}
System.out.println();
}
}
//Asking user for input
public static void getInput (int playerNum) {
char piece;
char location = ' ';
if (playerNum != 1){
System.out.println("Player X - Enter the position you wish to mark.");
location = keyboard.next().charAt(0);
piece = 'X';
}
else{
System.out.println("Player O - Enter the position you wish to mark.");
location = keyboard.next().charAt(0);
piece = 'O';
}
if (location == '1')
if (board[0][0]=='1')
board[0][0] = piece;
else getInput(playerNum);
else if (location == '2')
if (board[0][1] == '2')
board[0][1] = piece;
else getInput(playerNum);
else if (location == '3')
if (board[0][2] == '3')
board[0][2] = piece;
else getInput(playerNum);
else if (location == '4')
if (board[1][0] == '4')
board[1][0] = piece;
else getInput(playerNum);
else if (location == '5')
if (board[1][1] == '5')
board[1][1] = piece;
else getInput(playerNum);
else if (location == '6')
if (board[1][2] == '6')
board[1][2] = piece;
else getInput(playerNum);
else if (location == '7')
if (board[2][0] == '7')
board[2][0] = piece;
else getInput(playerNum);
else if (location == '8')
if (board[2][1] == '8')
board[2][1] = piece;
else getInput(playerNum);
else if (location == '9')
if (board[2][2] == '9')
board[2][2] = piece;
else getInput(playerNum);
else if (location != '1' || location !='2' || location !='3' || location != '4' || location !='5' || location !='6' || location != '7' || location != '8'|| location !='9'){
System.out.println("That is not a valid position - must be between 1 and 9 inclusive.");
getInput(playerNum);
}
for (int i = 0; i<board.length; i++){
for (int j = 0; j<board.length; j++)
/*if (location == '1' || location == '2' || location == '3'|| location == '4' || location == '5'|| location == '6' || location == '7' || location == '8' || location == '9')*/
if (board[i][j] == 'X' || board[i][j] == 'O'){
System.out.println("Position not available"); //This is was i tried to do so far to check is the position was available on the board. Not working
}
getInput(playerNum);
}
}
//Checking if position available
public static void isAvailable(){ //This is a method i thought of creating to check if the position was available but I have not used it yet.
char location_1 = ' ';
char location_2 = ' ';
char location_3 = ' ';
char location_4 = ' ';
char location_5 = ' ';
char location_6 = ' ';
char location_7 = ' ';
char location_8 = ' ';
char location_9 = ' ';
}
/*Checking if there is a winner by checking if the cells in the board are equal to each other
*and checking if the cell isn't empty. If one isn't empty and they're all equal, then
none of them is empty.*/
public static char isWinner() {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0]!='1')
return board[0][0];
else if (board[0][0] == board[1][0] && board[0][0] == board[2][0] && board[0][0]!='1')
return board[0][0];
else if (board[0][0]==board[0][1] && board[0][0]==board[0][2] && board[0][0]!='1')
return board[0][0];
else if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] !='3')
return board[0][2];
else if (board[0][2] == board[1][2] && board[0][2] == board[2][2] && board[0][2] != '3')
return board[0][2];
else if (board[2][0] == board [2][1] && board[2][0] == board[2][2] && board[2][0] != '7')
return board[2][0];
else if (board[1][0] == board [1][1] && board[1][0] == board[1][2] && board[1][0] != '4')
return board[1][0];
else if (board[0][1] == board[1][1] && board[0][1] == board[2][1] && board[0][1] != '2')
return board[0][1];
else
return 'Y';
}
//New board for a new game
public static void newBoard() {
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';
}
//Main method
public static void main(String[] args) {
int game = 0;
int playerNum = 1;
String answer;
do {
turns = 0;
newBoard();
while (isWinner() == 'Y') {
drawBoard();
isWinner();
playerNum *= -1;
getInput(playerNum);
turns++;
System.out.println(turns);
if (turns == 9) {
break;
}
}
drawBoard();
if (isWinner() == 'X')
System.out.println("Player X wins");
else if (isWinner()=='O')
System.out.println("Player O wins");
else
System.out.println("It's a tie!");
System.out.println("Would you like to play another game?");
answer = keyboard.next().toLowerCase();
}
while (answer.equals("yes"));
}
}
I would suggest:
You move your check for available position before inserting the new input.
Instead of a loop to check all positions of the grid, you check only the position the player is asking.
Please find a working code below:
public class A3Q1_40011419 {
//Creating the board for the user input
static char [][] board = {{'1','2','3'}, {'4','5','6'},{'7','8','9'}};
static Scanner keyboard = new Scanner (System.in);
//Keeping track of the turns
public static int turns = 0;
//Drawing the board
public static void drawBoard() {
int row = 0;
int col = 0;
int turn = 0;
for (row = 0; row < board.length; row++){
for (col = 0; col < board[row].length; col++){
System.out.print(board[row][col]);
System.out.print(" ");
}
System.out.println();
}
}
//Asking user for input
public static void getInput (int playerNum) {
char piece;
char location = ' ';
if (playerNum != 1){
System.out.println("Player X - Enter the position you wish to mark.");
location = keyboard.next().charAt(0);
piece = 'X';
}
else{
System.out.println("Player O - Enter the position you wish to mark.");
location = keyboard.next().charAt(0);
piece = 'O';
}
//------------------------
// Your new check
int locationInt = Integer.parseInt("" + location);
int x = (locationInt-1)/3;
int y = ((locationInt-1)%3);
if (board[x][y] == 'X' || board[x][y] == 'O'){
System.out.println("Position not available"); //This is was i tried to do so far to check is the position was available on the board. Not working
getInput(playerNum);
return;
}
//------------------------
if (location == '1')
if (board[0][0]=='1')
board[0][0] = piece;
else getInput(playerNum);
else if (location == '2')
if (board[0][1] == '2')
board[0][1] = piece;
else getInput(playerNum);
else if (location == '3')
if (board[0][2] == '3')
board[0][2] = piece;
else getInput(playerNum);
else if (location == '4')
if (board[1][0] == '4')
board[1][0] = piece;
else getInput(playerNum);
else if (location == '5')
if (board[1][1] == '5')
board[1][1] = piece;
else getInput(playerNum);
else if (location == '6')
if (board[1][2] == '6')
board[1][2] = piece;
else getInput(playerNum);
else if (location == '7')
if (board[2][0] == '7')
board[2][0] = piece;
else getInput(playerNum);
else if (location == '8')
if (board[2][1] == '8')
board[2][1] = piece;
else getInput(playerNum);
else if (location == '9')
if (board[2][2] == '9')
board[2][2] = piece;
else getInput(playerNum);
else if (location != '1' || location !='2' || location !='3' || location != '4' || location !='5' || location !='6' || location != '7' || location != '8'|| location !='9'){
System.out.println("That is not a valid position - must be between 1 and 9 inclusive.");
getInput(playerNum);
}
}
//Checking if position available
public static void isAvailable(){ //This is a method i thought of creating to check if the position was available but I have not used it yet.
char location_1 = ' ';
char location_2 = ' ';
char location_3 = ' ';
char location_4 = ' ';
char location_5 = ' ';
char location_6 = ' ';
char location_7 = ' ';
char location_8 = ' ';
char location_9 = ' ';
}
/*Checking if there is a winner by checking if the cells in the board are equal to each other
*and checking if the cell isn't empty. If one isn't empty and they're all equal, then
none of them is empty.*/
public static char isWinner() {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0]!='1')
return board[0][0];
else if (board[0][0] == board[1][0] && board[0][0] == board[2][0] && board[0][0]!='1')
return board[0][0];
else if (board[0][0]==board[0][1] && board[0][0]==board[0][2] && board[0][0]!='1')
return board[0][0];
else if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] !='3')
return board[0][2];
else if (board[0][2] == board[1][2] && board[0][2] == board[2][2] && board[0][2] != '3')
return board[0][2];
else if (board[2][0] == board [2][1] && board[2][0] == board[2][2] && board[2][0] != '7')
return board[2][0];
else if (board[1][0] == board [1][1] && board[1][0] == board[1][2] && board[1][0] != '4')
return board[1][0];
else if (board[0][1] == board[1][1] && board[0][1] == board[2][1] && board[0][1] != '2')
return board[0][1];
else
return 'Y';
}
//New board for a new game
public static void newBoard() {
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';
}
//Main method
public static void main(String[] args) {
int game = 0;
int playerNum = 1;
String answer;
do {
turns = 0;
newBoard();
while (isWinner() == 'Y') {
drawBoard();
isWinner();
playerNum *= -1;
getInput(playerNum);
turns++;
System.out.println(turns);
if (turns == 9) {
break;
}
}
drawBoard();
if (isWinner() == 'X')
System.out.println("Player X wins");
else if (isWinner()=='O')
System.out.println("Player O wins");
else
System.out.println("It's a tie!");
System.out.println("Would you like to play another game?");
answer = keyboard.next().toLowerCase();
}
while (answer.equals("yes"));
}
}

Tic Tac Toe in Java printing error

I've almost got this homework assignment finished, but I'm having some printing errors with the output.
The game is functional, but there's a problem with methods printOBoard and printXBoard where it messes up the game board when a move is made. The problem becomes worse the longer the game goes on. Thanks for your help.
import java.util.Scanner;
public class TicTacToe {
private enum Tiles {
X, O, EMPTY;
}
public static void main(String[] args) {
int i;
int j;
//initialize 2d array of enum types called "board"
Tiles[][] board = new Tiles[3][3];
for (i=0; i<board.length; i++)
for (j=0; j<board.length; j++)
board[i][j] = Tiles.EMPTY;
//print out an empty board as a 2d array, with each tile set as "EMPTY"
printBoard(board);
int row, col;
int countEmpty=0;
//initial countEmpty count, if it's less than 1, the board is full and the game is over.
for (i=0; i<board.length; i++)
for (j=0; j<board.length; j++)
if (board[i][j] == Tiles.EMPTY)
countEmpty++;
while (countEmpty > 0) {
//Player O enters the row coordinate
System.out.println("Player O's turn.");
System.out.println("Player O: Enter row (0, 1, or 2):");
Scanner stdin1 = new Scanner(System.in);
row = stdin1.nextInt();
//Player O enters the column coordinate
System.out.println("Player O: Enter column (0, 1, or 2):");
Scanner stdin2 = new Scanner(System.in);
col = stdin2.nextInt();
//If the tile is empty, it was a valid move, and an 'O' is placed on the spot.
if (board[row][col] == Tiles.EMPTY) {
board[row][col] = Tiles.O;
//MOVE FOR O ********************
printOBoard(board, row, col);
checkWin(board);
if (checkWin(board) == 2)
;
else
break;
}
//If the tile is not empty, it was not a valid move, and Player O is prompted to try again.
else {
System.out.println("Space already occupied. Please choose another.");
System.out.println("Player O's turn.");
//Player 0 enters the row coordinate
System.out.println("Player O: Enter row (0, 1, or 2):");
stdin1 = new Scanner(System.in);
row = stdin1.nextInt();
//Player O enters the column coordinate
System.out.println("Player O: Enter column (0, 1, or 2):");
stdin2 = new Scanner(System.in);
col = stdin2.nextInt();
//ERROR MOVE FOR O********************
board[row][col] = Tiles.O;
printOBoard(board, row, col);
checkWin(board);
if (checkWin(board) == 2)
;
else
break;
}
//Player X enters the row coordinate
System.out.println("Player X's turn.");
System.out.println("Player X: Enter row (0, 1, or 2):");
Scanner stdin3 = new Scanner(System.in);
row = stdin3.nextInt();
//Player X enters the column coordinate
System.out.println("Player X: Enter column (0, 1, or 2):");
Scanner stdin4 = new Scanner(System.in);
col = stdin4.nextInt();
if (board[row][col] == Tiles.EMPTY) {
board[row][col] = Tiles.X;
printXBoard(board, row, col);
//MOVE FOR X *************************************************
checkWin(board);
if (checkWin(board) == 2)
;
else
break;
}
else {
System.out.println("Space already occupied. Please choose another.");
System.out.println("Player O's turn.");
System.out.println("Player O: Enter row (0, 1, or 2):");
stdin3 = new Scanner(System.in);
row = stdin3.nextInt();
//Player O enters the column coordinate
System.out.println("Player O: Enter column (0, 1, or 2):");
stdin4 = new Scanner(System.in);
col = stdin4.nextInt();
board[row][col] = Tiles.O;
//ERROR MOVE FOR X ****************************************
printXBoard(board, row, col);
checkWin(board);
if (checkWin(board) == 2)
;
else
break;
}
//After both players move, we check to see if the board is full.
countEmpty = 0;
for (i=0; i<board.length; i++)
for (j=0; j<board.length; j++)
if (board[i][j] == Tiles.EMPTY)
countEmpty++;
}
}
//method printBoard prints out a grid of EMPTY's and returns nothing
private static void printBoard(Tiles board[][]) {
int i, j;
System.out.println(" -----------------------------");
System.out.println("| | | |");
for (i=0; i<board.length; i++){
for (j=0; j<board.length; j++){
System.out.printf("| " + board[i][j] + " ");
}
System.out.println("|");
System.out.println("| | | |");
System.out.println(" -----------------------------");
if (i<2)
System.out.println("| | | |");
}
return;
}
//method printXBoard prints out the grid modified with the addition of an X after Player X's turn
private static void printXBoard(Tiles board[][], int curRow, int curCol) {
int i, j;
System.out.println(" -----------------------------");
System.out.println("| | | |");
for (i=0; i<board.length; i++){
for (j=0; j<board.length; j++){
if (i == curRow && j == curCol)
board[i][j] = Tiles.X;
else
;
System.out.printf("| " + board[i][j] + " ");
}
System.out.println("|");
System.out.println("| | | |");
System.out.println(" -----------------------------");
if (i<2)
System.out.println("| | | |");
}
return;
}
//method printOBoard prints out the grid modified with the addition of an X after Player X's turn
private static void printOBoard(Tiles board[][], int curRow, int curCol) {
int i, j;
System.out.println(" -----------------------------");
System.out.println("| | | |");
for (i=0; i<board.length; i++){
for (j=0; j<board.length; j++){
if (i == curRow && j == curCol)
board[i][j] = Tiles.O;
else
;
System.out.printf("| " + board[i][j] + " ");
}
System.out.println("|");
System.out.println("| | | |");
System.out.println(" -----------------------------");
if (i<2)
System.out.println("| | | |");
}
return;
}
//method checkWin checks all possible winning combinations for both players.
private static int checkWin(Tiles board[][]) {
if (board[0][0] == Tiles.X && board[0][1] == Tiles.X && board[0][2] == Tiles.X){
System.out.println("Player X wins!");
return 1;
}
else if (board[0][0] == Tiles.X && board[1][1] == Tiles.X && board[2][2] == Tiles.X){
System.out.println("Player X wins!");
return 1;
}
else if (board[0][0] == Tiles.X && board[1][0] == Tiles.X && board[2][0] == Tiles.X){
System.out.println("Player X wins!");
return 1;
}
else if (board[1][0] == Tiles.X && board[1][1] == Tiles.X && board[1][2] == Tiles.X){
System.out.println("Player X wins!");
return 1;
}
else if (board[2][0] == Tiles.X && board[2][1] == Tiles.X && board[2][2] == Tiles.X){
System.out.println("Player X wins!");
return 1;
}
else if (board[0][1] == Tiles.X && board[1][1] == Tiles.X && board[2][1] == Tiles.X){
System.out.println("Player X wins!");
return 1;
}
else if (board[0][2] == Tiles.X && board[1][2] == Tiles.X && board[2][2] == Tiles.X){
System.out.println("Player X wins!");
return 1;
}
else if (board[2][0] == Tiles.X && board[1][1] == Tiles.X && board[0][2] == Tiles.X){
System.out.println("Player X wins!");
return 1;
}
//check if player O wins
else if (board[0][0] == Tiles.O && board[0][1] == Tiles.O && board[0][2] == Tiles.O){
System.out.println("Player O wins!");
return 0;
}
else if (board[0][0] == Tiles.O && board[1][1] == Tiles.O && board[2][2] == Tiles.O){
System.out.println("Player O wins!");
return 0;
}
else if (board[0][0] == Tiles.O && board[1][0] == Tiles.O && board[2][0] == Tiles.O){
System.out.println("Player O wins!");
return 0;
}
else if (board[1][0] == Tiles.O && board[1][1] == Tiles.O && board[1][2] == Tiles.O){
System.out.println("Player O wins!");
return 0;
}
else if (board[2][0] == Tiles.O && board[2][1] == Tiles.O && board[2][2] == Tiles.O) {
System.out.println("Player O wins!");
return 0;
}
else if (board[0][1] == Tiles.O && board[1][1] == Tiles.O && board[2][1] == Tiles.O) {
System.out.println("Player O wins!");
return 0;
}
else if (board[0][2] == Tiles.O && board[1][2] == Tiles.O && board[2][2] == Tiles.O){
System.out.println("Player O wins!");
return 0;
}
else if (board[2][0] == Tiles.O && board[1][1] == Tiles.O && board[0][2] == Tiles.O) {
System.out.println("Player O wins!");
return 0;
}
else
return 2;
}
}
There is a problem in 2nd attempt to place X (if space is occupied by O), you copy pasted code from O and haven't changed player & tile.
System.out.println("Player O's turn.");
board[row][col] = Tiles.O;
It was pain to read this code -_- but you'll get better eventually ;) .
The reason as to why this is happening when printing out the Letters onto your board(which I've run on my mac) is that when you're printing the letters, you're using println...since you're accompanying a certain amount of space per block you should be using printf...for example:
System.out.printf("%10s", LetterVariableForTurn);
This will give the LetterVariableForTurn 10 spaces of text to write within.
here is a link to help you more: printf
Hope this helps!

Scanner only accepting input once

Recently, I've been working on my Noughts and Crosses game, but I've stumbled upon a problem that I can't seem to be able to fix.
Whenever I type in something the first time, it works and prints out the board, however, from that point onward, it just stops checking and printing out the board.
while(inf){
String temp = input.next();
if(playerTurn == 1){
if(amountP1 <= 3){
if(temp.equalsIgnoreCase("00")){
if(board[0][0] == 0){
board[0][0] = 1;
showBoard(board);
playerTurn = 2;
amountP1++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("01")){
if(board[0][1] == 0){
board[0][1] = 1;
showBoard(board);
playerTurn = 2;
amountP1++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("02")){
if(board[0][2] == 0){
board[0][2] = 1;
showBoard(board);
playerTurn = 2;
amountP1++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("10")){
if(board[1][0] == 0){
board[1][0] = 1;
showBoard(board);
playerTurn = 2;
amountP1++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("11")){
if(board[1][1] == 0){
board[1][1] = 1;
showBoard(board);
playerTurn = 2;
amountP1++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("12")){
if(board[1][2] == 0){
board[1][2] = 1;
showBoard(board);
playerTurn = 2;
amountP1++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("20")){
if(board[2][0] == 0){
board[2][0] = 1;
showBoard(board);
playerTurn = 2;
amountP1++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("21")){
if(board[2][1] == 0){
board[2][1] = 1;
showBoard(board);
playerTurn = 2;
amountP1++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("22")){
if(board[2][2] == 0){
board[2][2] = 1;
showBoard(board);
playerTurn = 2;
amountP1++;
}
else{
System.out.println("This space is already occupied!");
}
}
}
else if(playerTurn == 2){
if(amountP2 <= 3){
if(temp.equalsIgnoreCase("00")){
if(board[0][0] == 0){
board[0][0] = 2;
showBoard(board);
playerTurn = 1;
amountP2++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("01")){
if(board[0][1] == 0){
board[0][1] = 2;
showBoard(board);
playerTurn = 1;
amountP2++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("02")){
if(board[0][2] == 0){
board[0][2] = 2;
showBoard(board);
playerTurn = 1;
amountP2++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("10")){
if(board[1][0] == 0){
board[1][0] = 2;
showBoard(board);
playerTurn = 1;
amountP2++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("11")){
if(board[1][1] == 0){
board[1][1] = 2;
showBoard(board);
playerTurn = 1;
amountP2++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("12")){
if(board[1][2] == 0){
board[1][2] = 2;
showBoard(board);
playerTurn = 1;
amountP2++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("20")){
if(board[2][0] == 0){
board[2][0] = 2;
showBoard(board);
playerTurn = 1;
amountP2++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("21")){
if(board[2][1] == 0){
board[2][1] = 2;
showBoard(board);
playerTurn = 1;
amountP2++;
}
else{
System.out.println("This space is already occupied!");
}
}
else if(temp.equalsIgnoreCase("22")){
if(board[2][2] == 0){
board[2][2] = 2;
showBoard(board);
playerTurn = 1;
amountP2++;
}
else{
System.out.println("This space is already occupied!");
}
}
}
}
}
}
And this is the method for printing out the board:
public static void showBoard(int x[][]){
int rowNumber = 1;
for(int row = 0 ; row < x.length ; row++){
for(int column = 0 ; column < x[row].length ; column++){
if(x[row][column] == 0){
if(rowNumber <= 2){
System.out.print(" E");
rowNumber++;
}
else if(rowNumber == 3){
System.out.println(" E");
rowNumber = 1;
}
}
else if(x[row][column] == 1){
if(rowNumber <= 2){
System.out.print(" X");
rowNumber++;
}
else if(rowNumber == 3){
System.out.println(" X");
rowNumber = 1;
}
}
else if(x[row][column] == 2){
if(rowNumber <= 2){
System.out.print(" O");
rowNumber++;
}
else if(rowNumber == 3){
System.out.println(" O");
rowNumber = 1;
}
}
}
}
}
Also, I am aware that this code is a big mess and there's problably a ton of other, more efficient ways to do this, but since I am a fairly new programmer, I chose to go with functionality over efficiency with this one.
Your else if(playerTurn == 2) line needs to be pulled out to the same level as if(playerTurn == 1):
if(playerTurn == 1){
if(amountP1 <= 3){
//...
}
else if(playerTurn == 2){
//...
}
}
should become
if(playerTurn == 1){
if(amountP1 <= 3){
//...
}
} else if(playerTurn == 2) {
//...
}

Categories