!
!  Potshot
!
!  A little game of parabolas.  This game can be played
!  by two players, or on autopilot (the computer plays
!  against itself).  As set up, the game is on autopilot.
!  Change the AngleSpeed subroutine to ask for player
!  input...
!
!  This game is based on the excellent Tektronix version
!  designed by Art Luehrmann.
!
!
OPTION ANGLE degrees
RANDOMIZE
OPEN #1: screen 0,1,.1,1          !the output window
OPEN #2: screen 0,.45,0,.09       !player 1 input
OPEN #3: screen .55,1,0,.09       !player 2 input

WINDOW #1                         !set up output window
SET window 0,10,0,2
CALL InitExplosion(.2,.07)        !and canned explosion
CALL InitShell(80/639,8/180)      !and shell image

DO
   WINDOW #0
   CLEAR
   WINDOW #1
   SET color "green/blue"
   CALL DrawHill(x1,y1,x2,y2)
   CALL DrawHut(x1,y1)
   CALL DrawHut(x2,y2)
   LET huthit = 0
   DO
      WINDOW #2
      CALL AngleSpeed(a,s)
      CALL Shoot(x1,y1,a,s,x2,y2,huthit,0)
      IF huthit<>0 then EXIT DO
      WINDOW #3
      CALL AngleSpeed(a,s)
      CALL Shoot(x2,y2,-a,s,x1,y1,huthit,1)
   LOOP until huthit<>0
LOOP

DIM xrand(25), yrand(25)

SUB InitExplosion(xd,yd)
    ASK window x1,i,y1,i
    FOR i = 0 to 360 step 5
        LET z = mod((i+4)/60,1)
        CALL Divide(i,10,q,r)
        SET color Mod(q,3)+1
        PLOT (1+sin(i)*z)*xd/2+x1,(1+cos(i)*z)*yd/2+y1
    NEXT i
    BOX KEEP x1,x1+xd,y1,y1+yd in explosion$
    FOR i = 1 to 25
        LET xrand(i) = (rnd-1)*xd
        LET yrand(i) = (rnd-1)*yd
    NEXT i
    CLEAR
END SUB

SUB InitShell(xd,yd)
    SET color "yellow"
    LET shw = xd
    LET shh = yd
    ASK window x1,i,y1,i
    BOX KEEP x1,x1+shw,y1,y1+shh in no_shell$
    FOR i = 0 to 360 step 30
        PLOT x1+(sin(i)+1)*shw/2, y1+(cos(i)+1)*shh/2;
    NEXT i
    PLOT
    BOX KEEP x1,x1+shw,y1,y1+shh in shell$
    CLEAR
END SUB

!
!  Kaboom
!
!  Make an explosion.  First we display the explosion
!  (and flash the background if a hut was hit).  Then we
!  use the explosion image to eat into whatever it hit.
!
SUB Kaboom(x,y,huthit)
    FOR j = 1 to 2
        FOR i = 1 to 25
            IF huthit<>0 then SET back i
            BOX SHOW explosion$ at x+xrand(i),y+yrand(i) using "xor"
        NEXT i
    NEXT j
    FOR i = 1 to 6 + 6*rnd
        BOX SHOW explosion$ at x+xrand(i),y+yrand(i) using 4
    NEXT i
END SUB

!
!  Shoot
!
!  Shoot from hut (x1,y1) to hut (x2,y2) with angle 'a'
!  and speed 's'.  We set huthit nonzero if the shot
!  hits a hut.  The parameter is used only for scoring;
!  it's 0 if the left hut shot, or 1 if the right hut shot.
!
!  This subroutine takes care of one complete shot.
!
SUB Shoot(x1,y1,a,s,x2,y2,huthit,right)
    LET grav = .001
    LET x = sin(a)
    LET y = cos(a)
    LET vx = s*x/100
    LET vy = s*y/300
    LET x = x1 + x*.3 - shw/2
    LET y = y1 + y*.12 - shh/2
    WINDOW #1
    ASK window wx1,wx2,wy1,wy2
    LET dx = abs(wx1-wx2)/60      !near enough to hut to kaboom
    LET dy = abs(wy1-wy2)/40
    LET oldx, oldy = -100
    DO
       BOX SHOW shell$ at x,y using "xor"
       BOX SHOW shell$ at oldx,oldy using "xor"
       LET oldx = x
       LET oldy = y
       BOX KEEP x,x+shw, y,y+shh in shell2$
       IF shell2$ <> shell$ then EXIT DO
       LET x = x + vx
       LET y = y + vy
       LET vy = vy - grav
    LOOP
    BOX SHOW shell$ at x,y using "xor"
    LET x = x + shw/2
    IF (abs(x-x1)<dx and abs(y-y1)<dy) then
       LET huthit=1
       LET right_score = right_score + (1-right)
       LET left_score  = left_score + right
    ELSEIF (abs(x-x2)<dx and abs(y-y2)<dy) then
       LET huthit=1
       LET left_score  = left_score + (1-right)
       LET right_score = right_score + right
    END IF
    IF huthit<>0 then SOUND 20,.3 else SOUND 2000,.05
    CALL Kaboom(x,y,huthit)
    IF huthit<>0 then
       SET back "blue"
       SET cursor 4,18
       PRINT "SCORE"
       SET cursor 5,16
       PRINT using "%% to %%": left_score, right_score
       PAUSE 3
    END IF
END SUB

END

!
!
!  DrawHill
!
!  Draw random landscape with two small hills, and a
!  big central hill.  Return (x1,y1) as the top of one
!  small hill, and (x2,y2) as the top of the other.
!
SUB DrawHill(x1,y1,x2,y2)

    LET c1 = 2+1.5*(rnd-.5)       ! x coordinates of hills
    LET c2 = 5+1.8*(rnd-.5)
    LET c3 = 8+1.5*(rnd-.5)

    LET a1 = .15+rnd/10           ! height controls
    LET a2 = .8+rnd/2.5
    LET a3 = .15+rnd/10

    LET b1 = .35 + rnd*.3
    LET b2 = .6+rnd/3
    LET b3 = .35 + rnd*.3

    DEF ht(x)
        LET x01 = x-c1
        LET x02 = x-c2
        LET x03 = x-c3
        LET ht = a1/(b1+(x01*x01)) + a2/(b2+x02*x02) + a3/(b3+x03*x03)
    END DEF

    LET i = 1
    FOR x = 0 to 10 step 1/8      !draw hill outline
        LET y = ht(x)
        PLOT x,y;
        LET i=i+1
    NEXT x
    PLOT
    FLOOD 10,0                    !color the hill
    LET x1 = c1                   !(x1,y1) = one hut
    LET x2 = c3
    LET y1 = ht(x1)               !(x2,y2) = the other
    LET y2 = ht(x2)
END SUB

SUB DrawHut(x,y)
    SET color "red"
    BOX AREA x-.1,x+.1,y-.01,y+.04
    SET color "yellow"
    BOX LINES x-.1,x+.1,y-.01,y+.04
END SUB

SUB AngleSpeed(a,s)

    IF 1=0 then                   !two humans playing
       INPUT prompt "Angle, speed: ": a,s
       LET a = 90-a
    ELSE                          !autopilot
       LET a = 30 + (rnd-.5)*40
       LET s = 14 + (rnd-.5)*6
       IF rnd < .05 then LET a = -a
       IF rnd < .02 then LET a=0
       IF rnd < .08 then LET s = s/3
    END IF

END SUB
