Tic-tac-toe: Difference between revisions

Content deleted Content added
Cchando (talk | contribs)
→‎{{header|J}}: shorten code; prefer separate explanation over comments
Chkas (talk | contribs)
 
(18 intermediate revisions by one other user not shown)
Line 4,741:
It uses minimax with alpha-beta pruning. Therefore, the computer never loses.
 
[https://easylang.devonline/apps/tictactoe.html Run it]
 
<syntaxhighlight>
Line 4,828:
else
rval = alpha
start = randintrandom 9
mov = start
repeat
Line 6,687:
=={{header|J}}==
<syntaxhighlight lang="j">
(Until=: {{[ F.(u[_2:Z:v)}}) prompt=: [ echo@'enter a move (1–9):'
'`turn board open full'=: {.`}.`(0=[{board@])`(0-.@e.board)
'`turn board open '`cpu_move positionfull'=: (?@#{])@.`}.`([:I.0=[{board@])`(cpu_move`you_move0-.@e.(_1 1 i.turn)board)
'`cpu_move pos'=: (?@#{])@([:I.0=board)`(cpu_move`you_move@.(_1 1 i.turn))
you_move=: $:@echo@'invalid'^:(-.@e.i.@9)@:<:@".@>@{.@;:@(1!:1@1)@prompt
move=: position (][echo@'already taken!')`(-@turn@] , turn@]`[`(board@])})@.open ]
showmove=: [pos ($:@][: echo@'already taken!')`(-@echo (turn@],' '&,)/"1turn@]`[`('.XO'{~3 3$board@])})@.open [ echo@'']
outcome=: echo@'tie'`(' wins'echo@,~{&'.XO'{~@-@turn)`(echo@'tie')@.(1:i.~won,full)
won=: [:+./ (3=[:|+/)"1@(], |:, (<@i.@2|:]),: <@i.@2|:|.)@(3 3$board)
show=: [ prompt=[: echo@:>:''@iecho (,' '&,)/"1@({&'.XO')@(3 3$board) [ echo@'enter a move (1–9) each turn; you''re X''s'
won=: [: +./ (3=[:|+/)"1@(], |:, (<@i.@2|:]),: <@i.@2|:|.)@(3 3$board)
outcome=: (' wins'echo@,~'.XO'{~-@turn)`(echo@'tie')@.(1:i.~won,full)
ttt=: [: outcome@( [F.(: show@move[_2:Z: Until (won+.full))@( 10{._1)@prompt "_
 
</syntaxhighlight>
This version is stateless, purely functional, and tacit. CPU selects a random open position. The <code>turn</code> and <code>board</code> verbs extract the turn/board from the state vector. The board is represented by a vector of -1's, 0’s and 1’s, which index into the character vector '.XO' when it’s time to display the board.
 
{{out}}
Encoding data with numbers this way allows the convenience of e.g. being able to simply check whether the absolute value of the sum across a given line is 3, indicating a win.
 
<pre>
]M=: 0 1 _1{~?3 3$3
0 _1 _1
_1 1 1
_1 1 0
M{'.XO'
.OO
OXX
OX.
</pre>
 
The verb <code>open</code> tests whether the selected position is available on the board. Fold (<code>F.</code>) is used because <code>Until=:<tt>{{</tt>u^:(-.@:v)^:_<tt>}}</tt></code> would've quit upon receiving invalid input, as the argument would be unchanged between that iteration and the next.
 
Sample play:
<pre> ttt 0
enter a move (1–9) each turn; you're X's
1 2 3
4 5 6
7 8 9
 
. O .
. . .
. . .
enter a move (1–9) each turn; you're X's:
 
1
 
Line 6,736 ⟶ 6,715:
. . .
. . O
enter a move (1–9):
 
5
 
Line 6,747 ⟶ 6,726:
. X .
. O O
enter a move (1–9):
 
_1
invalid!
enter a move (1–9):
7
 
Line 6,758 ⟶ 6,740:
O X .
X O O
enter a move (1–9):
 
9
already taken!
enter a move (1–9):
 
X O .
O X .
X O O
 
3
 
Line 6,772 ⟶ 6,750:
X O O
 
X wins</pre>
 
</pre>
CPU selects a random open position.
 
This implementation is stateless (no mutation or variables) and written entirely in tacit style. The <code>turn</code> and <code>board</code> verbs extract the turn/board from the vector which represents the game state. The verb <code>open</code> tests whether the selected position is available on the board. Fold (<code>F.</code>) is used because the familiar <code>Until=:<tt>{{</tt>u^:(-.@:v)^:_<tt>}}</tt></code> idiom would've quit upon receiving invalid input, as the argument would beremain unchanged between that iteration andfor the next iteration.
 
=={{header|Java}}==