Code:
' Defipong v0.1 by Zyx coded in QB45 july 2003
' Use V to switch between automatic mode and manual mode
' + and - to adjust display speed
' 2,4,6,8 to move the paddle in Manual mode
' P to pause
' ESC to quit
'---------------------- CONSTANTS ----------------------
' Choose you language here:
'CONST LANGUAGE = "ENGLISH"
CONST LANGUAGE = "FRENCH"
'CONST LANGUAGE = "SPANISH"
'step of paddles when they move (in pixel):
CONST PADDLESTEP = 20
' moves between each instruction of the script:
CONST MOVES = 10
' ball will bounce accordingly to distance from the center of the paddle
' the lower the value the greater the effect
CONST EFFECTPADDLE = 2000
' moving paddle will accelerate the ball
' the lower the value the greater the effect
CONST IMPULSEPADDLE = 10000
' ball will accelerate with time
' the lower the value the greater the effect
CONST ACCELERATION = 2000
'HALF-width of the padle:
CONST PADDLEWIDTH = 25
'---------------------- INITIALIZATION SUBS ----------------------
DECLARE SUB init ()
DECLARE SUB new.game ()
DECLARE SUB new.set ()
DECLARE SUB load.robots ()
'---------------------- ENGINE SUBS ----------------------
DECLARE SUB show.rules.english ()
DECLARE SUB show.rules.french ()
DECLARE SUB show.rules.spanish ()
DECLARE SUB show.info ()
DECLARE SUB show.ball ()
DECLARE SUB move.ball ()
DECLARE SUB move.paddle (numero AS INTEGER)
DECLARE SUB check.collision ()
DECLARE SUB check.limits.paddle ()
DECLARE SUB check.limits.ball ()
DECLARE SUB check.keyboard ()
DECLARE SUB win ()
'---------------------- SCRIPT SUBS ----------------------
DECLARE SUB execute.script ()
DECLARE SUB parser.ifthen ()
DECLARE SUB parser.myvariable ()
DECLARE FUNCTION calculate (paratexte AS STRING)
DECLARE FUNCTION operateur$ (paratexte2 AS STRING, op AS STRING)
DECLARE SUB replace.litterals ()
DECLARE SUB remplace (old AS STRING, new AS LONG)
'declarations
'---------------------- PADDLES ----------------------
' paddle coordinates
DIM SHARED x(2) AS SINGLE, y(2) AS SINGLE
'paddle aimed coordinates
DIM SHARED xobj(2) AS INTEGER, yobj(2) AS INTEGER
'---------------------- BALL ----------------------
' ball coordinates
DIM SHARED xball AS SINGLE, yball AS SINGLE
' ball direction
DIM SHARED xxball AS SINGLE, yyball AS SINGLE
' provisory ball coordinates
DIM SHARED xtmp AS SINGLE, ytmp AS SINGLE
'---------------------- ROBOTS ----------------------
' scripts (litteral)
REDIM SHARED script(2, 1) AS STRING
' scripts (interpreted)
REDIM SHARED command(2, 1) AS INTEGER
' size of scripts (and of paddle)
DIM SHARED taille(2) AS INTEGER
' current instruction
DIM SHARED ligne(2) AS INTEGER
' internal variable used for the script
DIM SHARED myvariable(2) AS LONG
' score of robots
DIM SHARED score(2) AS INTEGER
' number of the robot (used to look for in Robot#.txt)
DIM SHARED robnum(2) AS INTEGER
'---------------------- VARIABLES FOR SCRIPT ----------------------
' if the paddle is horizontally in front of the ball (0=wrong,-1=true)
DIM SHARED Enfacedelaballe AS INTEGER
'---------------------- GAME VARIABLES ----------------------
' current set
DIM SHARED manche AS INTEGER
' delay between each loop
DIM SHARED vitesse AS INTEGER
' current mode: 1=player vs robot 2=robot vs robot
DIM SHARED manualmode AS INTEGER
' time of play and acceleration
DIM SHARED compteur AS INTEGER
'---------------------- PARSER VARIABLES ----------------------
DIM SHARED texte AS STRING, test AS STRING
'---------------------- FLAGS and DUMMY VARIABLES ----------------------
DIM SHARED a AS INTEGER, B AS INTEGER
' set to 1 for debugging
DIM SHARED debug AS INTEGER
debug = 0
'------------------------------------------------------------------
' MAIN:
new.game
timer1 = TIMER
DO
check.keyboard
'robots
FOR a = 1 TO 2
execute.script
check.limits.paddle
NEXT
'will executes all the MOVES before next order
DO
'delay
'(vitesse=1 will limit the speed of the ball to MOVES*100 pixels/second)
IF TIMER - timer1 >= vitesse / 100 THEN
timer1 = TIMER
move.ball
check.collision
FOR B = 1 TO 2: move.paddle (B): NEXT
check.collision
show.ball
'ball coordinates are now definitive
xball = xtmp
yball = ytmp
END IF
'acceleration
compteur = compteur + 1
IF compteur MOD MOVES = 0 THEN EXIT DO
IF compteur > ACCELERATION THEN
compteur = 0
xxball = xxball * 1.1
yyball = yyball * 1.1
check.limits.ball
END IF
LOOP
LOOP
FUNCTION calculate (paratexte AS STRING)
' calculate the numeric value of a string
DIM ptexte AS STRING
ptexte = paratexte
' First look for ()
DO
paren1 = 0 'last (
paren2 = 0 'first )
FOR e = 1 TO LEN(ptexte)
IF MID$(ptexte, e, 1) = "(" THEN paren1 = e
IF MID$(ptexte, e, 1) = ")" THEN paren2 = e: EXIT FOR
NEXT
IF paren1 > 0 THEN
ptexte = LEFT$(ptexte, paren1 - 1) + LTRIM$(STR$(calculate(MID$(ptexte, paren1 + 1, paren2 - paren1 - 1)))) + MID$(ptexte, paren2 + 1)
ELSE
EXIT DO
END IF
LOOP
'now evaluate the operands and operators
ptexte = operateur$(ptexte, "*")
ptexte = operateur$(ptexte, "/")
ptexte = operateur$(ptexte, "MOD")
ptexte = operateur$(ptexte, "+")
ptexte = operateur$(ptexte, "-")
result = VAL(ptexte)
'truncating
'calculate = FIX(result + .99999 * SGN(result))
calculate = FIX(result)
END FUNCTION
SUB check.collision
'checks if the ball collides with a paddle
DIM dify AS INTEGER, difx AS INTEGER
FOR B = 1 TO 2
'relative coordinates between ball and paddle
dify = ytmp - y(B)
difx = xtmp - x(B)
'dify>0 if paddle lower than ball
'dify<0 if paddle upper than ball
'difx>0 if paddle to the left of the ball
'difx>0 if paddle to the right of the ball
'impulse
impulsex = (xobj(B) - x(B)) / IMPULSEPADDLE
impulsey = (yobj(B) - y(B)) / IMPULSEPADDLE
'collision
IF ABS(dify) < 3 + taille(B) / 2 THEN
IF ABS(difx) < 3 + PADDLEWIDTH THEN
'type of bouncing
SELECT CASE ABS(difx)
'the ball hit the horizontal edge
CASE IS < 2 + PADDLEWIDTH
'vertical rebond + some x angle
yyball = ABS(yyball) * SGN(dify) + impulsey
xxball = xxball + difx / EFFECTPADDLE
' the ball hit the extremity
CASE IS = 2 + PADDLEWIDTH
'have to check the vertical edge
SELECT CASE ABS(dify)
'extremity too: the ball hit the corner!
CASE 2 + taille(B) / 2
' *TO DO*
'the ball hit the vertical edge normally
CASE ELSE
'horizontal rebond + some y angle
xxball = ABS(xxball) * SGN(difx) + impulsex
yyball = yyball + dify / EFFECTPADDLE
END SELECT
END SELECT
'new position of the ball:
DO WHILE ABS(y(B) - ytmp) < 3 + taille(B) / 2 AND ABS(x(B) - xtmp) < 3 + PADDLEWIDTH
xtmp = xtmp + xxball
ytmp = ytmp + yyball
LOOP
check.limits.ball
END IF
END IF
NEXT
END SUB
SUB check.keyboard
k$ = INKEY$
IF k$ > "" THEN
SELECT CASE UCASE$(k$)
CASE "+"
vitesse = vitesse + 1
CASE "-"
vitesse = vitesse - 1
CASE " " 'new game
new.game
CASE CHR$(27)
END
CASE "4"
IF manualmode = 1 THEN xobj(2) = x(2) - PADDLESTEP
CASE "6"
IF manualmode = 1 THEN xobj(2) = x(2) + PADDLESTEP
CASE "2"
IF manualmode = 1 THEN yobj(2) = y(2) + PADDLESTEP / 2
CASE "8"
IF manualmode = 1 THEN yobj(2) = y(2) - PADDLESTEP / 2
CASE "D"
debug = 1 - debug
CASE "P"
SLEEP
CASE "V"
manualmode = 3 - manualmode
END SELECT
IF vitesse < 0 THEN vitesse = 0
IF vitesse > 100 THEN vitesse = 100
show.info
END IF
END SUB
SUB check.limits.ball
' check a collision with the walls
'left and right walls
IF xtmp < 3 OR xtmp > 557 THEN
xtmp = xball
xxball = -xxball
END IF
'upper and lower walls
IF ytmp < 3 OR ytmp > 457 THEN
IF ytmp < 3 THEN score(2) = score(2) + 1 ELSE score(1) = score(1) + 1
ytmp = yball
yyball = -yyball
win
END IF
' check that the movement stays UNDER 1 pixel/frame
IF ABS(xxball) > 1 THEN yyball = yyball / ABS(xxball): xxball = SGN(xxball)
IF ABS(yyball) > 1 THEN xxball = xxball / ABS(yyball): yyball = SGN(yyball)
END SUB
SUB check.limits.paddle
' check that the paddle stays in its zone
IF xobj(a) < 1 + PADDLEWIDTH THEN xobj(a) = 1 + PADDLEWIDTH
IF xobj(a) > 560 - 1 - PADDLEWIDTH THEN xobj(a) = 560 - 1 - PADDLEWIDTH
IF a = 1 THEN
IF yobj(a) > 201 - taille(a) / 2 THEN yobj(a) = 201 - taille(a) / 2
IF yobj(a) < 1 + taille(a) / 2 THEN yobj(a) = 1 + taille(a) / 2
ELSE
IF yobj(a) < 259 - taille(a) / 2 THEN yobj(a) = 259 - taille(a) / 2
IF yobj(a) > 459 - taille(a) / 2 THEN yobj(a) = 459 - taille(a) / 2
END IF
END SUB
SUB execute.script
' execute the current instruction of the robot
'unselect previous instruction
COLOR a
IF ligne(a) < 30 THEN
IF a = 1 THEN LOCATE ligne(a) + 1, 72 ELSE LOCATE ligne(a) + 1, 77
PRINT LEFT$(script(a, ligne(a)), 4)
END IF
IF a > manualmode THEN EXIT SUB
SELECT CASE command(a, ligne(a))
CASE 0 'wait
xobj(a) = x(a): yobj(a) = y(a)
CASE 1 'left
xobj(a) = xobj(a) - PADDLESTEP
CASE 2 'right
xobj(a) = xobj(a) + PADDLESTEP
CASE 3 'front
IF a = 1 THEN yobj(a) = yobj(a) + PADDLESTEP ELSE yobj(a) = yobj(a) - PADDLESTEP
CASE 4 'back
IF a = 1 THEN yobj(a) = yobj(a) - PADDLESTEP ELSE yobj(a) = yobj(a) + PADDLESTEP
CASE 5 'goto
ligne(a) = VAL(MID$(script(a, ligne(a)), 5)) - 1
CASE 6 'if then goto
parser.ifthen
CASE 7 'set myvariable
parser.myvariable
CASE ELSE
STOP
END SELECT
'next instruction
ligne(a) = ligne(a) MOD taille(a) + 1
'select it
COLOR 4
IF ligne(a) < 30 THEN
IF a = 1 THEN LOCATE ligne(a) + 1, 72 ELSE LOCATE ligne(a) + 1, 77
PRINT LEFT$(script(a, ligne(a)), 4)
END IF
END SUB
SUB load.robots
'open robot1.txt and robot2.txt and memorize the script
DIM order AS STRING
' check the maximum size of the scripts
'------------------------------------------------------------
FOR a = 1 TO 2
k$ = "robot" + LTRIM$(STR$(robnum(a))) + ".txt"
OPEN k$ FOR INPUT AS #1
DO WHILE NOT EOF(1)
LINE INPUT #1, order
order = LTRIM$(order)
IF LEFT$(order, 1) <> ";" AND order > "" THEN taille(a) = taille(a) + 1
LOOP
CLOSE #1
NEXT
' dimension the arrays according to the maximum size
IF taille(1) > taille(2) THEN
REDIM script(1, taille(1)), command(1, taille(1))
REDIM script(2, taille(1)), command(2, taille(1))
ELSE
REDIM script(1, taille(2)), command(1, taille(2))
REDIM script(2, taille(2)), command(2, taille(2))
END IF
taille(1) = 0
taille(2) = 0
' Now read and memorize the scripts!
'------------------------------------------------------------
FOR a = 1 TO 2
k$ = "robot" + LTRIM$(STR$(robnum(a))) + ".txt"
OPEN k$ FOR INPUT AS #1
DO WHILE NOT EOF(1)
LINE INPUT #1, order
order = LTRIM$(order)
IF LEFT$(order, 1) <> ";" AND order > "" THEN
taille(a) = taille(a) + 1
script(a, taille(a)) = order
'Translate the command to a number
SELECT CASE LEFT$(UCASE$(order), 3)
CASE "WAI"
command(a, taille(a)) = 0
CASE "LEF"
command(a, taille(a)) = 1
CASE "RIG"
command(a, taille(a)) = 2
CASE "FRO"
command(a, taille(a)) = 3
CASE "BAC"
command(a, taille(a)) = 4
CASE "GOT"
command(a, taille(a)) = 5
CASE "IF "
command(a, taille(a)) = 6
CASE "SET"
command(a, taille(a)) = 7
CASE ELSE 'error: unknown command
PRINT LEFT$(UCASE$(order), 3)
STOP
END SELECT
END IF
LOOP
CLOSE #1
NEXT
END SUB
SUB move.ball
xtmp = xball + xxball
ytmp = yball + yyball
check.limits.ball
'*TO DO* later I'll add a trail here
END SUB
SUB move.paddle (numero AS INTEGER)
'moves and displays the paddles
DIM dirx AS SINGLE, diry AS SINGLE, stepping AS SINGLE
' direction
dirx = INT(xobj(numero) - x(numero))
diry = INT(yobj(numero) - y(numero))
IF dirx = 0 AND diry = 0 THEN EXIT SUB
'I normalize to a step of .5 pixel maximum
IF ABS(dirx) > ABS(diry) THEN
IF ABS(dirx) > 2 * PADDLESTEP THEN stepping = 2 ELSE stepping = 4 * PADDLESTEP / ABS(dirx)
diry = diry / ABS(dirx) / stepping
dirx = SGN(dirx) / stepping
ELSE
IF ABS(diry) > 2 * PADDLESTEP THEN stepping = 2 ELSE stepping = 4 * PADDLESTEP / ABS(diry)
dirx = dirx / ABS(diry) / stepping
diry = SGN(diry) / stepping
END IF
'display the paddle
' size/2 up, size/2 down
LINE (x(numero) - PADDLEWIDTH, y(numero) - taille(numero) / 2)-(x(numero) + PADDLEWIDTH, y(numero) + taille(numero) / 2), 0, BF
x(numero) = x(numero) + dirx
y(numero) = y(numero) + diry
LINE (x(numero) - PADDLEWIDTH, y(numero) - taille(numero) / 2)-(x(numero) + PADDLEWIDTH, y(numero) + taille(numero) / 2), numero, BF
END SUB
SUB new.game
SCREEN 12
SELECT CASE LANGUAGE
CASE "FRENCH"
show.rules.french
CASE "ENGLISH"
show.rules.english
CASE "SPANISH"
show.rules.spanish
CASE ELSE
STOP
END SELECT
'I set a command by default
script(1, 1) = "WAIT": command(1, 1) = 0
script(2, 1) = "WAIT": command(2, 1) = 0
load.robots
'delay by default
vitesse = 0
'by default, Robot vs Robot
manualmode = 2
score(1) = 0: score(1) = 0
manche = 0
new.set
END SUB
SUB new.set
'game is stopped, ready for service
' redraw of the screen
CLS
LINE (0, 0)-(560, 460), 4, B 'je laisse 4 caractÅ res de chaque câtâ
'paddles in position
x(1) = 280: x(2) = 280
y(1) = 20: y(2) = 440
'I force a slight move to ensure display
xobj(1) = 279: xobj(2) = 279
yobj(1) = 20: yobj(2) = 440
manche = manche + 1
ligne(1) = 0
ligne(2) = 0
' ball in position
xball = 275
xxball = -.1
vball = 1
IF manche MOD 2 = 0 THEN 'service player 1
yball = 26 + taille(1) / 2
yyball = .05
ELSE 'service player 2
yball = 434 - taille(2) / 2
yyball = -.05
END IF
xtmp = xball: ytmp = yball
show.info
' I show the 29 first lines of script
LOCATE 1, 72: COLOR 1
PRINT "Up"
FOR a = 1 TO taille(1)
LOCATE a + 1, 72
PRINT LEFT$(script(1, a), 4)
IF taille(1) > 29 THEN EXIT FOR
NEXT a
LOCATE 1, 77: COLOR 2
PRINT "Down"
FOR a = 1 TO taille(2)
LOCATE a + 1, 77
PRINT LEFT$(script(2, a), 4)
IF taille(2) > 29 THEN EXIT FOR
NEXT a
'display ball and paddles
show.ball
FOR B = 1 TO 2: move.paddle (B): NEXT
k$ = INKEY$: DO WHILE k$ = "": k$ = INKEY$: LOOP
END SUB
FUNCTION operateur$ (paratexte2 AS STRING, op AS STRING)
'identify operands for a given operator (op) and calculate the operation
DIM ptexte2 AS STRING, calcul AS SINGLE
ptexte2 = paratexte2
FOR f = 1 TO LEN(ptexte2)
' look for the operator
IF MID$(ptexte2, f, LEN(op)) = op THEN
'left operand: first character must be 0-9 or . or -
gauche = 0
DO
gauche = gauche + 1
IF f - gauche < 1 THEN EXIT DO
k$ = MID$(ptexte2, f - gauche, 1)
'include the minus sign
IF ASC(k$) = 45 THEN gauche = gauche + 1
IF k$ = "" OR ASC(k$) = 47 OR ASC(k$) < 46 OR ASC(k$) > 57 THEN EXIT DO
LOOP
gauche = gauche - 1
'right operand: last character must be 0-9 or .
droite = 1
DO
droite = droite + 1
IF f + LEN(op) + droite > LEN(ptexte2) THEN droite = droite + 1: EXIT DO
k$ = MID$(ptexte2, f + LEN(op) + droite - 1, 1)
IF k$ = "" OR ASC(k$) = 47 OR ASC(k$) < 46 OR ASC(k$) > 57 THEN EXIT DO
LOOP
droite = droite - 1
'value of each operand
valeur1 = VAL(MID$(ptexte2, f - gauche, gauche))
valeur2 = VAL(MID$(ptexte2, f + LEN(op), droite + 1))
'execute the operation
SELECT CASE op
CASE "*"
calcul = valeur1 * valeur2
CASE "/"
calcul = valeur1 / valeur2
CASE "MOD"
calcul = valeur1 MOD valeur2
CASE "+"
calcul = valeur1 + valeur2
CASE "-"
calcul = valeur1 - valeur2
CASE ELSE
STOP
END SELECT
'replace the operation by its result
ptexte2 = LEFT$(ptexte2, f - gauche - 1) + LTRIM$(STR$(calcul)) + MID$(ptexte2, f + LEN(op) + droite)
'for debugging
IF debug = 1 AND a = 2 THEN
LOCATE 7, 1: PRINT SPACE$(400): LOCATE 7, 1
PRINT "Formula:"; paratexte2
PRINT "Operation:"; op
PRINT "left value:"; valeur1, "right value:"; valeur2
PRINT "Result:"; calcul
PRINT "New formula:"; ptexte2
SLEEP
END IF
END IF
NEXT
operateur = ptexte2
END FUNCTION
SUB parser.ifthen
' evaluate the tests.
'If a test is TRUE, then execute the GOTO of the script
'take out "IF " and "THEN"
test = MID$(UCASE$(script(a, ligne(a))), 4)
FOR c = 3 TO LEN(test)
IF MID$(test, c, 4) = "THEN" THEN EXIT FOR
NEXT
'memorize the line referenced by the GOTO
gotoligne = VAL(MID$(test, c + 10))
test = LEFT$(test, c - 1)
replace.litterals
'identify the kind of test (=,>,>=,<,<=)
FOR c = LEN(test) TO 1 STEP -1
ope$ = MID$(test, c, 1)
IF ope$ = "=" OR ope$ = ">" OR ope$ = "<" THEN EXIT FOR
NEXT
'memorize the two parts of the test
test1$ = LEFT$(test, c - 1)
test2$ = MID$(test, c + 1)
'in case of <= or >= (2 characters long)
IF ope$ = "=" THEN
ope2$ = MID$(test, c - 1, 1)
IF ope2$ = "<" OR ope2$ = ">" THEN
ope$ = ope2$ + ope$
test1$ = LEFT$(test, c - 2)
END IF
END IF
'evaluate each part
t1 = calculate(test1$)
t2 = calculate(test2$)
'evaluate the test
flag = 0
SELECT CASE ope$
CASE "="
IF t1 = t2 THEN flag = 1
CASE ">"
IF t1 > t2 THEN flag = 1
CASE "<"
IF t1 < t2 THEN flag = 1
CASE ">="
IF t1 >= t2 THEN flag = 1
CASE "<="
IF t1 <= t2 THEN flag = 1
CASE ELSE
STOP
END SELECT
'for debugging:
IF debug = 1 AND a = 2 THEN
LOCATE 1, 1: PRINT SPACE$(1200): LOCATE 1, 1
PRINT "IF ... THEN ... GOTO ..."
PRINT "Line:"; ligne(a)
PRINT script(a, ligne(a))
PRINT "Test:"; test
PRINT "Left value:"; t1, "Right value:"; t2
PRINT "Result:"; flag
SLEEP
END IF
'if TRUE, then go to the line
IF flag = 1 THEN ligne(a) = gotoligne - 1
END SUB
SUB parser.myvariable
' sets the internal variable
'take out "set myvariable="
test = MID$(UCASE$(script(a, ligne(a))), 16)
replace.litterals
'for debugging:
IF debug = 1 AND a = 2 THEN
LOCATE 1, 1: PRINT SPACE$(1200): LOCATE 1, 1
PRINT "SET MYVARIABLE"
PRINT "Line:"; ligne(a)
PRINT script(a, ligne(a))
PRINT "Formula:"; test
END IF
'evaluate and sets the variable
t1 = calculate(test)
myvariable(a) = t1
'for debugging:
IF debug = 1 AND a = 2 THEN
LOCATE 5, 1
PRINT "New Value:"; myvariable(a)
SLEEP
END IF
END SUB
SUB remplace (old AS STRING, new AS LONG)
'replace a string by another
FOR f = 1 TO LEN(test)
IF MID$(test, f, LEN(old)) = old THEN
test = LEFT$(test, f - 1) + LTRIM$(STR$(new)) + MID$(test, f + LEN(old))
END IF
NEXT
END SUB
SUB replace.litterals
'replaces variables by numeric values
' ball variables: KEEP THIS ORDER!
CALL remplace("XXBALL", INT(xxball * 100))
CALL remplace("YYBALL", INT(yyball * 100))
CALL remplace("XBALL", INT(xball))
CALL remplace("YBALL", INT(yball))
'generic variables
CALL remplace("HEIGHT", 201 - 1)
CALL remplace("WIDTH", 599 - 41)
CALL remplace("PADDLEWIDTH", PADDLEWIDTH)
'robot-dependent variables
CALL remplace("MYVARIABLE", myvariable(a))
CALL remplace("XOPPONENT", INT(x(3 - a)))
CALL remplace("YOPPONENT", INT(y(3 - a)))
CALL remplace("XMYSELF", INT(x(a)))
IF a = 1 THEN
CALL remplace("BALLAPPROACHING", (yyball < 0))
CALL remplace("INFRONTOFBALL", (ABS(x(a) - xtmp) < PADDLEWIDTH + 2 + 1 AND y(a) < ytmp AND ytmp - y(a) < PADDLESTEP * 4))
CALL remplace("MINY", 1)
CALL remplace("MAXY", 201)
CALL remplace("YMYFRONT", INT(y(a) + taille(a) / 2))
CALL remplace("YMYBACK", INT(y(a) - taille(a) / 2))
ELSE
CALL remplace("BALLAPPROACHING", (yyball > 0))
CALL remplace("INFRONTOFBALL", (ABS(x(a) - xtmp) < PADDLEWIDTH + 2 + 1 AND y(a) > ytmp AND y(a) - ytmp < PADDLESTEP * 4))
CALL remplace("MINY", 259)
CALL remplace("MAXY", 459)
CALL remplace("YMYFRONT", INT(y(a) - taille(a) / 2))
CALL remplace("YMYBACK", INT(y(a) + taille(a) / 2))
END IF
'Remove the empty spaces:
FOR f = 1 TO LEN(test)
IF MID$(test, f, 1) = " " THEN
test = LEFT$(test, f - 1) + MID$(test, f + 1)
END IF
NEXT
END SUB
SUB show.ball
'affichage balle
CIRCLE (xball, yball), 2, 0
CIRCLE (xtmp, ytmp), 2, 2 + vball / 2
END SUB
SUB show.info
' show info at line 30
LOCATE 30, 1
COLOR 15: PRINT "Set "; manche,
COLOR 5: PRINT "Delay (+/-):"; vitesse;
LOCATE 30, 35
COLOR 6
IF manualmode = 1 THEN PRINT "Player (V)s Robot"; ELSE PRINT "Robot (V)s Robot ";
LOCATE 30, 55
COLOR 15: PRINT "Scores:";
COLOR 1: PRINT " "; score(1);
COLOR 2: PRINT " "; score(2); " ";
END SUB
SUB show.rules.english
CLS
COLOR 15
PRINT " DEFI PONG (A game of robots and paddles)"
PRINT " The program reads the scripts of the robots from the robot#.txt files."
COLOR 4
PRINT " Commands recognized for the script: "
COLOR 15
PRINT "(use lines starting with ';' for comments)"
PRINT " 0 - WAIT 1 - LEFT 2 - RIGHT 3 - FRONT 4 - BACK"
PRINT " 5 - GOTO line"
PRINT " 6 - IF test THEN GOTO line"
PRINT " 7 - SET MYVARIABLE=expression"
COLOR 4
PRINT " Possible tests:"
COLOR 15
PRINT " (no AND nor OR nor NOT)"
PRINT " > >= < <= ="
COLOR 4
PRINT " Possible operators (by order of priority):"
COLOR 15
PRINT " () * / mod + -"
COLOR 4
PRINT " Possible variables:"
COLOR 15
PRINT " Xmyself Ymyfront Ymyback Xopponent Yopponent"
PRINT " Xball Yball XXball (*100) YYball (*100)"
PRINT " Infrontofball (Boolean) Ballapproaching(Boolean)"
PRINT " Myvariable (internal use)"
PRINT " Width Height MinY MaxY"
PRINT "Paddlewidth"
COLOR 4
PRINT " Special Rules:"
COLOR 15
PRINT "Each turn, an instruction is executed for each robot,then the ball moves"
PRINT "In function of the vertical movement of the paddle before hitting the ball, the ball can be accelerated OR slowed down"
PRINT "Each set has 5 points"
COLOR 4
PRINT "ball dimensions: a circle of 4 pixels"
PRINT "Zone limits: x from 1 to 559 y from 1 to 459"
COLOR 7
INPUT "Select robot numbers (example: 1,2) :", a, B
robnum(1) = a: robnum(2) = B
END SUB
SUB show.rules.french
CLS
COLOR 15
PRINT " DEFI PONG (Jeu de robots et de raquettes)"
PRINT "Le programme lit les scripts des robots depuis les fichiers robot#.txt"
COLOR 4
PRINT " Commandes acceptâes pour le script:"
COLOR 15
PRINT "(Utilisez des lignes commenâ¡ant par ';' pour les commentaires)"
PRINT " 0 - WAIT 1 - LEFT 2 - RIGHT 3 - FRONT 4 - BACK"
PRINT " 5 - GOTO ligne"
PRINT " 6 - IF test THEN GOTO ligne"
PRINT " 7 - SET MYVARIABLE=expression"
COLOR 4
PRINT " Tests possibles:"
COLOR 15
PRINT " (pas de AND ni de OR ni de NOT)"
PRINT " > >= < <= ="
COLOR 4
PRINT " Opârateurs possibles (par ordre de prioritâ):"
COLOR 15
PRINT " () * / mod + -"
COLOR 4
PRINT " Variables possibles:"
COLOR 15
PRINT " Xmyself Ymyfront Ymyback Xopponent Yopponent"
PRINT " Xball Yball XXball (*100) YYball (*100)"
PRINT " Infrontofball (Boolean) Ballapproaching(Boolean)"
PRINT " Myvariable (usage interne)"
PRINT " Width Height MinY MaxY"
PRINT "Paddlewidth"
COLOR 4
PRINT " RÅ gles spâciales:"
COLOR 15
PRINT "Chaque tour, une instruction est exâcutâe pour chaque robot, puis la balle bouge"
PRINT "En fonction du mouvement vertical de la raquette juste avant le contact avec la balle la balle peut-Ëtre accâlârâe ou ralentie"
PRINT "Chaque manche se joue en 5 points"
COLOR 4
PRINT " Dimensions de la balle: cercle de 4 pixels"
PRINT " Limites du terrain: x de 1 ⦠559 y de 1 ⦠459"
COLOR 7
INPUT "Seleccionez les numâros de robots (exemple: 1,2) :", a, B
robnum(1) = a: robnum(2) = B
END SUB
SUB show.rules.spanish
CLS
COLOR 15
PRINT " DEFI PONG (Juego de robots y de paletas)"
PRINT "El programa lee los scripts de los robots desde los archivos robot#.txt"
COLOR 4
PRINT " Comandos aceptados para el script:"
COLOR 15
PRINT "(use lineas empezando por ';' para commentarios)"
PRINT " 0 - WAIT 1 - LEFT 2 - RIGHT 3 - FRONT 4 - BACK"
PRINT " 5 - GOTO linea"
PRINT " 6 - IF test THEN GOTO linea"
PRINT " 7 - SET MYVARIABLE=expresion"
COLOR 4
PRINT " Tests posibles:"
COLOR 15
PRINT " (no AND ni OR ni NOT)"
PRINT " > >= < <= ="
COLOR 4
PRINT " Opâradores posibles (por orden de prioridad):"
COLOR 15
PRINT " () * / mod + -"
COLOR 4
PRINT " Variables posibles:"
COLOR 15
PRINT " Xmyself Ymyfront Ymyback Xopponent Yopponent"
PRINT " Xball Yball XXball (*100) YYball (*100)"
PRINT " Infrontofball (Boolean) Ballapproaching(Boolean)"
PRINT " Myvariable (uso interno)"
PRINT " Width Height MinY MaxY"
PRINT "Paddlewidth"
COLOR 4
PRINT " Reglas especiales:"
COLOR 15
PRINT "Cada turno, se ejecuta una instruccion para cada robot, luego se mueve la pelota"
PRINT "En funcion del movimiento vertical de la paleta justo antes de pegar la pelota, esta puede ser acelerada o frenada"
PRINT "Cada set se juega en 5 puntos"
COLOR 4
PRINT " Dimensiones de la pelota: circulo de 4 pixeles"
PRINT " Limites de la cancha: x de 1 a 559 y de 1 a 459"
COLOR 7
INPUT "Seleccione los numeros de los robots (ejemplo: 1,2) :", a, B
robnum(1) = a: robnum(2) = B
END SUB
SUB win
'for now, each 5 points means a new set. That's all
show.info
FOR B = 1 TO 2
IF score(B) = manche * 5 THEN
LOCATE 15, 15: COLOR B
PRINT "Player" + STR$(B) + " won the set #"; manche;
k$ = INKEY$: DO WHILE k$ = "": k$ = INKEY$: LOOP
new.set
END IF
NEXT
END SUB