RosettaCodeData/Task/Tic-tac-toe/TAV/tic-tac-toe.tav
2026-04-30 12:34:36 -04:00

133 lines
3.5 KiB
Text

\( Simple (not perfect) solver for tic-tac-toe
The state is a 9-element vector, with
0 for free, 1 for user; 4 for machine
Lanes are used to check if there is a win or near-win:
1 2 3
4 5 6
7 8 9
1 4 7
2 5 8
3 6 9
1 5 9
3 5 7
For each lane, the sum of the values is calculated
and the number of free ones determined.
After the player's move and the machine action,
the lane sums are checked for wins:
- if = 3, the player has won, stop.
- if = 12, the machine has won, stop.
- if none are free, the game ends with a draw
The machine action is:
- if = 2, the player could win; set the free place
- if = 8, the machine will win, set the free place
- if field 5 is free, set
- if any of the fields 1, 3, 7 or 9 are free, set at random
- if any of the fields 2, 4, 6 or 8 are free, set at random
\)
main (parms):+
random set seed ()
print "enter field number, or 'x' to quit:"
state =: new row size 9 init 0
state.lanes =: ((1, 2, 3), (4, 5, 6), (7, 8, 9), (1, 4, 7), (2, 5, 8), (3, 6, 9), (1, 5, 9), (3, 5, 7))
state.free =: 9
?* state.free > 0
show state
set user state
show state
check end state
? state.free > 0
step move state
check end state
show state
check end (state):
?# t =: tuple state.lanes give values
c =: sum of places state lane t
\ print c, t
? c = 3:
print "You win:", t
?# i =: tuple t give values
state[i] =: '+'
state.free =: 0
:>
? c = 12:
print "I win:", t
?# i =: tuple t give values
state[i] =: '*'
state.free =: 0
:>
? state.free = 0
print "This is a draw."
step move (state):
?# t =: tuple state.lanes give values
c =: sum of places state lane t
? c = 2
set state at t
:>
? c = 8
set state at t
:>
? set state at 5
:>
? set state at shuffle 1, 3, 7, 9
:>
? set state at shuffle 2, 4, 6, 8
:>
set (state) at (points):
? ~ is points tuple
points =: points, () \ make it a tuple
?# i =: tuple points give values
? state[i] = 0
state[i] =: 4
print "my move:", i
:> ?+
:> ?-
shuffle (points):
n =: points.Count
r =: random tuple n
points =: tuple points select r
:> points
sum of places (state) lane (tpl):
s =: 0
?# i =: tuple tpl give values
v =: state[i]
? v ~= 0
s =+ state[i]
:> s
set user (state):
?*
print "your move: " nonl
c =: file stream () get
? c = 'q' || c = 'x' || c = ()
system exit 0
n =: string c as integer else ()
? n = () || n < 1 || n > state.Count
print "Invalid input, " nonl
?^
? state[n] = 0
state[n] =: 1
:>
print "not free; retry " nonl
show (state):
state.free =:0
?# i =: from 1 upto 9
v =: state[i]
w =: v
? v = 0
w =: i
state.free =+ 1
? v = 1
w =: 'X'
? v = 4
w =: 'O'
print ' ' _ w nonl
? i = 3 || i = 6
print ''
print ''
\ state.free=0 is used to terminate the central loop