'===========================================================================
' Subject: TRON LIGHT CYCLES                  Date: 10-27-95 (16:44)       
'  Author: Joshua Dickerson                   Code: QB, QBasic, PDS        
'  Origin: FidoNet QUIK_BAS Echo            Packet: DEMOS.ABC
'===========================================================================
'                     T r O n   L i G h T   c Y c L e S
'
'                              Programmed By:
'                             Joshua Dickerson
'
'                          Press Shift+F5 To Play!
'
DEFINT A-S, U-Z
DEFSNG T
'
TYPE Cycle
    X AS INTEGER
    Y AS INTEGER
    XD AS INTEGER
    YD AS INTEGER
    Turbo AS INTEGER
    TurboOn AS INTEGER
    Alive AS INTEGER
    WINS AS INTEGER
    WinLocX AS INTEGER
    WinLocY AS INTEGER
    Up AS STRING * 1
    Down AS STRING * 1
    Left AS STRING * 1
    Right AS STRING * 1
    TurboKey AS STRING * 1
END TYPE
'
DECLARE SUB PlayerDead (i)
DECLARE SUB Display ()
DECLARE SUB UpdatePlayer (i)
DECLARE SUB GetKeyboardInputs ()
DECLARE SUB GamePlay ()
DIM SHARED Player(1 TO 2) AS Cycle
DIM SHARED Pfield$(100)
'
CLS : WIDTH 40: RANDOMIZE TIMER                  'General Intialization
Player(2).WinLocY = 1: Player(2).WinLocX = 20
Player(1).WinLocY = 3: Player(1).WinLocX = 1
Player(1).Up = "w"
Player(1).Down = "s"
Player(1).Left = "a"
Player(1).Right = "d"
Player(1).TurboKey = " "
'
Player(2).Up = "8"
Player(2).Down = "2"
Player(2).Left = "4"
Player(2).Right = "6"
Player(2).TurboKey = "5"
'
COLOR 11
FOR i = 1 TO 2
LOCATE Player(i).WinLocY, Player(i).WinLocX: PRINT "ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"
    FOR j = 1 TO 15
     LOCATE Player(i).WinLocY + j, Player(i).WinLocX
     PRINT "³               ³"
    NEXT
LOCATE Player(i).WinLocY + 16, Player(i).WinLocX
PRINT "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"
NEXT
'
'
FOR Round = 1 TO 3
    FOR j = 1 TO 100: Pfield$(j) = SPACE$(100): NEXT
    Player(1).X = 50: Player(1).Y = 50
    Player(2).X = 51: Player(2).Y = 50
'  
    FOR j = 1 TO 2
     Player(j).Alive = -1
     Player(j).Turbo = 100
     Player(j).TurboOn = 0
     Player(j).XD = 0: Player(j).YD = 0
     Pfield$(50) = SPACE$(49) + "³³" + SPACE$(49)
     Display
    NEXT
    '
    WHILE INKEY$ <> "": WEND
    FOR j = 3 TO 0 STEP -1
     WHILE TIMER < t + 1
     GetKeyboardInputs
     WEND: t = TIMER: SOUND 400, .4: '
    NEXT: SOUND 600, 8
    FOR i = 1 TO 2                'Default direction is up
     IF Player(i).YD = 0 AND Player(i).XD = 0 THEN Player(i).YD = -1
    NEXT
GamePlay
NEXT
    IF Player(1).WINS > Player(2).WINS THEN LOCATE 22, 1: PRINT "Player 1 WINS!"
    IF Player(2).WINS > Player(1).WINS THEN LOCATE 22, 1: PRINT "Player 2 WINS!"
    IF Player(1).WINS = Player(2).WINS THEN LOCATE 22, 1: PRINT "TIE GAME, WOW!"
DEFSNG A-H, K-S, U-Z
DEFINT K

'
SUB Display
'
FOR j = 1 TO 2
'Display Player Locations.
COLOR 10: LOCATE Player(j).WinLocY + 17, Player(j).WinLocX: PRINT "Location(";
PRINT USING "###"; Player(j).X; : PRINT ",";
PRINT USING "###"; Player(j).Y; : PRINT ")"
COLOR 11
    FOR k = -7 TO 7
     'Is Window displaying upper or lower side of boundry?
     IF Player(j).Y + k < 1 OR Player(j).Y + k > 100 THEN
     LOCATE Player(j).WinLocY + 8 + k, Player(j).WinLocX + 1
     PRINT STRING$(15, "Å"): GOTO Skip
     END IF
'
     'Is Window displaying left side of boundry?
     IF Player(j).X - 7 < 1 THEN
     LOCATE Player(j).WinLocY + 8 + k, Player(j).WinLocX + 1
     PRINT STRING$(ABS(Player(j).X - 8), "Å");
     PRINT LEFT$(Pfield$(Player(j).Y + k), 15 - ABS(Player(j).X - 8)): GOTO Skip
     END IF
'
     'Is Window displaying right side of boundry?
     IF Player(j).X + 7 > 100 THEN
     LOCATE Player(j).WinLocY + 8 + k, Player(j).WinLocX + 1
     PRINT RIGHT$(Pfield$(Player(j).Y + k), 101 - (Player(j).X - 7));
     PRINT STRING$(15 - (101 - (Player(j).X - 7)), "Å"): GOTO Skip
     END IF
'
     'Nothing beyond boundry is being displayed.
     LOCATE Player(j).WinLocY + 8 + k, Player(j).WinLocX + 1
     PRINT MID$(Pfield$(Player(j).Y + k), Player(j).X - 7, 15)
'
Skip: NEXT
NEXT
'
END SUB

DEFSNG K
'
SUB GamePlay
'
GamePlayMainLoop:
IF Player(1).Alive = 0 OR Player(2).Alive = 0 THEN GOTO RoundOver
't = TIMER: WHILE TIMER < t + .1: WEND
GetKeyboardInputs
FOR i = 1 TO 2
IF Player(i).TurboOn = -1 AND Player(i).Turbo > 0 THEN
Player(i).Turbo = Player(i).Turbo - 1: UpdatePlayer (i)
END IF
NEXT
'
IF Player(1).Alive = 0 OR Player(2).Alive = 0 THEN GOTO RoundOver
't = TIMER: WHILE TIMER < t + .2: WEND
GetKeyboardInputs
FOR i = 1 TO 2: UpdatePlayer (i): NEXT
GOTO GamePlayMainLoop
RoundOver: END SUB

SUB GetKeyboardInputs
GetKeyMainLoop: a$ = INKEY$
IF a$ = "" THEN GOTO NoKey
FOR i = 1 TO 2
'Turbo Toggle?
IF a$ = Player(i).TurboKey THEN
Player(i).TurboOn = (Player(i).TurboOn = 0)
IF Player(i).Turbo < 1 THEN Player(i).TurboOn = 0
GOTO DalreadySet
END IF
'If player already selected direction, skip him.
IF MID$(Pfield$(Player(i).Y), Player(i).X, 1) <> "Ä" AND MID$(Pfield$(Player(i).Y), Player(i).X, 1) <> "³" THEN GOTO DalreadySet
'Did player press left?
IF a$ = Player(i).Left AND Player(i).XD = 0 THEN
IF Player(i).YD = -1 THEN b$ = "¿" ELSE b$ = "Ù"
Player(i).XD = -1: Player(i).YD = 0
GOTO Bypass
END IF
 'Did player press right?
IF a$ = Player(i).Right AND Player(i).XD = 0 THEN
IF Player(i).YD = -1 THEN b$ = "Ú" ELSE b$ = "À"
 Player(i).XD = 1: Player(i).YD = 0
GOTO Bypass
END IF
'Did player press up?
IF a$ = Player(i).Up AND Player(i).YD = 0 THEN
IF Player(i).XD = -1 THEN b$ = "À" ELSE b$ = "Ù"
Player(i).YD = -1: Player(i).XD = 0
GOTO Bypass
END IF
'Did Player press down?
IF a$ = Player(i).Down AND Player(i).YD = 0 THEN
IF Player(i).XD = -1 THEN b$ = "Ú" ELSE b$ = "¿"
Player(i).YD = 1: Player(i).XD = 0
GOTO Bypass
END IF
GOTO DalreadySet
Bypass:
Pfield$(Player(i).Y) = LEFT$(Pfield$(Player(i).Y), Player(i).X - 1) + b$ + RIGHT$(Pfield$(Player(i).Y), 100 - Player(i).X)
Display
DalreadySet: NEXT: GOTO GetKeyMainLoop            'Loop until buffer empty
NoKey: END SUB

SUB PlayerDead (i)
'Animated Explosion sequence with sound.
Player(i).Alive = 0
Player(2 - INT(i / 2)).WINS = Player(2 + (i = 2)).WINS + 1
WHILE a < 4: SOUND INT(500 * RND(1)) + 100, .1
    IF TIMER > t + .1 THEN
    LOCATE Player(i).WinLocY + 8, Player(i).WinLocX + 8
    a = a + 1: PRINT MID$("Û²±°", a, 1): t = TIMER
END IF
WEND: a = 0
END SUB

DEFINT K
SUB UpdatePlayer (i)
'If player is not alive, don't bother.
IF Player(i).Alive = 0 THEN GOTO Shunt
'Did player crash into outer-boundry?
IF Player(i).X + Player(i).XD < 1 THEN PlayerDead (i): GOTO Shunt
IF Player(i).X + Player(i).XD > 100 THEN PlayerDead (i): GOTO Shunt
IF Player(i).Y + Player(i).YD < 1 THEN PlayerDead (i): GOTO Shunt
IF Player(i).Y + Player(i).YD > 100 THEN PlayerDead (i): GOTO Shunt
'Did player crash into light trail?
IF MID$(Pfield$(Player(i).Y + Player(i).YD), Player(i).X + Player(i).XD, 1) <> " " THEN PlayerDead (i): GOTO Shunt
'Move player in current direction.
Player(i).X = Player(i).X + Player(i).XD      'If moving horizontaly, update X
Player(i).Y = Player(i).Y + Player(i).YD      'If moving verticaly, Update Y
'Place light trail in current position.
IF Player(i).YD <> 0 THEN b$ = "³" ELSE b$ = "Ä"
Pfield$(Player(i).Y) = LEFT$(Pfield$(Player(i).Y), Player(i).X - 1) + b$ + RIGHT$(Pfield$(Player(i).Y), 100 - Player(i).X)
Display                                               'Display Player's Window
Shunt: END SUB

