home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ahoy 1986 February
/
Ahoy_Magazine_86-02_1986_Double_L.d64
/
elmac
(
.txt
)
< prev
next >
Wrap
Commodore BASIC
|
2022-10-26
|
7KB
|
252 lines
0 rem << rr26-1 >>
10 rem
15 rem rupert report #26
20 rem elmac plays nim
25 rem
30 print chr$(147);
40 :rem - - - - - - - -
50 :rem initialize
55 :rem - - - - - - - -
60 dim a(3,4,5,12),m(6,3)
70 false=0 : true=not false
80 bk$="[157][157][157][157][157][157][157][157][157][157]"
90 sp$=" "
100 l$="======================================"
105 poke53280,0:poke53281,6
110 print "elmac <the elementary learning machine>"tab(53)"plays nim" : print
120 open 15,8,15 :rem disk error channel
125 :rem - - - - - - - - - - - -
130 rem - - begin new game - -
140 :rem - - - - - - - - - - - -
150 :rem read keyboard
160 gosub 2110
170 :rem player chosen yet?
180 if pl=0 then 160
190 :rem move array filled yet?
200 if f0=1 then 230
210 :rem fill move array initially
220 print : print "thinking ..." : gosub 1580 : f0=1
230 if not mdchg then 300
240 :rem new game in new mode
250 print chr$(147); : ll=5 : gosub 2400 : mdchg=false
260 :rem
270 :rem <><><> main game loop <><><><>
280 :rem
290 :rem new game in previous mode
300 x=3 : y=4 : z=5 : mn=0
310 :rem does elmac go first?
320 if rnd(0)<.5 then 380
330 :rem other player's move
340 on pl gosub 810,1790
350 :rem did other player win?
360 if x+y+z=0 then win=false :goto 460
370 :rem elmac's turn
380 gosub 530
390 :rem did elmac lose?
400 if tm=0 then win=false : goto 460
410 :rem did elmac make last move?
420 if x+y+z=0 then win=true : goto 460
430 :rem ready for next move
440 goto 340
450 :rem go to game over routine
460 gosub 970
470 :rem has any key been pressed?
480 get r$ : if r$<>"" then 160
490 :rem start next game, same mode
500 goto 300
510 :rem <><><> end of game loop <><><>
520 :rem - - - - - - - - - -
530 rem elmac's move
540 :rem - - - - - - - - - -
550 :rem how many valid moves?
560 tm=a(x,y,z,0)
570 :rem return if no valid moves; elmac lost
580 if tm=0 then 790
590 :rem select next move
600 rn=int(rnd(0)*tm)+1
610 :rem step thru the choices to find the selected move
620 ct=0 : for p=1 to 12
630 ct=ct+a(x,y,z,p) : mv=p
640 :rem found move value (mv=1 to 12)
650 if ct>=rn then p=12
660 next p
670 :rem record the move
680 mn=mn+1 : m(mn,0)=mv : m(mn,1)=x
690 m(mn,2)=y : m(mn,3)=z
700 :rem save the board
710 x0=x : y0=y : z0=z
720 :rem mv stores the selected move
730 if mv<4 then x=x-mv : goto 770
740 if mv<8 then y=y-mv+3 : goto 770
750 z=z-mv+7
760 :rem show board after move
770 print "elmac: ";x;y;z
780 :rem next move
790 return
800 :rem - - - - - - - - - - -
810 rem random player
820 :rem - - - - - - - - - - -
830 :rem pick random move
840 row=int(rnd(0)*3)+1
850 if row=1 then max=x
860 if row=2 then max=y
870 if row=3 then max=z
880 :rem if row empty, try again
890 if max=0 then 840
900 num=int(rnd(0)*max)+1
910 if row=1 then x=x-num
920 if row=2 then y=y-num
930 if row=3 then z=z-num
940 print "random:";x;y;z
950 return
960 :rem - - - - - - - - - -
970 rem game over
980 :rem - - - - - - - - - -
990 :rem increment number of games
1000 ng=ng+1
1010 if win=true then 1110
1020 :rem > > elmac lost! < <
1030 :rem punish the last move
1040 last=a(x0,y0,z0,mv)
1050 a(x0,y0,z0,mv)=0
1060 a(x0,y0,z0,0)=a(x0,y0,z0,0)-last
1070 :rem increment number of losses
1080 nl=nl+1
1090 :rem update screen
1100 goto 1220
1110 :rem > > elmac won! < <
1120 :rem increment number of wins
1130 nw=nw+1
1140 :rem reward all winning moves
1150 for j=1 to mn
1160 x1=m(j,1) : y1=m(j,2) : z1=m(j,3)
1170 m1=m(j,0)
1180 a(x1,y1,z1,m1)=a(x1,y1,z1,m1)+1
1190 a(x1,y1,z1,0)=a(x1,y1,z1,0)+1
1200 next j
1210 :rem update screen
1220 if pl=1 then 1260
1230 if win then print "elmac won. press any key."
1240 if not win then print "you won. press any key."
1250 get r$ : if r$="" then 1250
1260 for j=1 to 8 : print sp$ : next j :ll=1 : gosub 2400
1270 wstrk=wstrk+1
1280 if not win then wstrk=0
1290 if wstrk>wmax then wmax=wstrk
1300 print "# games, wins, losses % win"
1310 print tab(2)ng;tab(9)nw;tab(16)nl;tab(25)left$(str$(100*nw/ng)+" ",7)
1320 print "current/longest win streak ";bk$;wstrk;"/";wmax : print l$
1330 :rem ready for new game
1340 return
1350 :rem - - - - - - - - - - - - - - -
1360 rem display & save move array
1370 :rem - - - - - - - - - - - - - - -
1375 :rem display move array
1380 print chr$(147)
1390 for i=0 to 3 : for j=0 to 4
1400 for k=0 to 5 : print "";i;j;k;"[146]"
1410 for p=0 to 12 : print a(i,j,k,p); : next p
1420 print :get r$ :if r$<>"" then i=3 :j=4 : k=5
1430 next k : next j : next i
1440 :rem save move array to disk
1450 input "save this array (y/n)";a$
1460 if a$<>"y" then 1560
1470 input "what filename";f$
1480 :rem create move array if it's not already loaded
1490 if f0=0 then print "one moment ..." : gosub 1580 : f0=1
1500 open 1,8,8,f$+",s,w" : gosub 2500
1510 for i=0 to 3 : for j=0 to 4
1520 for k=0 to 5 : for p=0 to 12
1530 print#1,a(i,j,k,p)
1540 next p,k,j,i
1550 print#1 : close 1
1560 return
1570 :rem - - - - - - - - - - - - - - -
1580 rem fill move array initially
1590 :rem - - - - - - - - - - - - - - -
1600 for x=0 to 3 : for y=0 to 4
1610 for z=0 to 5
1620 a(x,y,z,0)=x+y+z
1630 if x<>0 then for p=1 to x : a(x,y,z,p)=1 : next p
1640 if y<>0 then for p=4 to y+3:a(x,y,z,p)=1:next p
1650 if z<>0 then for p=8 to z+7:a(x,y,z,p)=1:next p
1660 next z,y,x
1670 return
1680 :rem - - - - - - - - - - - - - - -
1690 rem fill move array from file
1700 :rem - - - - - - - - - - - - - - -
1710 input"load from what file";f$
1720 open 1,8,8,f$+",s,r" : gosub 2500
1730 for i=0 to 3 : for j=0 to 4
1740 for k=0 to 5 : for p=0 to 12
1750 input#1,a(i,j,k,p)
1760 next p,k,j,i : close 1
1770 return
1780 :rem - - - - - - - -
1790 rem user plays
1800 :rem - - - - - - - -
1810 b(1)=x : b(2)=y : b(3)=z
1820 for j=1 to 5 : print sp$ :next j
1830 ll=10 : gosub 2400
1840 print "row 1 =";x
1850 print "row 2 =";y
1860 print "row 3 =";z
1870 print " <press m to go to menu>"
1880 print ""sp$"[145]"
1890 input "pick from which row";rw$
1900 :rem m = back to menu & restart
1910 if rw$="m" then 160
1920 rw=val(rw$)
1930 if rw<1 or rw>3 then 1820
1940 :rem 0 = empty row
1950 if b(rw)=0 then 1820
1960 ll=17 : gosub 2400
1970 print sp$"[145]"
1980 print "take how many from row";rw;
1990 input tk$ : if tk$="m" then 160
2000 tk=val(tk$)
2010 :rem take too many?
2020 if tk>b(rw) then 1960
2030 :rem choose a different row
2040 if tk<1 then 1820
2050 b(rw)=b(rw)-tk
2060 x=b(1) : y=b(2) : z=b(3)
2070 ll=5 : gosub 2400
2080 print "user: ";x;y;z
2090 return
2100 :rem - - - - - - - - - -
2110 rem read keyboard
2120 :rem - - - - - - - - - -
2130 print : print sp$,sp$ : print l$
2140 print "press <c> for random computer to play against elmac"
2150 print"press <p> to play against elmac "
2160 print "press <l> to load the move array from disk"
2170 print "press <d> to display the move array "
2180 print "press <s> to save the move array to disk" : print : print
2190 get r$ : if r$="" then 2190
2200 print r$
2205 :rem mode change
2210 mdchg=true
2220 :rem random computer plays
2230 if r$="c" then pl=1 : return
2240 :rem user plays
2250 if r$="p" then pl=2 : return
2255 :rem display the move array
2260 if r$<>"d" then 2290
2270 if f0=0 then print "thinking..." : gosub 1580 : f0=1
2280 gosub 1360 : return
2285 :rem save the move array
2290 if r$="s" then gosub 1450 :return
2300 :rem load the move array
2310 if r$="l" then gosub 1690 : f0=1 : return
2320 goto 2130 :rem bad key
2400 rem locate cursor at column one of line ll (ll=1 to 24)
2410 poke 214,ll-1 : print
2420 return
2500 rem check disk error status
2510 input#15,en,em$,et,es
2520 if en<20 then 2550
2530 print en;em$;et;es : close 15 : close 1 : goto 120
2540 :rem no error
2550 return