Hi again,

Here is Battle Ships, well my variation on it. Very simple array based game for two players. The next message is an AS (Artificial Stupidity) computer opponent.

Works by passing small text files between games via a shared path - ie both games use \\server\share or x:\path etc

If the into animation is too fast, put some SLEEP 1 into the INTRO subroutine, I wrote this on a P100 with Win95...

cj

code:

; Battleships
; Version 1.0
; For Megan and Jochen


break on
$=setascii(on)


$seed=val(substr("@time",7,2)) $seed=$seed+1
do $=rnd(1) $seed=$seed-1 until $seed=0


; Dimension vars
dim $boat[5] ; boat names
dim $name ; players name
dim $nameA[8] ; players name generator array
dim $grid[100] ; 10x10 grid
dim $boatlen[5] ; boat size
dim $boathit[5] ; hit indicators
dim $g dim $gy dim $gx
dim $ship1[7] dim $ship2[7] dim $ship3[7] ; intro graphics


; Setup vars
$boat[0]="Frigate " $boatlen[0]=2
$boat[1]="Submarine " $boatlen[1]=3
$boat[2]="Cruiser " $boatlen[2]=3
$boat[3]="BattleShip" $boatlen[3]=4
$boat[4]="Carrier " $boatlen[4]=5
$name="Player" $last="o" $lose=0
$path="c:\scripts" $random=0


$boathit[0]=0 $boathit[1]=0 $boathit[2]=0 $boathit[3]=0 $boathit[4]=0
$ship1[5]=" \ /" $ship1[6]=" \ /"
$ship2[0]=" _" $ship2[1]=" __|_" $ship2[2]=" | 87 |"
$ship3[5]=" \ \/ \/ / \/. / " $ship3[6]=" \ .\ \ / /. / "
$ship2[3]=" ________|____|________" $ship2[4]=" / ooo -- ooo \"
$ship3[3]=" | / \/ \/ | " $ship3[4]=" | \ /\ / /\ /. | "
$ship2[5]=" [| -- |" $ship2[6]=" x\______________________/"
$ship1[3]="_____|__|___|_____|___|__|____" $ship1[4]="\ 11 . . . . . /"
$ship3[0]=" |\ | | /| "
$ship3[1]=" | \/\| | | |/\/ | " $ship3[2]=" |/ \ \| |/ / | "
$ship1[0]=" |" $ship1[1]=" \ \ __|__ / /"
$ship1[2]=" \_\ | | /_/"


$i=0 do $grid[$i]=9 $i=$i+1 until $i=100


goto MAIN


:intro ; -------------------------------------------------------------------------- intro screen
cls at(12,10) color b+/n "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
; Draw ship and sub
color w/n $y=0 do at(5+$y,17) $ship1[$y] at(16+$y,20) $ship2[$y] $y=$y+1 until $y=7
; move sub
$x=20 do $y=0 do at(16+$y,$x) $ship2[$y] $y=$y+1 until $y=7 $x=$x+1 until $x=30
; shoot
$y=19 do at($y+1,35) " " at(12,35) color b+/n "~" color w/n at($y,35) "!" at(19,35) "_" at(20,35) "o"
at (31-$y,25) " " at(12,25) color b+/n "~" color w/n at(32-$y,25) "o" at(24,79) sleep 1 $y=$y-1 until $y=10
at(21,25) " " at(22,25) "*"
; burn ship
$end=50 gosub burn at(22,25) " "
; Break ship
color w/n $y=0 do at(5+$y,17) $ship3[$y] $y=$y+1 until $y=7
; burn ship
$end=30 gosub burn
; sink ship
color w/n $d=0 do $y=6 at($d+11-$y,17) " " do color w/n at($d+12-$y,17) $ship3[6-$y]
$y=$y-1 until $y=$d $end=10 gosub burn $d=$d+1 until $d=6
; move sub
color w/n $x=30 do $y=0 do at(16+$y,$x) $ship2[$y] $y=$y+1 until $y=7 $x=$x+1 until $x=50
; write title
big color w/n at(0,0) "Battle" ? " Ships" small ? ? ? ? ? "Version 1.0" ? "by cj" ? ? ? "Press any key to begin" get$ cls
return


:burn
$c=0 do $a=rnd(3)+8 $b=rnd(10)+27 $s1=rnd(2)+176 $s2=rnd(2)+176 $s3=rnd(2)+176
$col=rnd(2) if $col=0 color r+/n endif if $col=1 color r/n endif if $col=2 color y+/n endif
at($a,$b) chr($s1) at($a-1,$b-1) chr($s2) at($a-1,$b+1) chr($s3) $c=$c+1 until $c=$end
return


:drawgrid ; -------------------------------------------------------------------------- draw grid


$r=3
do
at($r,3) "³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³"
at($r+1,3) "ÃÄÄÅÄÄÅÄÄÅÄÄÅÄÄÅÄÄÅÄÄÅÄÄÅÄÄÅÄÄ´"
$r=$r+2
until $r=23
at(2,3) "ÚÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄ¿"
at(22,3) "ÀÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÙ"


; If you can't use the bars above, use the following code:
;$a=chr(218) $b=chr(191) $c=chr(192) $d=chr(217) $e=chr(196) $f=chr(179)
;$g=chr(195) $h=chr(180) $i=chr(194) $j=chr(193) $k=chr(197)
;$r=3
;do
; at($r,3) "$f $f $f $f $f $f $f $f $f $f $f"
; at($r+1,3) "$g$e$e$k$e$e$k$e$e$k$e$e$k$e$e$k$e$e$k$e$e$k$e$e$k$e$e$k$e$e$h"
; $r=$r+2
;until $r=23
;at(2,3) "$a$e$e$i$e$e$i$e$e$i$e$e$i$e$e$i$e$e$i$e$e$i$e$e$i$e$e$i$e$e$b"
;at(22,3) "$c$e$e$j$e$e$j$e$e$j$e$e$j$e$e$j$e$e$j$e$e$j$e$e$j$e$e$j$e$e$d"


color w/n
at(1,4) "A B C D E F G H I J"
at(1,4) $i=0 do at(3+2*$i,2) "$i" $i=$i+1 until $i=10


at(2,37) "Battleships"
at(3,37) "Version 1.0"


at(5,37) "Please enter your name :"
$i=0 do $nameA[$i]=" " $i=$i+1 until $i=8
$i=0
do
:wrong
at(5,62+$i) get $a
if $a=chr(13) if $i=0 $name="Chris" endif $i=8 goto leave endif
if $a=chr(8)
if $i>0 $i=$i-1 endif
at(5,62+$i) " "
endif
if ((asc($a)>47) and (asc($a)<58)) or ((asc($a)>64) and (asc($a)<91)) or ((asc($a)>96) and (asc($a)<123))
at(5,62+$i) $a ; Restrictions are because this name will be a filename later.
$nameA[$i]=$a
$name=""
$i=$i+1
else
goto wrong
endif
:leave
until $i=8
$i=0
do
if $nameA[$i]<>" " $name=$name+$nameA[$i] endif
$i=$i+1
until $i=8


at(5,37) " "
at(5,37) "Welcome Commander $name."
color w+/n
at(7,37) "Enter co-ordinates:" color w/n


return


:getXY ; ---------------------------------------------======================================= Get Co-ordinates
$boatname=$boat[$i] $nogo=0
select case $i=0 color b/n case $i=1 color g/n case $i=2 color c/n case $i=3 color m/n case $i=4 color y/n endselect
at(8+$i,37) "$boatname : "


; Get column
:inputcol
if $random=1 $gx=rnd(9) $gy=rnd(9) goto calc endif
if $bad=0
$j=0 do at(3+2*$j,2) " " $j=$j+1 until $j=10
color w+/n at(1,4) ? color w/n
else
color w+/n at(9,62) "ABCDEFGHIJ"
$z=0 do at(10+$z,61) " " $z=$z+1 until $z=10
endif
at(8+$i,41+len($boatname))
flushkb get $c $c=ucase($c)
if $c="Q" goto bye endif
if $c="R" $random=1 $gx=rnd(9) $gy=rnd(9) goto calc else $random=0 endif
if (asc($c)>64) and (asc($c)<75) at(8+$i,41+len($boatname))
"$c"
else goto inputcol
endif


; Get row
:inputrow
if $bad=0
at(1,4) " "
color w+/n $j=0 do at(3+2*$j,2) "$j" $j=$j+1 until $j=10 color w/n
else
at(9,62) " "
color w+/n $z=0 do at(10+$z,61) "$z" $z=$z+1 until $z=10
endif
at(8+$i,42+len($boatname))
flushkb get $r
if $r="q" goto bye endif
if (asc($r)>47) and (asc($r)<58) at(8+$i,42+len($boatname))
"$r"
else goto inputrow
endif


; create Display vars from user input
$gx=asc($c)-65
$gy=asc($r)-48
:calc
$x=(2*$gx)+($gx+4)
$y=(2*$gy)+3
$g=($gy*10)+$gx


; restore colours
if $bad=0
color w/n at(1,4) "A B C D E F G H I J"
color w/n at(1,4) $j=0 do at(3+2*$j,2) "$j" $j=$j+1 until $j=10
else
color w/n at(9,62) "ABCDEFGHIJ"
$z=0 do at(10+$z,61) "$z" $z=$z+1 until $z=10
endif


return


:checkgrid ; ----------------------------------------------------------------------- Check grid
; Check possible starting point
$gn=$grid[$g]
if $gn=9 else at(8+$i,41+len($boatname)) " " $nogo=1 goto out endif


; Get scope
$b=$boatlen[$i]
$by1=9-$b+1 $by2=0+$b-1
;at(23,40) "$$b=$b $$by1=$by1 $$by2=$by2 $$gx=$gx $$gy=$gy "


; Check within scope
$ra="M" $da="P" $la="K" $ua="H"
if $gx>($by1) $ra="" endif
if $gx<($by2) $la="" endif
if $gy>($by1) $da="" endif
if $gy<($by2) $ua="" endif


;Check directions
; First check that this ship will not cross others
$j=1 $c=" " $rc="9" $dc="9" $lc="9" $uc="9"
do
if $ra<>"" $rc=$grid[$g+$j] endif ; right >
if $da<>"" $dc=$grid[$g+($j*10)] endif ; down v
if $la<>"" $lc=$grid[$g-$j] endif ; left <
if $ua<>"" $uc=$grid[$g-($j*10)] endif ; up ^
if $rc<>9 $ra="" endif
if $dc<>9 $da="" endif
if $lc<>9 $la="" endif
if $uc<>9 $ua="" endif
$j=$j+1
until $j=$boatlen[$i]
; $avail is the allowed directions
$avail=$ra+$da+$la+$ua

; If $avail=0 then the ship will not fit in the space
if len($avail)=0
$nogo=1 color r+/n
at(14,37) "Ship will not fit here"
color w/n goto out
else
at(14,37) " "
endif


; Get direction
color w/n at(8+$i,44+len($boatname))


; Display allowed directions only
if $random=0
if $ra<>"" chr(16) " " endif ; >
if $da<>"" chr(31) " " endif ; v
if $la<>"" chr(17) " " endif ; <
if $ua<>"" chr(30) " " endif ; ^
endif
:getway ; -------------------------------------------------------------------------- Get way
if $random=0
get $way
else
$rndch=rnd(3)
if $rndch=0 $way="M" endif
if $rndch=1 $way="P" endif
if $rndch=2 $way="K" endif
if $rndch=3 $way="H" endif
endif
if $way="q" goto bye endif
if instr($avail,$way) else goto getway endif


; Calculate ship size on screen
if ($way="M") or ($way="K") $t=(($boatlen[$i]-1)*3)+2 $k=0 endif ; horizontal
if ($way="P") or ($way="H") $t=($boatlen[$i]*2)-1 $k=0 endif ; vertical


;Choose ship colour
select case $i=0 color b/n case $i=1 color g/n case $i=2 color c/n case $i=3 color m/n case $i=4 color y/n endselect


; Display ship
do
if $way="M" at($y,$x+$k) chr(219) endif ; right
if $way="P" at($y+$k,$x) chr(219) chr(219) endif ; down
if $way="K" at($y,$x-($k-1)) chr(219) endif ; left
if $way="H" at($y-$k,$x) chr(219) chr(219) endif ; up
$k=$k+1
until $k=$t
color w/n

; Update database
$j=0
do
$grid[$g]=$i
if $way="M" $g=$g+1 endif ; right
if $way="P" $g=$g+10 endif ; down
if $way="K" $g=$g-1 endif ; left
if $way="H" $g=$g-10 endif ; up
$j=$j+1
until $j=$boatlen[$i]
:out


return


:debug
; Display GRID database (Debug)
at(13,41) color w/n
$y=0 $d=" "
do
$x=0
do
at(13+$y,41+$x)
$g=($y*10)+$x
if $grid[$g]=9 $grid[$g] else "." endif
$x=$x+1
until $x=10
$y=$y+1
until $y=10
return


:status ; ------------------------------------------------------------------------------ Status check
; Check status of boats and display on screen
$i=0 $lose=1
do
at(8+$i,51)
if $boathit[$i]=0 at(8+$i,51) color g+/n "100%" $lose=0 endif
if ($boathit[$i]>0) and ($boathit[$i]<$boatlen[$i]) $p=100-(($boathit[$i]*100)/$boatlen[$i]) color y+/n "$p% " $lose=0 endif
if $boathit[$i]=$boatlen[$i] color r+/n "Lost" endif
$i=$i+1
until $i=5
color w/n
return


:checkhit
$gn=$grid[$g] $last="o"
if $gn<>9
if $gn<>8 $boathit[$gn]=$boathit[$gn]+1 $last="X" endif
$grid[$g]=8
; Display explosion
color r+/n
else
color w/n
endif
at($y,$x) chr(178) chr(178)
color w/n
return


:badguy
color r+/n
at(7,61) "$badguy"
color w/n
box(8,60,20,72,single)
at(9,62) "ABCDEFGHIJ"
$y=0
do
at(10+$y,61) "$y"
$x=0
do
at(10+$y,62+$x)"."
$x=$x+1
until $x=10
$y=$y+1
until $y=10
return


:blowmeup
$gx=rnd(9) ;$gx=$gx*10 $gx=$gx/10
$gy=rnd(9) ;$gy=$gy*10 $gy=$gy/10
$x=(2*$gx)+($gx+4)
$y=(2*$gy)+3
;at(17,40) "$$x=$x $$y=$y "
;at(18,40) "$$gx=$gx $$gy=$gy "
$g=(10*$gy)+$gx ;at(19,40) "$$g=$g "
gosub checkhit
return


:showbad
if $mark="X" color r+/n else color w+/n endif
at(10+$gy,62+$gx)"$mark"
color w/n
return


:sendattack
$=open(1,"$path\$name.txt",5)


$out=$last+chr(13)+chr(10)
$=writeline(1,$out)


$out=chr($gx+65)+","+chr($gy+48)
$=writeline(1,$out)


$=close(1)
return


:getattack
$r=exist("$path\$badguy.txt")
if $r=0 sleep 1 goto getattack endif
sleep 1
$=open(1,"$path\$badguy.txt")


$in1=readline(1)
if $in1="lose" color g+/n at(17,37) "You Won!" goto bye endif
$in2=readline(1)


$=close(1)
del "$path\$badguy.txt"
return


:gameON
del "$path\$name.txt" ; clean up from previous games
$r=open(1,"$path\game.txt")
if $r=2 ; start new game
$create=1
$=open(1,"$path\game.txt",5)
$=writeline(1,$name)
$=close(1)
:getreply
$r=open(1,"$path\reply.txt")
if $r=2 sleep 1 goto getreply endif
$badguy=readline(1)
$=close(1)
del "$path\reply.txt"
else ; join this game
$create=0
$badguy=readline(1)
$=close(1)
del "$path\game.txt"
$=open(1,"$path\reply.txt",5)
$=writeline(1,$name)
$=close(1)
endif
return


:bye
; Clean up files
$last="lose"
gosub sendattack
del "$path\$badguy.txt"
at(22,0) color w+/n "Bye!" ?
quit


:MAIN ; ============================================================================ Main
gosub intro ; intro screen
gosub drawgrid ; Draw screen
$i=0 $r=" " $c=" " $g=0
do
:getagain
$bad=0
gosub getXY ; Get players ship placements
gosub checkgrid ; Check and place ships
if $nogo=1 goto getagain endif
at(8+$i,41+len($boatname)) " " ; Clean up screen
$i=$i+1
; gosub debug
until $i=5
$random=0
color w+/n at(15,37) "Looking for player"
gosub gameON ; look for a game to join/create


at(7,37) "Ship Status "
gosub badguy ; draw bad guy mini screen


:shoot
gosub status ; update ship status
if $lose=1 $last="lose" gosub sendattack color r+/n at(17,37) "You lost!" goto bye endif


; This code is for self destruct - used in testing
;gosub blowmeup


if $create=0 goto waitnow endif
; Get attack co-ordinates
color w+/n at(15,37) "Enter attack: "
$i=7 $bad=1 $random=0
gosub inputcol
$mark="?"
gosub showbad ; Show ? on bad guy mini screen
color w/n at(15,37) "Processing... "


gosub sendattack ; send attack co-ords to bad guy
:waitnow
$create=1
gosub getattack ; get result of attack and get bad guys attack from bad guy
; $in1 is result of my attack - "o" for miss and "X" for hit
; $in2 is bad guys attack in the form of "A,5" etc
$mark=$in1
gosub showbad ; update bad guy mini screen


;color y+/n at(16,37) "$$in2=$in2 "
$gxc=substr($in2,1,1) $gyc=substr($in2,3,1)
;color y+/n at(17,37) "$$gxc=$gxc $$gyc=$gyc "
$gx=asc($gxc)-65 $gy=asc($gyc)-48
;color y+/n at(18,37) "$$gx=$gx $$gy=$gy "
$x=(2*$gx)+($gx+4) $y=(2*$gy)+3 $g=(10*$gy)+$gx
;color y+/n at(19,37) "$$x=$x $$y=$y $$g=$g "
gosub checkhit ; Check for hit on us and update
goto shoot ; next turn


;END


[This message has been edited by cj (edited 27 June 2000).]