# java – Check Tic Tac Toe Winner

## Question:

The algorithm professor asked us to write code to make a simple tic-tac-toe game in Java. And I already have everything ready, but I'm not very happy with the solution I came up with to validate who won the game.

I did a series of if and elseifs to check each condition a player can win the game. And okay, that covers what the professor asked, except I don't think that's the smartest way to write an algorithm. I was thinking about using nested repeats (for inside for) but I can't find a way where I can apply that in the algorithm, or maybe because of so much thinking I can't think straight anymore.

I also thought about creating an array with all possible possibilities:

``````   final int[][][] condicoesVencer = {
//COLUNAS
{{ 0, 0 }, { 1, 0 }, { 2, 0 }},
{{ 0, 1 }, { 1, 1 }, { 2, 1 }},
{{ 0, 2 }, { 1, 2 }, { 2, 2 }},

//LINHAS
{{ 0, 0 }, { 0, 1 }, { 0, 2 }},
{{ 1, 0 }, { 1, 1 }, { 1, 2 }},
{{ 2, 0 }, { 2, 1 }, { 2, 2 }},

//DIAGONAIS
{{ 0, 0 }, { 1, 1 }, { 2, 2 }},
{{ 2, 0 }, { 1, 1 }, { 0, 2 }}
};
``````

`condicoesVencer` keeps all possible winning combinations, the positions of the vector `char tabuleiro[][] = new char[3][3]` where the X or O can win. But I couldn't get a way to iterate through the two vectors in order to check on the board vector every condition in the `condicoesVencer` vector and now I don't know what to do.

How do I replace the bunch of ifs I made into something more 'smart'? Please, if you have an answer, send the code and explain.

EDIT: Here's the method I created, with all the ifs:

``````public boolean haGanhador(){
//Checa X verticalmente
if(tabuleiro[0][0] == 'X' && tabuleiro[1][0] == 'X' && tabuleiro [2][0] == 'X'){
System.out.println("'X' VENCEU");
return true;
}
else if(tabuleiro[0][1] == 'X' && tabuleiro[1][1] == 'X' && tabuleiro[2][1] == 'X'){
System.out.println("'X' VENCEU");
return true;
}
else if(tabuleiro[0][2] == 'X' && tabuleiro[1][2] == 'X' && tabuleiro[2][2] == 'X'){
System.out.println("'X' VENCEU");
return true;
}

//Checa X horizontalmente
else if(tabuleiro[0][0] == 'X' && tabuleiro[0][1] == 'X' && tabuleiro[0][2] == 'X'){
System.out.println("'X' VENCEU");
return true;
}
else if(tabuleiro[1][0] == 'X' && tabuleiro[1][1] == 'X' && tabuleiro[1][2] == 'X'){
System.out.println("'X' VENCEU");
return true;
}
else if(tabuleiro[2][0] == 'X' && tabuleiro[2][1] == 'X' && tabuleiro[2][2] == 'X'){
System.out.println("'X' VENCEU");
return true;
}
//Checa X diagonalmente
else if(tabuleiro[0][0] == 'X' && tabuleiro[1][1] == 'X' && tabuleiro[2][2] == 'X'){
System.out.println("'X' VENCEU");
return true;
}
else if(tabuleiro[0][2] == 'X' && tabuleiro[1][1] == 'X' && tabuleiro[2][0] == 'X'){
System.out.println("'X' VENCEU");
return true;
}
//Checa O verticalmente
if(tabuleiro[0][0] == 'O' && tabuleiro[1][0] == 'O' && tabuleiro [2][0] == 'O'){
System.out.println("'O' VENCEU");
return true;
}
else if(tabuleiro[0][1] == 'O' && tabuleiro[1][1] == 'O' && tabuleiro[2][1] == 'O'){
System.out.println("'O' VENCEU");
return true;
}
else if(tabuleiro[0][2] == 'O' && tabuleiro[1][2] == 'O' && tabuleiro[2][2] == 'O'){
System.out.println("'O' VENCEU");
return true;
}

//Checa O horizontalmente
if(tabuleiro[0][0] == 'O' && tabuleiro[0][1] == 'O' && tabuleiro[0][2] == 'O'){
System.out.println("'O' VENCEU");
return true;
}
else if(tabuleiro[1][0] == 'O' && tabuleiro[1][1] == 'O' && tabuleiro[1][2] == 'O'){
System.out.println("'O' VENCEU");
return true;
}
else if(tabuleiro[2][0] == 'O' && tabuleiro[2][1] == 'O' && tabuleiro[2][2] == 'O'){
System.out.println("'O' VENCEU");
return true;
}

//Checa O diagonalmente
if(tabuleiro[0][0] == 'O' && tabuleiro[1][1] == 'O' && tabuleiro[2][2] == 'O'){
System.out.println("'O' VENCEU");
return true;
}
else if(tabuleiro[0][2] == 'O' && tabuleiro[1][1] == 'O' && tabuleiro[2][0] == 'O'){
System.out.println("'O' VENCEU");
return true;
}

return false;
}
``````

Since you prefer with few `IF` s, I made a solution using an `IF` and a `FOR` only.

Solution:

``````public class JogoVelha {

public static String obtemVencedor(String[] tabuleiro) {

if ((tabuleiro == null) || (tabuleiro.length != 9)) {
throw new IllegalArgumentException
("Um tabuleiro deve ser um array de 9 posições.");
}
Integer[][] padroesVitoria = {
{0, 1, 2},
{0, 4, 8},
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
{2, 4, 6},
{3, 4, 5},
{6, 7, 8}};

boolean haVencedor = tabuleiro[padraoVitoria[0]] != null

if (haVencedor) {
String vencedor = tabuleiro[padraoVitoria[0]];
return vencedor;
}
}
return null;
}
}
``````

Test:

``````@Test
public void jovadorXVence() {

String[] tabuleiro = {
"X", "O", null,
"O", "O", null,
"X", "X", "X"} ;

String vencedor = JogoVelha.obtemVencedor(tabuleiro);

assertEquals("X", vencedor);
}

@Test
public void naoHaVencedor() {

String[] tabuleiro = {
"X", "O", null,
"O", "O", null,
"X", null, "X"} ;

String vencedor = JogoVelha.obtemVencedor(tabuleiro);

assertNull(vencedor);
}
``````

My approach was as follows:

• I noticed that the board has nine positions. Your preview would look like this:

` `0 | 1 | 2 --------- 3 | 4 | 5 --------- 6 | 7 | 8``
• Then the filled or partially filled board can be represented by an array of 9 positions.

• So I visualized an example of a finished game. It would be as follows:

` `X | O | - --------- O | O | - --------- X | X | X``
• Viewing this completed game within my array, I identified the winning patterns (which positions within the array, when occupied by the same player, signal a win):

` `0 1 2 0 4 8 0 3 6 1 4 7 2 5 8 2 4 6 3 4 5 6 7 8``
• And so I wrote an algorithm to process the array representing a board, looking inside it for the winning patterns.

After each turn, `obtemVencedor` can be invoked to identify if there is already a winner. If there is no winner, we can check if there are still available positions on the board (if there are non-null elements in the array) to see if the game ended in a draw.

Scroll to Top