using regex to do create a tictactoe
function which receives a string of nine "X", "O", and/or "-" characters representing the state of a tic tac toe board, for example the string:"X-OXXXO-O"
this represents:
X-O
XXX
O-O
some more examples:
"XOOOXXXXO" - False - no one got three in a row here.
"OXO-XOX-O" - True - player O won by getting three in a row vertically in the third column.
here is my attempt at writing the code:
public static boolean regexTicTacToeWinChecker(String b) {
return b.matches("(((^(...)*000(...)*$)|(.*0..0..0.*)|(0(...0{2}))|(.(.0){3}..))) | (((^(...)*XXX(...)*$)|(.*X..X..X.*)|(X(...X){2})|(.(.X){3}..)))");
}
using regex is much more useful then writing a lot of if's which cover all the cases. so answers with rejex please, help would be appreciated. thanks here are some tests that you can use to check:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
public class ExampleTestCases {
@Test
public void SomeBoardsWithWinnersTests () {
String[] winners = new String[]{"XXX-O-O-O", "X--OOOX-X", "O--OO-XXX", "O-XOX-O-X", "OXOOXOXX-", "X-O-OOXXO", "XO--X-OOX", "X-OXOOOXX"};
for (String winner : winners) {
System.out.println("Testing with board " + winner);
assertEquals(true, RegexTicTacToeWinChecker.regexTicTacToeWinChecker(winner));
}
}
@Test
public void SomeBoardsWithoutWinnersTests () {
String[] notWinners = new String[]{"XO-------", "XX-XOO---", "-XX-OO-O-", "OXO--XXO-", "OOXXXO---", "OXXX-XOO-", "OOXXX----", "XXOOXXOO-", "OXOXOX---"};
for (String notWinner : notWinners) {
System.out.println("Testing with board " + notWinner);
assertEquals(false, RegexTicTacToeWinChecker.regexTicTacToeWinChecker(notWinner));
}
}
}
You can break it down into the individual cases:
Horizontal match:
(?:...){0,2}([OX])\1\1
Vertical match:
.{0,2}([OX])..\2..\2
Diagonal match (two directions):
([OX])...\3...\3
..([OX]).\4.\4
Now, you just have to or
them all together and make sure that the regex matches at the beginning of the board string:
^(?:(?:...){0,2}([OX])\1\1|.{0,2}([OX])..\2..\2|([OX])...\3...\3|..([OX]).\4.\4)
Edit: Here's a small Java program to test the regex:
import java.util.regex.*;
public class TicTacToe {
public static void main(String[] args) {
Pattern r = Pattern.compile("^(?:(?:...){0,2}([OX])\\1\\1|.{0,2}([OX])..\\2..\\2|([OX])...\\3...\\3|..([OX]).\\4.\\4)");
String board = "XXX-O-O-O";
Matcher m = r.matcher(board);
System.out.println(m.lookingAt() ? "match" : "no match");
}
}