dos_compilers/Digital Research CB-86 v2/ttt.bas
2024-06-30 11:56:20 -07:00

187 lines
5.8 KiB
QBasic
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

rem coded for CBASIC Compiler CB-80 21 May 83 Version 2.0
rem Tic Tac Toe solving app that learns what WOPR learned: you can't win
rem Only three starting positions are examined. Others are just reflections of these
rem b% -- The board
rem al% -- Alpha, for pruning
rem be% -- Beta, for pruning
rem l% -- Top-level loop iteration
rem mv% -- the first move taken
rem wi% -- The winning piece (0 none, 1 X, 2, O )
rem re% -- Resulting score of 4000/minmax board position. 5 draw, 6 X win, 4 Y win
rem sX% -- Stack arrays for "recursion" X can be P, V, A, or B for those variables.
rem v% -- Value of a board position
rem st% -- Stack Pointer. Even for alpha/beta pruning Minimize plys, Odd for Maximize
rem p% -- Current position where a new piece is played
rem mc% -- Move count total for debugging. Should be a multiple of 6493
rem Note: Can't use real recursion with GOSUB because stack is limited to roughly 5 deep
rem BASIC doesn't support goto/gosub using arrays for target line numbers
rem build like this:
rem ntvdm -t cb86 tttcb86
rem ntvdm -t link86 tttcb86 = tttcb86
li% = val( command$ )
if 0 = li% then li% = 1
dim b%(9)
dim sp%(10)
dim sv%(10)
dim sa%(10)
dim sb%(10)
mc% = 0
for l% = 1 to li%
mv% = 0 : p% = 0
mc% = 0
al% = 2
be% = 9
b%(mv%) = 1
goto 4000
55 b%(mv%) = 0
mv% = 1 : p% = 1
b%(mv%) = 1
al% = 2
be% = 9
goto 4000
65 b%(mv%) = 0
mv% = 4 : p% = 4
b%(mv%) = 1
al% = 2
be% = 9
goto 4000
75 b%(mv%) = 0
next l%
87 print "iterations: "; li%
print "move count: "; mc%
stop
rem this version is slower but works if there are no computed gotos
2000 wi% = b%( 0 )
if 0 = wi% then goto 2100
if wi% = b%( 1 ) and wi% = b%( 2 ) then goto 4106
if wi% = b%( 3 ) and wi% = b%( 6 ) then goto 4106
2100 wi% = b%( 3 )
if 0 = wi% then goto 2200
if wi% = b%( 4 ) and wi% = b%( 5 ) then goto 4106
2200 wi% = b%( 6 )
if 0 = wi% then goto 2300
if wi% = b%( 7 ) and wi% = b%( 8 ) then goto 4106
2300 wi% = b%( 1 )
if 0 = wi% then goto 2400
if wi% = b%( 4 ) and wi% = b%( 7 ) then goto 4106
2400 wi% = b%( 2 )
if 0 = wi% then goto 2500
if wi% = b%( 5 ) and wi% = b%( 8 ) then goto 4106
2500 wi% = b%( 4 )
if 0 = wi% then goto 4106
if wi% = b%( 0 ) and wi% = b%( 8 ) then goto 4106
if wi% = b%( 2 ) and wi% = b%( 6 ) then goto 4106
wi% = 0
goto 4106
3000 wi% = b%(0)
if ( ( wi% = b%(1) ) and ( wi% = b%(2) ) ) then goto 4106
if ( ( wi% = b%(3) ) and ( wi% = b%(6) ) ) then goto 4106
if ( ( wi% = b%(4) ) and ( wi% = b%(8) ) ) then goto 4106
wi% = 0
go to 4106
3010 wi% = b%(1)
if ( ( wi% = b%(0) ) and ( wi% = b%(2) ) ) then goto 4106
if ( ( wi% = b%(4) ) and ( wi% = b%(7) ) ) then goto 4106
wi% = 0
go to 4106
3020 wi% = b%(2)
if ( ( wi% = b%(0) ) and ( wi% = b%(1) ) ) then goto 4106
if ( ( wi% = b%(5) ) and ( wi% = b%(8) ) ) then goto 4106
if ( ( wi% = b%(4) ) and ( wi% = b%(6) ) ) then goto 4106
wi% = 0
go to 4106
3030 wi% = b%(3)
if ( ( wi% = b%(4) ) and ( wi% = b%(5) ) ) then goto 4106
if ( ( wi% = b%(0) ) and ( wi% = b%(6) ) ) then goto 4106
wi% = 0
go to 4106
3040 wi% = b%(4)
if ( ( wi% = b%(0) ) and ( wi% = b%(8) ) ) then goto 4106
if ( ( wi% = b%(2) ) and ( wi% = b%(6) ) ) then goto 4106
if ( ( wi% = b%(1) ) and ( wi% = b%(7) ) ) then goto 4106
if ( ( wi% = b%(3) ) and ( wi% = b%(5) ) ) then goto 4106
wi% = 0
go to 4106
3050 wi% = b%(5)
if ( ( wi% = b%(3) ) and ( wi% = b%(4) ) ) then goto 4106
if ( ( wi% = b%(2) ) and ( wi% = b%(8) ) ) then goto 4106
wi% = 0
go to 4106
3060 wi% = b%(6)
if ( ( wi% = b%(7) ) and ( wi% = b%(8) ) ) then goto 4106
if ( ( wi% = b%(0) ) and ( wi% = b%(3) ) ) then goto 4106
if ( ( wi% = b%(4) ) and ( wi% = b%(2) ) ) then goto 4106
wi% = 0
go to 4106
3070 wi% = b%(7)
if ( ( wi% = b%(6) ) and ( wi% = b%(8) ) ) then goto 4106
if ( ( wi% = b%(1) ) and ( wi% = b%(4) ) ) then goto 4106
wi% = 0
go to 4106
3080 wi% = b%(8)
if ( ( wi% = b%(6) ) and ( wi% = b%(7) ) ) then goto 4106
if ( ( wi% = b%(2) ) and ( wi% = b%(5) ) ) then goto 4106
if ( ( wi% = b%(0) ) and ( wi% = b%(4) ) ) then goto 4106
wi% = 0
go to 4106
4000 rem minmax function to find score of a board position
rem recursion is simulated with gotos and arrays as stacks
st% = 0
v% = 0
re% = 0
4100 mc% = mc% + 1
rem print "{"; b%(0);b%(1);b%(2);b%(3);b%(4);b%(5);b%(6);b%(7);b%(8);"}";al%;be%;p%;st%
if st% < 4 then goto 4150
rem goto 2000
on (p% + 1) goto 3000, 3010, 3020, 3030, 3040, 3050, 3060, 3070, 3080
4106 if 0 = wi% then goto 4140
if wi% = 1 then re% = 6: goto 4280
re% = 4
goto 4280
4140 if st% = 8 then re% = 5: goto 4280
4150 if st% and 1 then v% = 2 else v% = 9
p% = 0
4180 if 0 <> b%(p%) then goto 4500
if st% and 1 then b%(p%) = 1 else b%(p%) = 2
sp%(st%) = p%
sv%(st%) = v%
sa%(st%) = al%
sb%(st%) = be%
st% = st% + 1
goto 4100
4280 st% = st% - 1
p% = sp%(st%)
v% = sv%(st%)
al% = sa%(st%)
be% = sb%(st%)
b%(p%) = 0
if st% and 1 then goto 4340
if re% = 4 then goto 4530
if re% < v% then v% = re%
if v% < be% then be% = v%
if be% <= al% then goto 4520
goto 4500
4340 if re% = 6 then goto 4530
if re% > v% then v% = re%
if v% > al% then al% = v%
if al% >= be% then goto 4520
4500 p% = p% + 1
if p% < 9 then goto 4180
4520 re% = v%
4530 if st% = 0 then on ( 1 + mv% ) goto 55, 65, 87, 87, 75
goto 4280
end