Post by Rod on Dec 2, 2020 15:38:53 GMT
I knew I had coded a Connect4, took a while to find. Being discussed elsewhere so thought this might pass on a few ideas. The AI can undoubtedly be improved.
nomainwin
' find how much whitespace the windows scheme is taking
' Anatoly's tip
WindowWidth = 200
WindowHeight = 200
open "Ajusting..." for graphics_nf_nsb as #1
#1, "home ; down ; posxy w h"
w=200-2*w : h = 200-2*h
close #1
' setup a 520 x 480 graphics view
' the graphic box borders are just outside the window edge
' the playing area is 8x7 60x60 pixels ie 480x420
WindowWidth = 520+w
WindowHeight = 480+h
UpperLeftX = (DisplayWidth-WindowWidth)/2
UpperLeftY = (DisplayHeight-WindowHeight)/2
graphicbox #1.g, 20,20,482,422
open "Connect4" for window_nf as #1
print #1, "trapclose [quit]"
#1.g "down ; font consolas 16 bold"
#1.g "backcolor darkblue ; color white"
'visible drawing coordinates are 0 to 419 ie 420 pixels
'draw our game graphics
r=255
g=128
b=0
For x = 60 to 0 Step -1
#1.g "color ";r;" ";g;" ";x
#1.g "place 0 0 ; box ";x;" ";x
r = r-1
g = g-1
Next
#1.g "place 29 29 ; backcolor white ; circlefilled 24"
#1.g "getbmp whit 0 0 60 60"
r=0
g=128
b=255
#1.g "size 2"
for x=0 to 24
#1.g "color ";r;" ";g;" ";b
#1.g "place 29 29 ; circle ";x
g=g-4
b=b-1
next
#1.g "getbmp blue 0 0 60 60"
r=128
g=255
b=50
for x=0 to 24
#1.g "color ";r;" ";g;" ";b
#1.g "place 29 29 ; circle ";x
g=g-4
r=r-1
next
#1.g "getbmp yell 0 0 60 60"
'draw the board
for x= 0 to 420 step 60
for y= 0 to 360 step 60
#1.g "drawbmp whit ";x;" ";y
next
next
dim c(7,6) '0-7 0-6 8x7 1= human 2= computer 0= free
dim risk(56,4) 'cell risk/value c,r,risk,value
dim d(8,2) 'delta x,y in 8 directions
d(1,1)=1
d(1,2)=0
d(2,1)=1
d(2,2)=1
d(3,1)=0
d(3,2)=1
d(4,1)=-1
d(4,2)=1
d(5,1)=-1
d(5,2)=0
d(6,1)=-1
d(6,2)=-1
d(7,1)=0
d(7,2)=-1
d(8,1)=1
d(8,2)=-1
[human]
#1.g "when leftButtonDown [leftclick]"
wait
'check the column
[leftclick]
c=int(MouseX/60)
if c(c,0)>0 then wait
'find how far we are falling
r=0
while c(c,r)=0 and r<6
#1.g "drawbmp whit ";c*60;" ";(r-1)*60
#1.g "drawbmp blue ";c*60;" ";r*60
timer 56,[go]
wait
[go]
timer 0
r=r+1
wend
if c(c,r)>0 then r=r-1
#1.g "drawbmp whit ";c*60;" ";(r-1)*60
#1.g "drawbmp blue ";c*60;" ";r*60
c(c,r)=1
[computer]
redim risk(1000,4)
plays=0
#1.g "when leftButtonDown"
'check for win, required blocking move, or offensive play
'check each cell and cast a ray in eight directions
for c= 0 to 7
for r= 0 to 6
'is there a token?
if c(c,r)>0 then
'record token color and starting position
token=c(c,r)
dim l(8,4)
for n= 1 to 8
l(n,1)=c 'col
l(n,2)=r 'row
l(n,3)=0 'risk
l(n,4)=0 'reward
next
'cast the ray three steps
for ray= 1 to 3
'in all eight directions
for n=1 to 8
l(n,1)=l(n,1)+d(n,1)
l(n,2)=l(n,2)+d(n,2)
'if we come across a similar token count it
'if we count four (0-3) we have a winner / loser
'if we come across an empty space check if it is playable
'if it is playable record its risk/worth
'is it on the board?
if l(n,1)>=0 and l(n,1)<=7 and l(n,2)>=0 and l(n,2)<=6 then
select case
case c(l(n,1),l(n,2))=1 and token = 1 'risk
l(n,3)=l(n,3)+1
if l(n,3)=3 then notice "Human Wins" : goto [quit]
case c(l(n,1),l(n,2))=2 and token = 2 'reward
l(n,4)=l(n,4)+1
if l(n,4)=3 then notice "Computer Wins" : goto [quit]
case c(l(n,1),l(n,2))=0 'playable?
'are we at the foot of the board or is the slot below taken
if l(n,2)=6 then rowbelow=6 else rowbelow=l(n,2)+1
'is the slot filled or are we at the foot of the board?
if c(l(n,1),rowbelow)>0 or l(n,2)=6 then
'record the risk/worth
risk(plays,1)=l(n,1)
risk(plays,2)=l(n,2)
if token=1 then risk(plays,3)=l(n,3)
if token=2 then risk(plays,4)=l(n,4)
plays=plays+1
end if
end select
end if
next
next
'sort moves on basis of risk/block move required
sort risk(,56,0,3
pc=risk(1,1)
rr=risk(1,3)
'sort moves on basis of reward/win move
sort risk(,56,0,4
'if the reward move is of higher worth take it else take the blocking move
if risk(1,4)>rr then pc=risk(1,1)
'here we need to think about playing the centre of the board, still to do
end if
next
next
c=pc
'find how far we are falling
r=0
while c(c,r)=0 and r<6
#1.g "drawbmp whit ";c*60;" ";(r-1)*60
#1.g "drawbmp yell ";c*60;" ";r*60
r=r+1
timer 56,[g]
wait
[g]
timer 0
wend
if c(c,r)>0 then r=r-1
#1.g "drawbmp whit ";c*60;" ";(r-1)*60
#1.g "drawbmp yell ";c*60;" ";r*60
c(c,r)=2
goto [human]
[quit]
close #1
end