I'm looking for the most efficient java way to test if somebody has won at tic tac toe. The data is in a 2d array like so...
char[][] ticTacToe =
{{'X',' ','O'},
{'O','X','O'},
{'X',' ','X'},};
I know this isn't the professional way to initialize an array but I'm just testing here.
The best I can do for right now is an exhaustive if/else tree. Here's one of those trees...
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");
}
}
}
This one only cares about what's in the middle
This is very basic and I want to improve it as far as minimizing lines of code goes.
When a player places a piece, update the corresponding row pair, column pair, and diagonal pairs (if on the diagonals). If any newly updated row, column, or diagonal pair equals either (n,0) or (0,n) then either A or B won, respectively.
Breaking down the problem of tic-tac-toe, one will realize that there are only 8 winning conditions in the game. We can create a handful of functions that will checkForWin when a square is clicked.
Most experienced tic tac toe players put the first "X" in a corner when they get to play first. This gives the opponent the most opportunities to make a mistake. If your opponent responds by putting an O anywhere besides the center, you can guarantee a win.
If both players play optimally, the first player will always win if they place their first move in the center of the cube. This is the same fork strategy that is used by two-dimensional boards, except that in 3x3 cubes, this strategy always works.
Just for fun, keep two numbers, starting as zeros, one for X
, one for O
. Update them by or
ing with the moves. To check for a winner, first and
, then xor
with the mask.
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)
For more fun, here's an example that plays O
in your favorite JavaScript console:
<!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>
Mark board as 3x3 magicSquare and you have win when sum in line is 15.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With