A number of little improvements and the possibility for initial army placement.
To use that mode, change the variable "classic" in the first line of the code into 1 (in the final version, this will be nicely sollicited in an opening screen).
Each of your 7 countries will have one army, you can assign the remaining 13 armies yourself, by means of the already present "draft" method.
The data file is not given here, as it has not changed.
There is still a todo list. One of the activities is a (stand alone) tool to convert a piece of plain ASCCI text into a scrollable helpfile.
Code: Select all
' The game of Risk, version october 24, 2018
'
classic=0 ' change to 1 for classic initial army placement
init_risk()
do
init_round()
for cp.nr=1 to 6
init_player()
if cp.play(1)=0 then continue
if cp.nr=human then human_play(human) else ai_play()
exit_player()
next cp.nr
exit_round()
until stop
end
def init_round()
if .sflag then k=4 else k=3
for i=1 to .ns
.state(i,3)+=.state(i,1)
button i text floor(.state(i,k))
next i
end def
def init_player()
p=cp.nr ! cp.ncp=state_count()
cp.draft=1+cont_count()
field "play" back color .col(p,1),.col(p,2),.col(p,3)
button "cards" show ! bc(p)
do
if .cards(p)>4 then
cp.draft+=10 ! .cards(p)=max(0,.cards(p)-3) ! bc(p)
end if
until .cards(p)<5
end def
def human_play(p)
'
'***** draft phase
'
if cp.draft then
drafty(p)
/*
button "cont" show ! group2(1)
button "strength" show ! field "draft" show
button "troops" text "0" ! button "maxtr" text cp.draft
lnr=0 ! ntr=0
do slowdown
if bp("strength") then disp_strength()
if bp("less") and lnr>0 then
if ntr=0 then ntr=cp.draft else ntr-=1
button "troops" text ntr
end if
if bp("more") and lnr>0 then
if ntr=cp.draft then ntr=0 else ntr+=1
button "troops" text ntr
end if
if bp("okee") and lnr>0 then
.state(lnr,3)+=ntr ! cp.draft-=ntr ! ntr=0
button lnr text floor(.state(lnr,3))
button "troops" text "0" ! button "maxtr" text cp.draft
end if
for i=1 to .ns
if bp(str$(i)) and .state(i,2)=p then
if i=lnr then lnr=0 else lnr=i
end if
next i
until bp("cont")
group2(0) ! field "draft" hide
*/
end if
'
'***** attack phase
'
field "attack" show ! group3(1)
lna=0 ! lnd=0 ! sp_flag=0 ! s_flag=0 ! c_flag=0
state_count()
do slowdown
if lna>0 then ! button "att" text floor(.state(lna,3))
else ! button "att" text ""
end if
if lnd>0 then ! button "def" text floor(.state(lnd,3))
else ! button "def" text ""
end if
if bp("strength") then disp_strength()
k=0
for i=1 to .ns ' check state buttons
if bp(str$(i)) then ! k=i ! break! end if
next i
if k then ' check self or foreign
e=0
for i=2 to cp.play(1)+1
if k=cp.play(i) then ! e=1 ! break ! end if
next i
if lna=0 and lnd=0 and e=1 then
lna=k ! sign_fight(lna,1) ! goto done
end if
if lna>0 then
nb=0 ' check neighbour state or not
for j=1 to 6
if .link(lna,j)=k then nb=1
next j
if k=lnd then
sign_fight(lnd,-2) ! lnd=0 ! goto done
end if
if k=lna then
if lnd>0 then ! sign_fight(lnd,-2) ! lnd=0 ! end if
lna=0 ! sign_fight(k,-1) ! goto done
end if
if e=1 and k<>lna then
sign_fight(lna,-1) ! lna=k ! sign_fight(lna,1)
if lnd>0 then ! sign_fight(lnd,-2) ! lnd=0 ! end if
goto done
end if
if nb=1 and e=0 then
if lnd>0 then sign_fight(lnd,-2)
lnd=k ! sign_fight(lnd,2)
end if
end if
end if
done:
if lnd=0 then nxt else quit=0
do ' start attack cycles on this combi
if bp("stop") then
if s_flag=0 then
s_flag=1 ! quit=0 ! button "stop" text "Stop"
else
quit=1 ! button "stop" text "Start" ! continue
end if
end if
if s_flag=0 then ! slowdown ! continue ! end if
if bp("speed") then
sp_flag=1-sp_flag
if sp_flag then ! button ("speed") text "Fast"
else ! button ("speed") text "Slow"
end if
end if
if sp_flag=0 then pause 1 else pause .3
if bp("pause") then
button ("pause") text "Go on"
do ! slowdown ! until bp("pause")
button ("pause") text "Pause"
end if
r=attack(.state(lna,3), .state(lnd,3),.state(lnd,4))
if r=1 then
.state(lnd,3)-=1 ! button "def" text floor(.state(lnd,3))
button "ddef" text "-1" ! button "datt" text ""
button lnd text floor(.state(lnd,3))
else
.state(lna,3)-=1 ! button "att" text floor(.state(lna,3))
button "datt" text "-1" ! button "ddef" text ""
button lna text max(1,floor(.state(lna,3)))
end if
if floor(.state(lnd,3))=0 then ' victory
da=max(1,floor(.state(lna,3)/3)) ! beep
.state(lnd,3)=da ! .state(lna,3)-=da
defen=.state(lnd,2) ! .state(lnd,2)=p
draw_state(lnd,p) ! .state(lnd,4)=0 ! state_count()
dc=check_dead(defen)
if dc then ! .cards(p)+=dc ! bc(p) ! end if
c_flag=1 ! quit=1
end if
if floor(.state(lna,3))=1 then quit=1 ' end of fight
until quit
button "att" text "" ! button "datt" text ""
button "def" text "" ! button "ddef" text ""
button lna text max(1,floor(.state(lna,3)))
button lnd text max(1,floor(.state(lnd,3)))
button "stop" text "Start" ! button "speed" text "Slow"
lna=0 ! lnd=0 ! s_flag=0 ! sp_flag=0
nxt:
until bp("cont")
if c_flag=1 then
.cards(p)+=1 ! bc(p) ! c_flag=0
end if
'
'*****. Move phase
'
group3(0) ! group2(1) ! maxmove=0
for i=1 to .ns
if .state(i,2)=p then maxmove+=.state(i,1)
next i
maxmove=int(2*maxmove) ! button "maxtr" text maxmove
field "attack" hide ! field "move" show
lna=0 ! lnb=0 ! ntr=0 ! button "troops" text "0"
do slowdown
if bp("strength") then disp_strength()
k=0
for i=1 to .ns ' check state buttons
if bp(str$(i)) then ! k=i ! break! end if
next i
if k=0 then m_label1
e=0
for i=2 to cp.play(1)+1
if k=cp.play(i) then ! e=1 ! break ! end if
next i
if e=0 then continue
if k=lna then
sign_fight(lna,-1) ! lna=0
if lnb>0 then ! sign_fight(lnb,-2) ! lnb=0 ! end if
continue
end if
if k=lnb then ! sign_fight(lnb,-2) ! lnb=0 ! continue ! end if
if lna=0 then ! lna=k ! sign_fight(lna,1) ! continue ! end if
if lnb=0 then
nb=0 ' check neighbour state or not
for j=1 to 6 ! if .link(lna,j)=k then nb=1 ! next j
if nb=0 then continue
lnb=k ! sign_fight(lnb,2)
end if
m_label1:
if lna=0 or lnb=0 then nxt1
lnr=floor(.state(lna,3)) ! if lnr<2 then continue
if bp("less") then
if ntr=0 then ntr=min(lnr-1,maxmove) else ntr-=1
button "troops" text ntr
end if
if bp("more") then
if ntr=maxmove then ntr=0 else ntr=min(lnr-1,ntr+1)
button "troops" text ntr
end if
if bp("okee") then
.state(lna,3)-=ntr ! button lna text floor(.state(lna,3))
.state(lnb,3)+=ntr ! button lnb text floor(.state(lnb,3))
maxmove-=ntr ! ntr=0 ! lna=0 ! lnb=0
button "troops" text "0" ! button "maxtr" text maxmove
end if
nxt1:
until bp("cont")
field "move" hide
end def
def drafty(p)
button "cont" show ! group2(1)
button "strength" show ! field "draft" show
button "troops" text "0" ! button "maxtr" text cp.draft
lnr=0 ! ntr=0
do slowdown
if bp("strength") then disp_strength()
if bp("less") and lnr>0 then
if ntr=0 then ntr=cp.draft else ntr-=1
button "troops" text ntr
end if
if bp("more") and lnr>0 then
if ntr=cp.draft then ntr=0 else ntr+=1
button "troops" text ntr
end if
if bp("okee") and lnr>0 then
.state(lnr,3)+=ntr ! cp.draft-=ntr ! ntr=0
button lnr text floor(.state(lnr,3))
button "troops" text "0" ! button "maxtr" text cp.draft
end if
for i=1 to .ns
if bp(str$(i)) and .state(i,2)=p then
if i=lnr then lnr=0 else lnr=i
end if
next i
until bp("cont")
group2(0) ! field "draft" hide
end def
def exit_player()
end def
def exit_round()
for i=1 to .ns ! .state(i,4)=.9*.state(i,4)+1 ! next i
if bp("strength") then disp_strength()
end def
def attack(na,nd,f)
f=2-cos(0.3142*f) ! nd*=f
q=na/(na+nd) ! q=min(.8,q) ! q=max(.2,q)
if rnd(1)<q then return 1 else return -1
end def
def check_dead(r)
dead=1
for i=1 to .ns
if .state(i,2)=r then ! dead=0 ! break ! end if
next i
if dead then return .cards(r) else return 0
end def
def f_fld(ff$,c$)
if c$="g" then ! field ff$ back color 0,1,0
else ! field ff$ back color 1,0,0
end if
field ff$ font name "MarkerFelt-Thin"
field ff$ font size 30
end def
def sign_state(s,c)
'for i=1 to 5
draw_state(s,7) ! pause .1
draw_state(s,c) ! pause .1
' next i
button s text max(1,int(.state(s,3)))
end def
def sign_fight(i,ind)
if ind>0 then
if ind=1 then t$=chr$(9732) else t$=chr$(57629)
button i text t$
else ! button i text floor(.state(i,3))
end if
end def
def bc(p) ' update cards button
button "cards" text .cards(p)
pause .5
end def
def bp(a$) = button_pressed(a$)
def cp() ! end def
' {risk_lib}
def ai_play()
'
'***** draft phase
p=cp.nr ! field "draft" show
nc=.cards(p) ! ns=cp.play(1)
button "cards" show ! button "cards" text nc ! pause .3
if nc>=3 then
cp.draft+=2*nc+floor(nc/5)-1
.cards(p)-=3
end if
if cp.draft >=1 then
for i=1 to cp.draft
k=(i-1)%ns+2 ! st=cp.play(k) ! .state(st,3)+=1
button st text int(.state(st,3))
next i
cp.draft=0
end if
pause .5 ! field "draft" hide
'
'****** attack phase
dim tab_in(99,3),tab(99,3)
max_attacks=.ai(p,1) ! field "attack" show
start_odds=.ai(p,2) ! stop_odds=.ai(p,3)
won_flag=0 ! ntab=0
for i=2 to ns+1
lnr=cp.play(i) ! n_att=.state(lnr,3)
for j=1 to 6
buur=.link(lnr,j)
if buur=0 or .state(buur,2)=p then continue
n_def=.state(buur,3)
ntab+=1 ! tab_in(ntab,1)=lnr ! tab_in(ntab,2)=buur
tab_in(ntab,3)=n_att/max(n_def,1)
next j
next i
tablesort(ntab,3,tab_in,tab,3)
for i=1 to min(max_attacks,ntab)
if touch_x(0)>-1 then stop
nla=tab(i,1) ! nld=tab(i,2)
d=.state(nld,2) ! if d=p then continue
do
n_att=.state(nla,3) ! n_def=.state(nld,3)
odds=n_att/max(n_def,1)
if odds<start_odds or n_att<=stop_odds then break
v=attack(n_att,n_def,.state(nld,4))
if v=1 then ! won_flag=1 ! .state(nld,3)-=1
else ! .state(nla,3)-=1
end if
sign_state(nla,p) ! sign_state(nld,d)
if .state(nld,3)<1 then
.state(nld,2)=p ! .state(nld,4)=0
dl=max(1,floor(.state(nla,3)/3))
.state(nla,3)-=dl ! .state(nld,3)=dl
sign_state(nla,p) ! sign_state(nld,p)
.cards(p)+=check_dead(d)
break
end if
until forever
next i
if won_flag then
.cards(p)+=1 ! button "cards" text .cards(p) ! pause .3
end if
field "attack" hide
'
'***** move phase
ns=state_count() ! field "move" show
for i=2 to ns+1
dim buren(6)
buur_flag=0 ! bsum=0 ! k=0
lnr=cp.play(i) ! n_c=.state(lnr,3)
for j=1 to 6
b=.link(lnr,j)
if b=0 then break
if .state(b,2)<>p then ! buur_flag=1
else ! k+=1 ! buren(k)=b ! bsum+=.state(b,3)
end if
next j
if k=0 then continue
nb=k ! mu=(n_c+bsum)/(nb+1)
if buur_flag=0 then ! pot=n_c-1
else
if n_c>mu then pot=n_c-mu else pot=0
end if
if pot>0 then ! .state(lnr,3)-=pot ! dp=pot/nb ! end if
for j=1 to nb ! .state(buren(j),3)+=dp ! next j
next i
for i=1 to .ns ! button i text floor(.state(i,3)) ! next i
pause .5 ! field "move" hide
end def
def assign()
dim t(42)
for i=1 to 42 ! t(i)=i ! .state(i,3)=1 ! next i
for i=1 to 7 ! for s=1 to 6
do ! r=1+rnd(42) ! k=t(r) ! until k
.state(k,2)=s ! t(r)=0 ! draw_state(k,s)
next s ! next i
for cp.nr=1 to .npl
state_count()
if .classic and cp.nr=.human then
cp.draft=13 ! p=.human ! init_round()
field "play" back color .col(p,1),.col(p,2),.col(p,3)
drafty(p)
else
for j=1 to 13
k=2+rnd(7) ! .state(cp.play(k),3)+=1
next j
end if
next cp.nr
for i=1 to 42 ! button i text .state(i,3) ! next i
refresh on
end def
def draw_state(k,c)
dim x(11),y(11)
n=.surf(k,1)
fill color .col(c,1),.col(c,2),.col(c,3)
for i=1 to n
p=.surf(k,i+1)
x(i)=.node(p,1) ! y(i)=.node(p,2)
next i
fill poly x,y count n ! draw poly x,y count n
end def
def state_count()
p=cp.nr ! k=1 ! cp.na=0
for i=1 to .ns
if .state(i,2)<>p then continue
k+=1 ! cp.play(k)=i ! cp.na+=.state(i,3)
next i
cp.play(1)=k-1 ! return k-1
end def
def cont_count()
dim check(6) ! bonus=0
for i=2 to cp.ncp+1
for k=1 to 6
if cp.play(i)<=.cont(k,2) then
check(k)+=1 ! break
end if
next k
next i
for i=1 to 6
if check(i)=.cont(i,4) then bonus+=.cont(i,3)
next i
return bonus
end def
def disp_strength()
.sflag=1-.sflag
if .sflag then ! k=4 ! n$="Strength"
else ! k=3 ! n$="Armies"
end if
button("strength") text n$
for i=1 to .ns ! button i text floor(.state(i,k)) ! next i
a=human_play.lna ! if a and k=3 then sign_fight(a,1)
d=human_play.lnd ! if d and k=3 then sign_fight(d,2)
end def
def group1(on)
if on then
field "draft" show ! field "attack" show ! field "move" show
else
field "draft" hide ! field "attack" hide ! field "move" hide
end if
end def
def group2(on)
if on then
button "less" show ! button "more" show ! button "okee" show
button "troops" show ! button "maxtr" show
else
button "less" hide ! button "more" hide ! button "okee" hide
button "troops" hide ! button "maxtr" hide
end if
end def
def group3(on)
if on then
button "datt" show ! button "att" show
button "ddef" show ! button "def" show
button "speed" show ! button "pause" show ! button "stop" show
else
button "datt" hide ! button "att" hide
button "ddef" hide ! button "def" hide
button "speed" hide ! button "pause" hide ! button "stop" hide
end if
end def
def init_risk()
set toolbar off ! option base 1 ! randomize
set orientation landscape
graphics ! graphics clear .7,.7,.7 ! draw color 0,0,0
f$="risk_data" ! file f$ input .np,.ns,.nc ! .npl=6
dim .node(.np,2),.surf(.ns,12),.cont(.nc,4),.state(.ns,4)
dim .col(7,3),.cent(.ns,2),lines(4),.link(.ns,6),cp.play(44)
dim .cards(.npl),.ai(6,3)
.human=1+rnd(6)
' refresh off
for i=1 to 6 ! for j=1 to 3
file f$ input .col(i,j)
next j ! next i
for j=1 to 3 ! .col(7,j)=1 ! next j
for i=1 to .np
file f$ input .node(i,1),.node(i,2)
next i
for i=1 to .ns
file f$ input .surf(i,1)
for j=2 to .surf(i,1)+1
file f$ input .surf(i,j)
next j
file f$ input .cent(i,1),.cent(i,2)
button i text i at .cent(i,1),.cent(i,2) size 28,28
next i
for i=1 to 6
for j=1 to 3 ! file f$ input .cont(i,j) ! next j
.cont(i,4)=.cont(i,2)-.cont(i,1)+1
next i
draw dash 2
for i=1 to 26
file f$ input k,lines(1),lines(2),lines(3),lines(4)
draw line lines(1),lines(2) to lines(3),lines(4)
next i
draw dash 0
for i=1 to .ns
for j=1 to 6 ! file f$ input .link(i,j) ! next j
next i
for i=1 to .ns
file f$ input .state(i,1) ! .state(i,1)/=10
.state(i,4)=0
next i
for i=1 to 6
.ai(i,1)=2+rnd(4) ! .ai(i,2)=.4+0.3*rnd(1) ! .ai(i,3)=3+rnd(3)
next i
set buttons font size 70
button "cont" text chr$(10145) at 840,685 size 70,70
draw size 3 ! draw rect 695,605 to 805,755
field "draft" text " Draft" at 700,610 size 100,40 RO
f_fld("draft","g") ! 'field "draft" hide
field "attack" text " Attack" at 700,660 size 100,40 RO
f_fld("attack","r") ! 'field "attack" hide
field "move" text " Move" at 700,710 size 100,40 RO
f_fld("move","g") ! 'field "move" hide
field "play" text "Player" at 40,450 size 100,80
field "play" font name "MarkerFelt-Thin"
field "play" font size 30
sx=320 ! sy=645 ! sz=50
set buttons custom ! set buttons font size sz
button "less" text chr$(57915) at sx,sy size sz,sz
button "more" text chr$(57914) at sx+2.5*sz+20,sy size sz,sz
button "okee" text chr$(9989) at sx+2.5*sz+20,sy+sz+10 size sz,sz
set buttons font name "Georgia-Bold" ! set buttons font size 30
fill color .7,.7,1
button "troops" text "" at sx+sz+10,sy size 1.5*sz,sz
button "maxtr" text "" at sx+sz+10,sy+sz+10 size 1.5*sz,sz
button "cards" text "" at 580,705 size sz,sz
sx=10 ! sy=705 ! bw=75 ! bh=50
set buttons font name "MarkerFelt-Thin"
fill color .5,.5,.5
button "speed" text "Slow" at sx,sy size bw,bh
button "pause" text "Pause" at sx+bw+10,sy size bw,bh
button "stop" text "Start" at sx+2*bw+20,sy size bw,bh
button "strength" text "Armies" at 360,570 size 120,50
sx=10 ! sy=585
fill color .7,.7,1
set buttons font name "Georgia-Bold"
button "att" text "" at sx,sy+bh+10 size bw,bh
button "datt" text "" at sx,sy size bw,bh
button "def" text "" at sx+bw+10,sy+bh+10 size bw,bh
button "ddef" text "" at sx+bw+10,sy size bw,bh
draw font size 20 ! draw text "Cards" at 575,685
button "cont" hide ! button "cards" hide
button "strength" hide !
group1(0) ! group2(0) ! group3(0)
assign() ' assign states and armies to players
end def
' table sorting function (option base 1 assumed)
' r = number of rows
' c = number of columns
' in(,) = table to be sorted
' out(,) = sorted table
' onc = column to be used for sorting
'
def tablesort (r,c,in(,),out(,),onc)
option sort descending
dim sortcol(r),index(r)
for i=1 to r ! sortcol(i)=in(i,onc) ! next i
sort sortcol as index
for i=1 to r ! for j=1 to c
out(i,j)=in(index(i),j)
next j ! next i
return
end def