在 java 中使用正则表达式的井字棋
TicTacToe using regex in java
使用正则表达式创建一个井字
该函数接收表示井字棋盘状态的九个“X”、“O”、and/or“-”字符的字符串,例如字符串:"X-OXXXO-O"
这代表:
X-O
XXX
O-O
更多示例:
"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.
这是我编写代码的尝试:
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}..)))");
}
使用正则表达式比编写大量涵盖所有情况的 if 更有用。所以请用 rejex 回答,我们将不胜感激。谢谢
这里有一些您可以用来检查的测试:
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));
}
}
}
您可以将其分解为个别情况:
水平匹配:
(?:...){0,2}([OX])
垂直匹配:
.{0,2}([OX])....
对角匹配(两个方向):
([OX])......
..([OX])..
现在,您只需 or
将它们放在一起,并确保正则表达式匹配板字符串的开头:
^(?:(?:...){0,2}([OX])|.{0,2}([OX])....|([OX])......|..([OX])..)
编辑:这是一个 Java 小程序来测试正则表达式:
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");
}
}
如果您希望能够在几个月后维护您的正则表达式,老实说,我宁愿选择更具可读性的东西,而不是过于聪明,例如;
Vertical match: X..X..X..|.X..X..X.|..X..X..X
Horizontal match: XXX......|...XXX...|......XXX
Diagonal match: X...X...X|..X.X.X..
在一起:
^(?:X..X..X..|.X..X..X.|..X..X..X|XXX......|...XXX...|......XXX|X...X...X|..X.X.X..)$
这使得仅通过查看正则表达式就几乎可以看到获胜模式。
对 O
做同样的事情,你应该可以开始了:)
我希望您的正则表达式尽可能简单!这意味着您需要停止将所有内容压缩到一个字符串中。
想象一下:
XOX
OOX
XXO
为什么不创建多个字符串,例如:
- 水平线:
XOX
- 水平线:
OOX
- 水平线:
XXO
和
- 竖线:
XOX
- 竖线:
OOX
- 竖线:
XXO
和
- 左上对角线:
XOO
- 左下对角线:
XOX
和 运行 这些值中的每一个都反对:
"^X{3}$" = player 1 won
"^O{3}$" = player 2 won
在代码中:
Pattern player1Pattern = Pattern.compile("^X{3}$");
Pattern player2Pattern = Pattern.compile("^O{3}$");
for(String s: tictactoe) {
if(player1Pattern.matcher(s).matches()){
//Player 1 wins
}else if(player2Pattern.matcher(s).matches()){
//Player 2 wins
}else{
//nobody wins
}
}
你可以试试这个:
我只是将输入作为模式输入:
X-O
XXX
O-O
Pattern pattern = Pattern.compile("([XO])(?:(?:\1\1)|(?:(?:[\sXO-]{2}\1){2})|(?:[\sXO-]{3}\1){2}|(?:[\sXO-]{4}\1){2})", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("X-O\n" +
"XXX\n" +
"O-O");
boolean matchFound = matcher.find();
if(matchFound) {
System.out.println("Match found and "+ matcher.group(1) + " win!");
} else {
System.out.println("Match not found!");
}
输出:
Match found and X win!
使用正则表达式创建一个井字
该函数接收表示井字棋盘状态的九个“X”、“O”、and/or“-”字符的字符串,例如字符串:"X-OXXXO-O"
这代表:
X-O
XXX
O-O
更多示例:
"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.
这是我编写代码的尝试:
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}..)))");
}
使用正则表达式比编写大量涵盖所有情况的 if 更有用。所以请用 rejex 回答,我们将不胜感激。谢谢 这里有一些您可以用来检查的测试:
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));
}
}
}
您可以将其分解为个别情况:
水平匹配:
(?:...){0,2}([OX])
垂直匹配:
.{0,2}([OX])....
对角匹配(两个方向):
([OX])......
..([OX])..
现在,您只需 or
将它们放在一起,并确保正则表达式匹配板字符串的开头:
^(?:(?:...){0,2}([OX])|.{0,2}([OX])....|([OX])......|..([OX])..)
编辑:这是一个 Java 小程序来测试正则表达式:
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");
}
}
如果您希望能够在几个月后维护您的正则表达式,老实说,我宁愿选择更具可读性的东西,而不是过于聪明,例如;
Vertical match: X..X..X..|.X..X..X.|..X..X..X
Horizontal match: XXX......|...XXX...|......XXX
Diagonal match: X...X...X|..X.X.X..
在一起:
^(?:X..X..X..|.X..X..X.|..X..X..X|XXX......|...XXX...|......XXX|X...X...X|..X.X.X..)$
这使得仅通过查看正则表达式就几乎可以看到获胜模式。
对 O
做同样的事情,你应该可以开始了:)
我希望您的正则表达式尽可能简单!这意味着您需要停止将所有内容压缩到一个字符串中。
想象一下:
XOX
OOX
XXO
为什么不创建多个字符串,例如:
- 水平线:
XOX
- 水平线:
OOX
- 水平线:
XXO
和
- 竖线:
XOX
- 竖线:
OOX
- 竖线:
XXO
和
- 左上对角线:
XOO
- 左下对角线:
XOX
和 运行 这些值中的每一个都反对:
"^X{3}$" = player 1 won
"^O{3}$" = player 2 won
在代码中:
Pattern player1Pattern = Pattern.compile("^X{3}$");
Pattern player2Pattern = Pattern.compile("^O{3}$");
for(String s: tictactoe) {
if(player1Pattern.matcher(s).matches()){
//Player 1 wins
}else if(player2Pattern.matcher(s).matches()){
//Player 2 wins
}else{
//nobody wins
}
}
你可以试试这个:
我只是将输入作为模式输入:
X-O
XXX
O-O
Pattern pattern = Pattern.compile("([XO])(?:(?:\1\1)|(?:(?:[\sXO-]{2}\1){2})|(?:[\sXO-]{3}\1){2}|(?:[\sXO-]{4}\1){2})", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("X-O\n" +
"XXX\n" +
"O-O");
boolean matchFound = matcher.find();
if(matchFound) {
System.out.println("Match found and "+ matcher.group(1) + " win!");
} else {
System.out.println("Match not found!");
}
输出:
Match found and X win!