home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d122
/
pushover
/
push_over
< prev
next >
Wrap
Text File
|
1987-12-31
|
11KB
|
493 lines
' Push_Over_16, October 19, 1987 16:48 R. Yost
' With last.mmv table to assure machine does not
' play same move three times in succession.
' With mak.val.tbl reading a file rather'
' than DATA statements.
'
' With machine code get_m_move
'
' "Push-over," Science et Vie, Jeux et Strategies, No. 2, Avril-Mai 1980, p. 7.
'
CLEAR, 25000
CLEAR, 50000&, 8000
WINDOW 1 ,"Push Over Instructions"
PRINT " This is the Game of Push Over. It is played on a 5x5"
PRINT "board. You play the 'white' pieces; I play the red ones. You"
PRINT "play first. The object is to get a row or column or major"
PRINT "diagonal filled with 5 of your pieces. To move, use the cursor"
PRINT "to point to one of the 20 1/2 sized edge starting pads, then"
PRINT "click the left button. Your piece will move onto the board,"
PRINT "pushing any pieces in its way to their neighboring squares."
PRINT ""
PRINT " A move is illegal if it merely cancels the effect of the"
PRINT " preceding opponent's move."
PRINT ""
PRINT " To quit, press the Q key."
PRINT ""
PRINT "Type any key to start the game."
begin:
IF INKEY$ = "" THEN begin
'
SCREEN 2,320,200,2,1
WINDOW 2,"PUSH OVER by R. Yost",,31, 2
DEFINT a-z
DIM b1&(6,6), b0&(6,6),bm1&(6,6), in.play(52)
DIM b.m.tbl&(21)
DIM val.tbl&(2,2,2,2,2)
DIM getmmvcode(1040)
DIM last.mmvs&(1) ' Table used by get_m_move_code.
GOSUB mak.val.tbl
GOSUB get.piece.shapes
GOSUB get.getmmvcode
'
start.game:
CLS: OBJECT.OFF
'
' close game piece objects
'
FOR p = 1 TO 52
IF in.play(p) THEN
OBJECT.CLOSE p
END IF
NEXT p
'
' Initialize arrays
'
FOR i=0 TO 6: FOR j=0 TO 6
b1&(i,j)=0
b0&(i,j)=0
bm1&(i,j)=0
NEXT j,i
FOR i=0 TO 52
in.play(i)=0
NEXT i
'
FOR i = 0 TO 1
last.mmvs&(i) = 0 ' An impossible move, so machine moves
' avoid repeating it.
NEXT i
'
last.mmv&=25 ' An impossible move, so machine moves wont
' avoid repeating it.
'
x0 = 85: y0 = 25: sqsize = 25 : hsqsz=INT(sqsize/2)
speed = 32
'
RANDOMIZE TIMER
'
main:
ON MOUSE GOSUB move.loop
CALL draw.board(x0, y0, sqsize)
main.loop:
MOUSE ON
LOCATE 1,1: PRINT "Your turn: ": LOCATE 1,1
SLEEP
IF UCASE$(INKEY$)="Q" THEN
IF err.flg& THEN
PRINT"You lose. "
ELSE
PRINT"Quitting ? "
END IF
GOTO wrap.up
END IF
GOTO main.loop
END
'
move.loop:
MOUSE OFF
GOSUB get.h.move
GOSUB get.pc.id
IF err.flg& THEN GOSUB bad.move: RETURN
mvp= 0: ' Don't move pieces.
CALL move.vector( move, new.pc.id, mvp, bm1&(), b0&(), b1&())
IF err.flg& THEN GOSUB bad.move: RETURN
mvp = -1: ' now moving pieces
CALL move.vector ( move, new.pc.id, mvp, bm1&(), b0&(), b1&())
GOSUB score
m.turn:
MOUSE OFF
GOSUB get.m.move
GOSUB get.pc.id
' mvp = 0
' illegal = 0
' CALL move.vector(move, new.pc.id, mvp, bm1&(), b0&(), b1&())
' IF err.flg& THEN illegal = move: GOTO m.turn
mvp = -1
CALL move.vector( move, new.pc.id, mvp, bm1&(), b0&(), b1&())
GOSUB score
RETURN
'
bad.move:LOCATE 1,1
PRINT"Bad move; try again.": LOCATE 1,1
delay.t = 1: GOSUB delay
PRINT STRING$(30,32): LOCATE 1,1
RETURN
'
' get human move number 1..20
'
get.h.move:
pc.color = 202: ' white
err.flg& = 0
WHILE MOUSE(0)<>0
WEND
xms=MOUSE(1): yms=MOUSE(2)
IF (xms>x0) AND (xms<x0+5*sqsize) THEN
IF (yms>y0-hsqsz) AND (yms<y0) THEN
move = INT((xms-x0)/sqsize+1)
ELSEIF ((yms>y0+5*sqsize) AND (yms < y0+5*sqsize+hsqsz) ) THEN
move = INT((xms-x0)/sqsize + 6)
ELSE
err.flg& = -1
END IF
ELSEIF ((xms>x0-hsqsz) AND (xms<x0)) THEN
IF (yms>y0) AND (yms<y0+5*sqsize) THEN
move = INT( (yms-y0)/sqsize + 11)
ELSE
err.flg& = -1
END IF
ELSEIF ((xms>x0+5*sqsize) AND (xms<x0+5*sqsize+hsqsz)) THEN
IF (yms>y0) AND (yms<y0 + 5*sqsize) THEN
move = INT((yms-y0)/sqsize + 16 )
ELSE
err.flg& = -1
END IF
ELSE
err.flg& = -1
END IF
RETURN
'
get.pc.id:
IF err.flg& = 0 THEN
'
' get new.pc.id
'
new.pc.id = pc.color - 200
WHILE in.play(new.pc.id)<>0
new.pc.id = new.pc.id + 2
WEND
OBJECT.SHAPE new.pc.id, pc.color
in.play(new.pc.id)=-1 : ' true
END IF
LOCATE 1,1
PRINT STRING$(30,32): LOCATE 1,1
RETURN
'
SUB draw.board( x0,y0, bx ) STATIC
FOR x=x0 TO x0+2*bx STEP bx
LINE(x,y0-bx/2)-STEP(3*bx,6*bx),3,b
NEXT x
FOR y=y0 TO y0+2*bx STEP bx
LINE(x0-bx/2,y)-STEP(6*bx,3*bx),3,b
NEXT y
END SUB
'
get.piece.shapes:
'
' CHDIR"push_over:pshovr"
OPEN "WHTOKEN" FOR INPUT AS 4
OPEN "BLKTOKEN" FOR INPUT AS 5
OBJECT.SHAPE 202, INPUT$(LOF(4),4)
OBJECT.SHAPE 201, INPUT$(LOF(5),5)
CLOSE 4,5
RETURN
'
get.getmmvcode:
OPEN "getmmovcode" FOR INPUT AS 6
i = 0
WHILE NOT EOF(6)
INPUT# 6, getmmvcode(i)
i = i+1
WEND
CLOSE 6
RETURN
'
SUB move.vector (mov,npcid,moving.pieces, bm1&(2), b0&(2), b1&(2)) STATIC : ' move.number, pc.color
DEFINT a-z
SHARED sqsize, x0, y0, speed ,in.play(), hsqsz
SHARED err.flg&
xb0=x0-5: yb0 = y0+4: ' Offsets for objects
spcid=npcid
IF (spcid AND 1)<>0 THEN
spcid = -spcid
END IF
IF NOT moving.pieces THEN
brd.move.type = 1
GOSUB move.brds
GOSUB make.move
'
' Check if new board same as board
' before previous move.
'
same=-1
FOR i=1 TO 5: FOR j=1 TO 5
IF ( SGN(b1&(i,j))<>SGN(bm1&(i,j))) THEN same=0: i=5: j=5
NEXT j,i
IF same THEN err.flg& = -1
ELSE
brd.move.type=1
GOSUB move.brds
GOSUB make.move
brd.move.type=2
GOSUB move.brds
END IF
EXIT SUB
'
make.move:
IF mov<6 THEN
mv = mov
xstrt=xb0+mv*sqsize-hsqsz
ystrt=yb0-hsqsz
row.new = 0: col.new = mv
step.size= 1
GOSUB move.col
ELSEIF mov>5 AND mov < 11 THEN
mv = mov-5
xstrt=xb0+mv*sqsize-hsqsz
ystrt=yb0+5*sqsize+hsqsz+1
step.size = -1
row.new = 6: col.new = mv
GOSUB move.col
ELSEIF mov>10 AND mov<16 THEN
mv=mov-10
xstrt=xb0-hsqsz
ystrt=yb0+mv*sqsize-hsqsz
row.new=mv: col.new=0
step.size=1
GOSUB move.row
ELSE
mv=mov-15
xstrt=xb0+5*sqsize+hsqsz
ystrt=yb0+mv*sqsize-hsqsz
row.new=mv: col.new=6
step.size= -1
GOSUB move.row
END IF
RETURN
'
move.brds:
FOR i=0 TO 6: FOR j=0 TO 6
ON brd.move.type GOSUB move1, move2
NEXT j,i
RETURN
'
move1:
b1&(i,j)=b0&(i,j)
RETURN
'
move2:
bm1&(i,j)=b0&(i,j)
b0&(i,j)=b1&(i,j)
RETURN
'
move.col:
IF moving.pieces THEN
OBJECT.X npcid, xstrt
OBJECT.Y npcid, ystrt
OBJECT.ON npcid
END IF
b1&(row.new,col.new)= spcid
row.n = row.new
WHILE b1&(row.n,col.new)<>0
row.n = row.n+step.size
WEND
' row.n now points to empty square,
' possibly row 6, off board.
FOR row=row.n TO row.new + step.size STEP -1*step.size
b1&(row,col.new)=b1&(row-step.size,col.new)
IF moving.pieces THEN
OBJECT.VY ABS(b1&(row-step.size,col.new)), step.size*speed
END IF
NEXT row
'
' now, move pieces in vector
'
IF moving.pieces THEN
OBJECT.START
keep.moving:
OBJECT.START
ydis = ABS(OBJECT.Y(npcid) - ystrt)
IF ydis < sqsize THEN keep.moving
OBJECT.STOP
OBJECT.STOP ' Make sure they stop!
'
' reset velocities to zero.
'
FOR row = row.new+step.size TO row.n STEP step.size
OBJECT.VY ABS(b1&(row,col.new)),0
NEXT row
'
' Discard piece pushed off board.
'
IF row.n = 6-row.new THEN
OBJECT.OFF ABS(b1&(6-row.new,col.new))
in.play(ABS(b1&(6-row.new,col.new)))=0
END IF
END IF
'
' Clear edges.
'
b1&(0,col.new)=0
b1&(6,col.new)=0
'
' Vector moved.
RETURN
'
move.row:
IF moving.pieces THEN
OBJECT.Y npcid, ystrt
OBJECT.X npcid, xstrt
OBJECT.ON npcid
END IF
b1&(row.new,col.new)=spcid
col.n = col.new
WHILE b1&(row.new,col.n)<>0
col.n = col.n + step.size
WEND
'
FOR col = col.n TO col.new+step.size STEP -1*step.size
b1&(row.new,col)=b1&(row.new,col-step.size)
IF moving.pieces THEN
OBJECT.VX ABS(b1&(row.new,col-step.size)), step.size*speed
END IF
NEXT col
'
IF moving.pieces THEN
keep.sliding:
OBJECT.START
xdis = ABS(OBJECT.X(npcid) - xstrt)
IF xdis < sqsize-1 THEN keep.sliding
OBJECT.STOP
OBJECT.STOP ' Make sure they stop!
'
FOR col = col.new+step.size TO col.n STEP step.size
OBJECT.VX ABS(b1&(row.new,col)), 0
NEXT col
IF col.n = 6 - col.new THEN
OBJECT.OFF ABS(b1&(row.new, 6-col.new))
in.play(ABS(b1&(row.new,6-col.new))) = 0
END IF
END IF
b1&(row.new,6)=0
b1&(row.new,0)=0
RETURN
END SUB
'
' Win evaluator; returns result
' in variable "win"
'
SUB win.eval(brd&(2),pc,win) STATIC
DEFINT a-z
win = 0: win.diag1 = -1: win.diag2 = -1
FOR i=1 TO UBOUND(brd&,1)-1
ON pc GOSUB test.diags.blk, test.diags.wht
win.row = -1: win.col = -1
FOR j=1 TO UBOUND(brd&,2)-1
ON pc GOSUB test.blk, test.wht
NEXT j
win = win OR (win.row OR win.col)
IF win THEN EXIT SUB
NEXT i
win = win OR (win.diag1 OR win.diag2)
EXIT SUB
'
subroutines
'
test.diags.blk:
IF brd&(i,i) >=0 THEN win.diag1 = 0
IF brd&(i,6-i) >=0 THEN win.diag2=0
RETURN
'
test.diags.wht:
IF brd&(i,i) <=0 THEN win.diag1 = 0
IF brd&(i,6-i) <=0 THEN win.diag2=0
RETURN
'
test.blk:
IF brd&(i,j) >=0 THEN win.row = 0
IF brd&(j,i) >=0 THEN win.col = 0
RETURN
'
test.wht:
IF brd&(i,j) <=0 THEN win.row = 0
IF brd&(j,i) <=0 THEN win.col = 0
RETURN
'
END SUB
'
' subroutine score detects wins and
' announces results and offers new
' game or ends.
'
score:
CALL win.eval(b1&(),1,win.blk)
CALL win.eval(b1&(),2,win.wht)
IF (win.wht AND win.blk) THEN
PRINT"A Tie. ": LOCATE 1,1
GOTO wrap.up
ELSEIF win.wht THEN
PRINT"You WIN! ": LOCATE 1,1
GOTO wrap.up
ELSEIF win.blk THEN
PRINT"I win! ": LOCATE 1,1
GOTO wrap.up
END IF
RETURN
'
wrap.up:
delay.t = 1: GOSUB delay
PRINT"New Game?";
w.u.loop:
a$=INKEY$
IF a$="" THEN w.u.loop
OBJECT.OFF
IF (a$="y" OR a$="Y") THEN start.game
SCREEN CLOSE 2
WINDOW CLOSE 2
CLS
END
'
delay:
FOR i=1 TO 250*delay.t: q=SIN(.5):NEXT
RETURN
mak.val.tbl:
OPEN "val.tbl.file" FOR INPUT AS #10
FOR i = 0 TO 2
FOR j = 0 TO 2
FOR k = 0 TO 2
FOR l = 0 TO 2
FOR m = 0 TO 2
INPUT# 10, val.tbl&(i,j,k,l,m)
NEXT m,l,k,j,i
CLOSE 10
RETURN
'
'
get.m.move:
PRINT "Please wait a moment."
LOCATE 1,1
getmmv& = VARPTR(getmmvcode(0))
CALL getmmv&(VARPTR(val.tbl&(0,0,0,0,0)),VARPTR(bm1&(0,0)), VARPTR(b0&(0,0)), VARPTR(b.m.tbl&(0)), VARPTR(last.mmv&), VARPTR(last.mmvs&(0)) )
move = b.m.tbl&(INT(1+(b.m.tbl&(0)-1)*RND))
last.mmv& = move
pc.color = 201
err.flg& = 0
PRINT "OK, here's my move. " : LOCATE 1,1
delay.t = 1 : GOSUB delay
RETURN
'
SUB dmp( brd(2) ) STATIC
FOR i = 1 TO 5
PRINT ""
FOR j = 1 TO 5
PRINT brd(i,j);
NEXT j
NEXT i
END SUB