Проверка состояния выигрыша tic tac toe
Я ищу наиболее эффективный способ java, чтобы проверить, выиграл ли кто-нибудь в tic tac toe. Данные находятся в массиве 2d, например...
char[][] ticTacToe =
{{'X',' ','O'},
{'O','X','O'},
{'X',' ','X'},};
Я знаю, что это не профессиональный способ инициализации массива, но я просто тестирую здесь.
Лучшее, что я могу сделать сейчас, - это исчерпывающее дерево if/else.
Здесь один из этих деревьев...
if (ticTacToe[1][1] == 'X'){
if (ticTacToe[0][0] == 'X'){
if (ticTacToe[2][2] == 'X'){
System.out.println("X wins");
}
}
else if (ticTacToe[0][1] == 'X'){
if (ticTacToe[2][1] == 'X'){
System.out.println("X wins");
}
}
else if (ticTacToe[1][0] == 'X'){
if (ticTacToe[1][2] == 'X'){
System.out.println("X wins");
}
}
else if (ticTacToe[2][0] == 'X'){
if (ticTacToe[0][2] == 'X'){
System.out.println("X wins");
}
}
}
Этот только заботится о том, что посередине
Это очень просто, и я хочу его улучшить, поскольку минимизация строк кода идет.
Ответы
Ответ 1
Это немного многословно, но я думаю, что это, вероятно, самый эффективный способ сделать это (если кто-то не придумает умный способ проверить обе диагонали сразу).
public class TicTacToe
{
char[][] ticTacToe =
{{'X',' ','O'},
{'O','X','O'},
{'X',' ','X'},};
private Character winner = null;
public Character getWinner()
{
return this.winner;
}
public boolean isSolved()
{
this.checkSolved();
return this.winner != null;
}
private void checkSolved()
{
for(int i = 0; i < ticTacToe.length; i++)
{
Character win = checkRow(i);
if(win != null || (win = checkColumn(i)) != null)
{
this.winner = win;
return;
}
}
//Check diagonal top left to bottom right
if(this.ticTacToe[0][0] != ' ')
{
if(this.ticTacToe[0][0] == this.ticTacToe[1][1] &&
this.ticTacToe[1][1] == this.ticTacToe[2][2])
{
this.winner = this.ticTacToe[0][0];
}
}
//Check diagonal top right to bottom left
else if(this.ticTacToe[0][2] != ' ')
{
if(this.ticTacToe[0][2] == this.ticTacToe[1][1] &&
this.ticTacToe[1][1] == this.ticTacToe[2][0])
{
this.winner = this.ticTacToe[0][2];
}
}
}
private Character checkRow(int row)
{
if(this.ticTacToe[row][0] == ' ')
{
return null;
}
if(this.ticTacToe[row][0] == this.ticTacToe[row][1] &&
this.ticTacToe[row][1] == this.ticTacToe[row][2])
{
return this.ticTacToe[row][0];
}
return null;
}
private Character checkColumn(int column)
{
if(this.ticTacToe[0][column] == ' ')
{
return null;
}
if(this.ticTacToe[0][column] == this.ticTacToe[1][column] &&
this.ticTacToe[1][column] == this.ticTacToe[2][column])
{
return this.ticTacToe[column][0];
}
return null;
}
public static void main(String[] args)
{
TicTacToe ttt = new TicTacToe();
if(ttt.isSolved())
{
System.out.println(ttt.getWinner()); // X
}
}
}
Ответ 2
Просто для удовольствия сохраните два числа, начиная с нулей, один для X
, один для O
. Обновите их с помощью or
ing с помощью ходов. Чтобы проверить победителя, сначала and
, затем xor
с помощью маски.
277 & 273 ^ 273
0 ==> we have a winner.
276 & 273 ^ 273
1 ==> not.
277 == parseInt ( "100010101", 2)
273 == parseInt ( "100010001", 2)
276 == parseInt ( "100010100", 2)
Для удовольствия, вот пример, который воспроизводит O
в вашей любимой консоли JavaScript:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
</head>
<body>
<script>
var x = 0, o = 0, count = 0, w = 0
ws = [0007,0070,0700,0111,0222,0444,0124,0421]
function t1(v){
var w1 = 0
for (var i in ws)
w1 |= !(v & ws[i] ^ ws[i])
return w1
}
function t(i){
var ot = count % 2, m = 1 << (9 - i), bd = x | o
if (!ot && (i > 9 || i < 1 || i != Math.floor(i)))
return "Out of bounds."
else if (m & bd)
return "Position taken."
if (ot){
var n1 = 0, a1 = -2
while (bd & (1 << n1))
n1++
var n = n1
while (n1 < 9){
var m1 = 1 << n1
if (!(bd & m1)){
var bt = -mx(x,o | m1,count + 1)
if (bt > a1){
a1 = bt
n = n1
}
}
n1++
}
w = t1(o |= 1 << n)
}
else
w = t1(x |= m)
var b = "\n", p = 0400
while (p > 0){
if (p & x)
b += "X"
else if (p & o)
b += "O"
else b += "."
if (p & 0110)
b += "\n"
p >>= 1
}
if (w)
b += "\n\n" + (ot ? "O" : "X") + " wins!"
else if (!(bd ^ 0777))
b += "\n\nDraw."
if (!ot){
console.log(b + '\n\n"""')
count++
console.log(t(-1))
count++
}
else
return b + "\n"
return '"'
}
function mx(x1,o1,c1){
var ot1 = c1 % 2, w1 = ot1 ? t1(x1) : t1 (o1),
b1 = x1 | o1, p = 0400
if (w1)
return -1
if (!(b1 ^ 0777))
return 0
var a = -2
while (p > 0){
if (!(b1 & p))
a = Math.max(a,-mx(ot1 ? x1 : x1 | p,ot1 ? o1 | p : o1,c1 + 1))
p >>= 1
}
return a
}
console.log(' Plays O!'
+ '\nTo play, type t(MOVE); MOVE is from 1-9')
</script>
</body>
</html>
Ответ 3
Отметьте доску как 3x3 magicSquare, и вы выиграете, когда сумма в строке равна 15.
![enter image description here]()
Ответ 4
Для игрока, скажем, "x", есть восемь способов выиграть, и каждый соответствует 3 'x' в строке/столбце/диагонали.
Следовательно, вы можете создать массив длиной 8, и каждый элемент соответствует числу "x" в этой строке/столбце/диагонали.
Когда игрок выбирает ход, вы обновляете массив и проверяете наличие 3 в массиве.
Хотя для этого требуется больше места, его проще обобщить на большую доску.
Ответ 5
Существует четыре разных способа победить на тик-лапах:
- образуют горизонтальную линию
- образуют вертикальную линию
- образуют диагональную линию от верхнего левого до нижнего правого угла.
- сформировать диагональную линию от нижнего левого до верхнего правого угла.
Все эти четыре условия выигрыша могут быть решены с помощью цикла for. Преимущество этого решения заключается в том, что его можно применять к любому размеру матрицы.