rem Snake Bite
rem copyright Marc Gale (Xalthorn) 2001
rem 
rem A fun little game for one or two players

gosub initialise

gosub main_loop

exit

label main_loop
  quitgame=0
    repeat
      gosub title_screen
      gosub main_menu
    until (quitgame=1)
return

label title_screen
  setdispbuf d
  setdrawbuf d

  clear window

  gosub draw_title
  setrgb 1,200,100,200
  text 50,50,"Snake Bite - Copyright Marc Gale (Xalthorn) 2001","lb"

  gosub waitfornoinput

  setrgb 1,150,150,255
  for a=1 to titlelines
    if title$(a)<>"" then
      for b=1 to len(title$(a))
        text b*12+50,a*18+70,mid$(title$(a),b,1)
        buttons=or(peek("port1"),peek("port2"))
        if buttons=0 then
          wait 0.1
        fi
      next b
    fi
  next a

  setrgb 1,255,255,255
  text sw/2,sh-20,"Press the X button for the main menu","cc"

  repeat
    buttons=or(peek("port1"),peek("port2"))
  until (and(buttons,16384)=16384)
return

label help_screen
  setdispbuf d
  setdrawbuf d

  clear window

  gosub draw_title
  setrgb 1,200,100,200
  text 50,50,"Snake Bite Help Screen","lb"

  gosub waitfornoinput

  setrgb 1,150,150,255
  for a=1 to helplines
    if help$(a)<>"" then
      for b=1 to len(help$(a))
        text b*12+50,a*18+70,mid$(help$(a),b,1)
        buttons=or(peek("port1"),peek("port2"))
        if buttons=0 then
          wait 0.1
        fi
      next b
    fi
  next a

  setrgb 1,255,255,255
  text sw/2,sh-20,"Press the X button to return to the main menu","cc"

  repeat
    buttons=or(peek("port1"),peek("port2"))
  until (and(buttons,16384)=16384)
return

label draw_title
  setrgb 1,0,0,100
  setrgb 2,0,0,0
  setrgb 3,0,0,100
  gtriangle 0,0 to 0,sh to sw,0
  setrgb 1,0,0,0
  gtriangle 0,sh to sw,sh to sw,0 

  setrgb 1,255,255,255
  line 50,60 to 600,60
return

label main_menu
  option=0

  repeat
    gosub waitfornoinput
    cursor=1
    setdispbuf d
    setdrawbuf d
    gosub draw_title
    setrgb 1,200,100,200
    text 50,50,"Snake Bite Main Menu","lb"

    for a=1 to numoptions
      draw_option(a,0)
    next a

    setrgb 1,255,255,255
    text sw/2,500,"Move up and down to highlight an option and press X","cc"

    draw_option(cursor,1)

    repeat
      buttons=or(peek("port1"),peek("port2"))

      if and(buttons,16)=16 and cursor>1 then
        draw_option(cursor,0)
        cursor=cursor-1
        draw_option(cursor,1)
        gosub waitfornoinput
      fi

      if and(buttons,64)=64 and cursor<numoptions then
        draw_option(cursor,0)
        cursor=cursor+1
        draw_option(cursor,1)
        gosub waitfornoinput
      fi

    until (and(buttons,16384)=16384)

    option=cursor

    if option=1 then
      gosub game_loop
    fi

    if option=2 then
      gosub option_screen
    fi

    if option=3 then
      gosub help_screen
    fi

  until (option=numoptions)
return

label option_screen
  choice=0

  repeat
    gosub waitfornoinput
    cursor=1
    setdispbuf d
    setdrawbuf d
    gosub draw_title
    setrgb 1,200,100,200
    text 50,50,"Snake Bite Options","lb"

    for a=1 to numchoices
      draw_choice(a,0)
      draw_choice_setting(a)
    next a

    setrgb 0,0,0,0

    draw_choice(cursor,1)

    repeat
      buttons=or(peek("port1"),peek("port2"))

      if and(buttons,16)=16 and cursor>1 then
        draw_choice(cursor,0)
        cursor=cursor-1
        draw_choice(cursor,1)
        gosub waitfornoinput
      fi

      if and(buttons,64)=64 and cursor<numchoices then
        draw_choice(cursor,0)
        cursor=cursor+1
        draw_choice(cursor,1)
        gosub waitfornoinput
      fi

      if and(buttons,128)=128 then
        if cursor=1 and snake(1,8)=2 then
          snake(1,8)=1
          draw_choice_setting(cursor)
        fi
        if cursor=2 and snake(1,14)=2 then
          snake(1,14)=1
          draw_choice_setting(cursor)
        fi
        if cursor=3 and snake(1,12)>1 then
          snake(1,12)=snake(1,12)-1
          draw_choice_setting(cursor)
        fi
        if cursor=4 and snake(1,13)>1 then
          snake(1,13)=snake(1,13)-1
          draw_choice_setting(cursor)
        fi
        if cursor=5 and snake(2,8)=2 then
          snake(2,8)=1
          draw_choice_setting(cursor)
        fi
        if cursor=6 and snake(2,14)=2 then
          snake(2,14)=1
          draw_choice_setting(cursor)
        fi
        if cursor=7 and snake(2,12)>1 then
          snake(2,12)=snake(2,12)-1
          draw_choice_setting(cursor)
        fi
        if cursor=8 and snake(2,13)>1 then
          snake(2,13)=snake(2,13)-1
          draw_choice_setting(cursor)
        fi
        gosub waitfornoinput
      fi

      if and(buttons,32)=32 then
        if cursor=1 and snake(1,8)=1 then
          snake(1,8)=2
          draw_choice_setting(cursor)
        fi
        if cursor=2 and snake(1,14)=1 then
          snake(1,14)=2
          draw_choice_setting(cursor)
        fi
        if cursor=3 and snake(1,12)<10 then
          snake(1,12)=snake(1,12)+1
          draw_choice_setting(cursor)
        fi
        if cursor=4 and snake(1,13)<10 then
          snake(1,13)=snake(1,13)+1
          draw_choice_setting(cursor)
        fi
        if cursor=5 and snake(2,8)=1 then
          snake(2,8)=2
          draw_choice_setting(cursor)
        fi
        if cursor=6 and snake(2,14)=1 then
          snake(2,14)=2
          draw_choice_setting(cursor)
        fi
        if cursor=7 and snake(2,12)<10 then
          snake(2,12)=snake(2,12)+1
          draw_choice_setting(cursor)
        fi
        if cursor=8 and snake(2,13)<10 then
          snake(2,13)=snake(2,13)+1
          draw_choice_setting(cursor)
        fi
        gosub waitfornoinput
      fi

    until (and(buttons,16384)=16384 and cursor=numchoices)

    choice=cursor

  until (choice=numchoices)
return

label waitfornoinput
  repeat
    padinput=or(peek("port1"),peek("port2"))
  until (padinput=0)
return

sub draw_option(a,s)
  if s=1 then
    setrgb 1,100,100,200
  else
    setrgb 1,100,100,100
  fi
  fill rectangle 200,a*100 to 400,a*100+50

  if s=1 then
    setrgb 1,80,80,130
  else
    setrgb 1,80,80,80
  fi
  line 200,a*100 to 200,a*100+50
  line 200,a*100+50 to 400,a*100+50

  if s=1 then
    setrgb 1,200,200,250
  else
    setrgb 1,200,200,200
  fi
  line 200,a*100 to 400,a*100
  line 400,a*100 to 400,a*100+50

  setrgb 1,255,255,255
  text 300,a*100+28,options$(a),"cc"
end sub

sub draw_choice(a,s)
  if s=1 then
    setrgb 1,100,100,200
  else
    setrgb 1,100,100,100
  fi
  fill rectangle 80,a*40+50 to 350,a*40+80

  if s=1 then
    setrgb 1,80,80,130
  else
    setrgb 1,80,80,80
  fi
  line 80,a*40+50 to 80,a*40+80
  line 80,a*40+80 to 350,a*40+80

  if s=1 then
    setrgb 1,200,200,250
  else
    setrgb 1,200,200,200
  fi
  line 80,a*40+50 to 350,a*40+50
  line 350,a*40+50 to 350,a*40+80

  setrgb 1,255,255,255
  text 220,a*40+70,choices$(a),"cc"

  setrgb 1,0,0,0
  fill rectangle 0,480 to sw,sh
  setrgb 1,255,255,255
  text sw/2,500,hints$(a),"cc"

end sub

sub draw_choice_setting(a)
  if a=1 or a=5 then
    if (a=1 and snake(1,8)=1) or (a=5 and snake(2,8)=1) then
      setrgb 1,100,100,200
    else
      setrgb 1,100,100,100
    fi
    fill rectangle 370,a*40+50 to 470,a*40+80
    setrgb 1,0,0,0
    rectangle 370,a*40+50 to 470,a*40+80
    setrgb 1,255,255,255
    text 420,a*40+70,"Human","cc"

    if (a=1 and snake(1,8)=2) or (a=5 and snake(2,8)=2) then
      setrgb 1,100,100,200
    else
      setrgb 1,100,100,100
    fi
    fill rectangle 470,a*40+50 to 570,a*40+80
    setrgb 1,0,0,0
    rectangle 470,a*40+50 to 570,a*40+80
    setrgb 1,255,255,255
    text 520,a*40+70,"Computer","cc"
  fi

  if a=2 or a=6 then
    if (a=2 and snake(1,14)=1) or (a=6 and snake(2,14)=1) then
      setrgb 1,100,100,200
    else
      setrgb 1,100,100,100
    fi
    fill rectangle 370,a*40+50 to 470,a*40+80
    setrgb 1,0,0,0
    rectangle 370,a*40+50 to 470,a*40+80

    setrgb 1,255,255,255
    text 420,a*40+70,"Turning","cc"

    if (a=2 and snake(1,14)=2) or (a=6 and snake(2,14)=2) then
      setrgb 1,100,100,200
    else
      setrgb 1,100,100,100
    fi
    fill rectangle 470,a*40+50 to 570,a*40+80
    setrgb 1,0,0,0
    rectangle 470,a*40+50 to 570,a*40+80
    setrgb 1,255,255,255
    text 520,a*40+70,"Cardinal","cc"
  fi


  if a=3 or a=7 then
    for b=1 to 10
      if (a=3 and b=snake(1,12)) or (a=7 and b=snake(2,12)) then
        setrgb 1,100,100,200
      else
        setrgb 1,100,100,100
      fi

      fill rectangle 350+b*20,a*40+50 to 370+b*20,a*40+80
      setrgb 1,0,0,0
      rectangle 350+b*20,a*40+50 to 370+b*20,a*40+80
    next b
  fi

  if a=4 or a=8 then
    for b=1 to 10
      if (a=4 and b=snake(1,13)) or (a=8 and b=snake(2,13)) then
        setrgb 1,100,100,200
      else
        setrgb 1,100,100,100
      fi

      fill rectangle 350+b*20,a*40+50 to 370+b*20,a*40+80
      setrgb 1,0,0,0
      rectangle 350+b*20,a*40+50 to 370+b*20,a*40+80
    next b
  fi

end sub

label game_loop
  quit=0
  setrgb 0,50,100,50
  gosub reset_players

  gosub countdown

  repeat
    gosub flip_screen
    clear window

    gosub draw_goodies

    gosub draw_parts

    rem human player
    if snake(1,8)=1 then
      buttons=peek("port1")
      player=1
      gosub process_input
    fi

    rem computer player
    if snake(1,8)=2 then
      player=1
      if snake(player,9)=0 then
        gosub acquire_target
      else
        gosub aim
      fi
    fi

    rem human player
    if snake(2,8)=1 then
      buttons=peek("port2")
      player=2
      gosub process_input
    fi

    rem computer player
    if snake(2,8)=2 then
      player=2
      if snake(player,9)=0 then
        gosub acquire_target
      else
        gosub aim
      fi
    fi

    gosub move_parts
    gosub collide

    gosub new_goodies

    buttons=or(peek("port1"),peek("port2"))
    if and(buttons,8)=8 then
      gosub quittest
      if quit=1 then
        return
      fi
    fi

    win=0
    gosub check_win
  until (win>0)

  gosub win_screen
return

label countdown
  setdispbuf d
  setdrawbuf d
  for a=3 to 1 step -1
    clear window

    gosub draw_goodies

    gosub draw_parts

    setrgb 1,255,255,255
    text sw/2,sh/2-20,"Get Ready","cc"
    text sw/2,sh/2,str$(a),"cc"
    wait 1
  next a
return

label quittest
  setdispbuf d
  setdrawbuf d

  gosub waitfornoinput

  setrgb 1,100,100,100
  fill rectangle 220,200 to 420,300
  setrgb 1,0,0,0
  rectangle 220,200 to 420,300
  setrgb 1,255,255,255
  text 320,220,"Quit Game?","cc"
  gosub draw_yesno

  repeat
    buttons=or(peek("port1"),peek("port2"))

    if (and(buttons,128)=128) and quit=0 then
      quit=1
      gosub draw_yesno
    fi

    if (and(buttons,32)=32) and quit=1 then
      quit=0
      gosub draw_yesno
    fi

  until (and(buttons,16384)=16384)
return

label draw_yesno
  if quit=1 then
    setrgb 1,100,100,200
  else
    setrgb 1,100,100,100
  fi
  fill rectangle 240,240 to 300,280
  setrgb 1,0,0,0
  rectangle 240,240 to 300,280
  setrgb 1,255,255,255
  text 270,260,"Yes","cc"

  if quit=0 then
    setrgb 1,100,100,200
  else
    setrgb 1,100,100,100
  fi
  fill rectangle 340,240 to 400,280
  setrgb 1,0,0,0
  rectangle 340,240 to 400,280
  setrgb 1,255,255,255
  text 370,260,"No","cc"
return

label acquire_target
  if int(ran(10))<snake(player,13) then
    for a=1 to maxplayers
      if a<>player then
        if snake(a,5)>1 then
          snake(player,9)=1
          snake(player,10)=a
          snake(player,11)=snake(a,5)
        fi
      fi
    next a
    if snake(player,9)>0 then 
      return
    fi
  fi

  for a=1 to maxgoodies
    if goodies(a,3)>0 and goodies(a,3)<4 then
      snake(player,9)=2
      snake(player,10)=a
      snake(player,11)=0
    fi
  next a
  if snake(player,9)>0 then 
    return
  fi

  change=snake(player,7)
  angle=parts(player,1,3)+(int(ran(change*2))-change)
  if angle>360 then 
    angle=angle-360
  fi
  if angle<0 then 
    angle=angle+360
  fi
  parts(player,1,3)=angle

return

label aim
  if int(ran(11))>snake(player,13) then
    snake(player,9)=0
    return
  fi

  targtype=snake(player,9)
  targnum=snake(player,10)
  targsecnum=snake(player,11)

  if targtype=0 then return fi

  xpos=parts(player,1,1)
  ypos=parts(player,1,2)
  angle=parts(player,1,3)

  if targtype=1 then
    if snake(targnum,5)<targsecnum then
      snake(player,9)=0
      return
    fi
    tx=parts(targnum,targsecnum,1)
    ty=parts(targnum,targsecnum,2)
  fi

  if targtype=2 then
    if goodies(targnum,3)=0 or goodies(targnum,3)=4 then
      snake(player,9)=0
      return
    fi

    tx=goodies(targnum,1)
    ty=goodies(targnum,2)
  fi

  hx=cosines(angle)
  hy=sines(angle)
  dx=tx-xpos
  dy=ty-ypos
  normal=(hy*dx - hx*dy)

  if int(ran(12))<snake(player,12) then
    if normal>=0 then
      angle=angle-snake(player,7)
    else
      angle=angle+snake(player,7)
    fi
  else
    change=snake(player,7)
    angle=angle+(int(ran(change*2))-change)
  fi

  if angle>360 then 
    angle=angle-360
  fi
  if angle<0 then 
    angle=angle+360
  fi

  parts(player,1,3)=angle
return

label win_screen
  setdispbuf d
  setdrawbuf d

  clear window

  gosub draw_title
  setrgb 1,200,100,200
  text 50,50,"Game Over","lb"

  setrgb 1,150,150,255
  win$="Player "+str$(win)+" won the game, well done."
  text 60,100,win$

  setrgb 1,255,255,255
  text sw/2,sh-20,"Press the X button for the main menu","cc"

  gosub waitfornoinput
  repeat
    keyinput=or(peek("port1"),peek("port2"))
  until (and(keyinput,16384)=16384)
return

label check_win
  for player=1 to maxplayers
    if snake(player,5)=maxparts then
      win=player
      return
    fi
  next player
return

label reset_players
  snake(1,1)=100
  snake(1,2)=0
  snake(1,3)=0
  snake(1,4)=0
  snake(1,5)=3
  snake(1,6)=0
  snake(1,7)=spinspeed
  snake(1,9)=0
  snake(1,10)=0
  snake(1,11)=0

  snake(2,1)=0
  snake(2,2)=0
  snake(2,3)=100
  snake(2,4)=0
  snake(2,5)=3
  snake(2,6)=0
  snake(2,7)=spinspeed
  snake(2,9)=0
  snake(2,10)=0
  snake(2,11)=0

  for player=1 to maxplayers
    for part=1 to maxparts
      parts(player,part,1)=-400+(player*500)
      parts(player,part,2)=200
      if part=1 then
        parts(player,part,3)=mod(player*180+180,360)
      else
        parts(player,part,3)=delay*(part-1)
      fi
      for a=0 to delay
        dirs(player,part,a)=0
      next a
    next part
  next player
return

label draw_goodies
  for goodie=1 to maxgoodies
    if goodies(goodie,3) > 0 then
      goodietype=goodies(goodie,3)

      if goodietype=1 then
        setrgb 1,0,150,0
        fill circle goodies(goodie,1),goodies(goodie,2),10
      fi

      if goodietype=2 then
        setrgb 1,150,150,0
        fill circle goodies(goodie,1),goodies(goodie,2),10
      fi

      if goodietype=3 then
        setrgb 1,150,150,150
        fill circle goodies(goodie,1),goodies(goodie,2),10
      fi

      if goodietype=4 then
        setrgb 1,0,0,0
        fill circle goodies(goodie,1),goodies(goodie,2),10
      fi

      if goodies(goodie,4)>0 then
        goodies(goodie,4)=goodies(goodie,4)-1
      else
        goodies(goodie,3)=0
      fi
    fi

  next goodie
return

label new_goodies
  if (int(ran(100))<2) then
    place=0
    for a=1 to maxgoodies
      if place=0 then
        if goodies(a,3)=0 then
          goodies(a,1)=int(ran(sw/2))+sw/4
          goodies(a,2)=int(ran(sh/2))+sh/4
          goodies(a,3)=int(ran(numgoodietypes))+1
          goodies(a,4)=int(ran(4)+1)*100
          place=1
        fi
      fi
    next a
  fi
return

label process_input
  if snake(player,14)=1 then
    if and(buttons,32)=32 then
      parts(player,1,3)=parts(player,1,3)+int(snake(player,7))
      if parts(player,1,3)>360 then
        parts(player,1,3)=parts(player,1,3)-360
      fi
    fi
    if and(buttons,128)=128 then
      parts(player,1,3)=parts(player,1,3)-int(snake(player,7))
      if parts(player,1,3)<0 then
        parts(player,1,3)=parts(player,1,3)+360
      fi
    fi
  else
    xpos=parts(player,1,1)
    ypos=parts(player,1,2)
    angle=parts(player,1,3)
    up=0:down=0:right=0:left=0
    if and(buttons,16)>0 then up=1 fi
    if and(buttons,32)>0 then right=1 fi
    if and(buttons,64)>0 then down=1 fi
    if and(buttons,128)>0 then left=1 fi

    if up=1 and left=0 and right=0 then
      tx=xpos+cosines(270)
      ty=ypos+sines(270)
      gosub turnto
      parts(player,1,3)=angle      
      return
    fi
    if up=1 and right=1 then
      tx=xpos+cosines(315)
      ty=ypos+sines(315)
      gosub turnto
      parts(player,1,3)=angle      
      return
    fi
    if up=0 and right=1 and down=0 then
      tx=xpos+cosines(0)
      ty=ypos+sines(0)
      gosub turnto
      parts(player,1,3)=angle      
      return
    fi
    if right=1 and down=1 then
      tx=xpos+cosines(45)
      ty=ypos+sines(45)
      gosub turnto
      parts(player,1,3)=angle      
      return
    fi
    if right=0 and down=1 and left=0 then
      tx=xpos+cosines(90)
      ty=ypos+sines(90)
      gosub turnto
      parts(player,1,3)=angle      
      return
    fi
    if down=1 and left=1 then
      tx=xpos+cosines(135)
      ty=ypos+sines(135)
      gosub turnto
      parts(player,1,3)=angle      
      return
    fi
    if down=0 and left=1 and up=0 then
      tx=xpos+cosines(180)
      ty=ypos+sines(180)
      gosub turnto
      parts(player,1,3)=angle      
      return
    fi
    if left=1 and up=1 then
      tx=xpos+cosines(225)
      ty=ypos+sines(225)
      gosub turnto
      parts(player,1,3)=angle      
      return
    fi
  fi
return

label turnto
  hx=cosines(angle)
  hy=sines(angle)
  dx=tx-xpos
  dy=ty-ypos
  normal=(hy*dx - hx*dy)
  if normal>=0 then
    angle=angle-int(snake(player,7))
  else
    angle=angle+int(snake(player,7))
  fi

  if angle>360 then 
    angle=angle-360
  fi
  if angle<0 then 
    angle=angle+360
  fi
return

label face_centre
  mempointer=1
  repeat
    hx=cosines(angle)
    hy=sines(angle)
    dx=tx-xpos
    dy=ty-ypos
    normal=(hy*dx - hx*dy)

    memory(mempointer)=normal
    mempointer=mempointer+1
    if mempointer=5 then
      mempointer=1
    fi

    if normal>=0 then
      angle=angle-10
    else
      angle=angle+10
    fi

    if angle>360 then 
      angle=angle-360
    fi
    if angle<0 then 
      angle=angle+360
    fi
  until (memory(1)=memory(3) and memory(2)=memory(4))
return

label collide
  for player=1 to maxplayers
    ta=parts(player,1,3)
    x=parts(player,1,1)+(partsize*cosines(ta))
    y=parts(player,1,2)+(partsize*sines(ta))
    for sp=1 to maxplayers
      if sp<>player then
        if snake(sp,4)=0 and snake(sp,5)>1 then
          for part=1 to snake(sp,5)
            if snake(sp,4)=0 then
              tx=parts(sp,part,1)
              ty=parts(sp,part,2)
              if x>tx-partsize and x<tx+partsize and y>ty-partsize and y<ty+partsize then
                if snake(player,5)<maxparts and snake(player,6)=0 then
                  snake(player,5)=snake(player,5)+1
                  snake(player,6)=4
                  snake(sp,5)=snake(sp,5)-1
                  snake(sp,4)=flashlength

                  newpart=snake(player,5)
                  parts(player,newpart,1)=parts(player,newpart-1,1)
                  parts(player,newpart,2)=parts(player,newpart-1,2)
                  parts(player,newpart,3)=delay
                  dirs(player,newpart,1)=0
                fi
              fi
            fi
          next part
        fi
      fi
    next sp

    for sp=1 to maxgoodies
      if goodies(sp,3)>0 then
        tx=goodies(sp,1)
        ty=goodies(sp,2)
        if x>tx-partsize and x<tx+partsize and y>ty-partsize and y<ty+partsize then
          gosub getgoodie
        fi
      fi
    next sp
  next player
return

label getgoodie
  type=goodies(sp,3)
  goodies(sp,3)=0

  if type=1 and snake(player,6)=0 then
    if snake(player,5)<maxparts then
      snake(player,5)=snake(player,5)+1
      newpart=snake(player,5)
      parts(player,newpart,1)=parts(player,newpart-1,1)
      parts(player,newpart,2)=parts(player,newpart-1,2)
      parts(player,newpart,3)=delay
      dirs(player,newpart,1)=0
      snake(player,6)=4
    fi
  fi

  if type=2 then
    snake(player,4)=snake(player,4)+30
  fi

  if type=3 then
    snake(player,7)=snake(player,7)+10
  fi

  if type=4 then
    if snake(player,5)>1 then
      snake(player,5)=snake(player,5)-1
      snake(player,4)=snake(player,4)+30
    fi
  fi
return

label draw_parts
  for player=1 to maxplayers
    if snake(player,4)=0 then
      setrgb 1,snake(player,1),snake(player,2),snake(player,3)
    else
      if mod(snake(player,4),2)=1 then
      setrgb 1,snake(player,1),snake(player,2),snake(player,3)
      else
      setrgb 1,255,255,255
      fi
      snake(player,4)=snake(player,4)-1
    fi

  for part=snake(player,5) to 1 step -1
    x=parts(player,part,1)
    y=parts(player,part,2)

    fill circle x,y,partsize
    if part=1 then
      setrgb 1,255,255,255
      ta=parts(player,part,3)-eyespace
      if ta<0 then
        ta=ta+360
      fi
      fill circle x+(partsize*cosines(ta)),y+(partsize*sines(ta)),eyesize
      ta=ta+(eyespace*2)
      if ta>360 then
        ta=ta-360
      fi
      fill circle x+(partsize*cosines(ta)),y+(partsize*sines(ta)),eyesize
    fi

  next part
  next player
return

label move_parts
  for player=1 to maxplayers
    angle=parts(player,1,3)
    xpos=parts(player,1,1)
    ypos=parts(player,1,2)

    if xpos>sw or xpos<0 or ypos>sh or ypos<0 then 
      tx=sw/2
      ty=sh/2
      gosub face_centre
      parts(player,1,3)=angle
    fi

  for part=snake(player,5) to 1 step-1
    if part>1 then
      if parts(player,part,3)>0 then
        parts(player,part,3)=parts(player,part,3)-1
      else
        dirs(player,part,2)=dirs(player,part,1)
        dirs(player,part,1)=dirs(player,part-1,2)
        angle=dirs(player,part,1)
        parts(player,part,1)=parts(player,part,1)+movecos(angle)
        parts(player,part,2)=parts(player,part,2)+movesin(angle)
      fi
    else
        dirs(player,part,2)=dirs(player,part,1)
        dirs(player,part,1)=parts(player,part,3)
        angle=dirs(player,part,1)
        parts(player,part,1)=parts(player,part,1)+movecos(angle)
        parts(player,part,2)=parts(player,part,2)+movesin(angle)
    fi

  next part

  if snake(player,7)>spinspeed then
    snake(player,7)=snake(player,7)-0.1
  fi

  if snake(player,6)>0 then
    snake(player,6)=snake(player,6)-1
  fi

  next player

return

label flip_screen
  setdispbuf d 
  d=1-d
  setdrawbuf d
return

label initialise
  sw=640
  sh=512

  flashlength=30
  maxparts=8
  partsize=10
  spinspeed=5
  eyesize=partsize/3
  eyespace=30
  movespeed=4
  delay=2

  maxgoodies=3
  numgoodietypes=4
  goodiesize=10
  dim goodies(maxgoodies,4)
  rem 1=x position
  rem 2=y position
  rem 3=type
  rem   0=inactive
  rem   1=extra tail
  rem   2=immunity
  rem   3=turn faster
  rem   4=lose a part
  rem 4=life

  for a=1 to maxgoodies
    goodies(a,3)=0
  next a

  maxplayers=2
  dim snake(maxplayers,14)
  rem 1=red
  rem 2=green
  rem 3=blue
  rem 4=flash
  rem 5=length
  rem 6=grow delay
  rem 7=turn speed
  rem 8=player type
  rem   0=none
  rem   1=player
  rem   2=computer
  rem 9=target type
  rem   0=none
  rem   1=player
  rem   2=goodie
  rem 10=target number
  rem 11=secondary target number
  rem 12=computer reactions
  rem 13=computer aggressiveness
  rem 14=control type
  rem   1=turning
  rem   2=cardinal

  dim parts(maxplayers, maxparts, 3)
                  rem 1=x coord 
                  rem 2=y coord
                  rem 3=angle/delay

  dim dirs(maxplayers, maxparts,delay)

  gosub reset_players
  snake(1,8)=1
  snake(1,12)=5
  snake(1,13)=5
  snake(1,14)=1
  snake(2,8)=2
  snake(2,12)=5
  snake(2,13)=5
  snake(2,14)=1

  d=1

  dim cosines(360)
  dim sines(360)
  dim movecos(360)
  dim movesin(360)

  for a=0 to 360
    cosines(a)=cos(a*(pi/180))
    sines(a)=sin(a*(pi/180))
    movecos(a)=movespeed*cosines(a)
    movesin(a)=movespeed*sines(a)
  next a

  titlelines=21
  dim title$(titlelines)
  for a=1 to titlelines
    title$(a)=""
  next a

  title$(1)="Welcome to Snake Bite."
  title$(3)="Snake Bite is a game involving ... snakes."
  title$(5)="The object of the game is to make your snake"
  title$(6)="as large as possible by either eating the"
  title$(7)="green food lying around the screen, or by"
  title$(8)="hunting down and eating the other snake on"
  title$(9)="the screen.  Of course, whilst you are doing"
  title$(10)="this, your opponent is trying to do the"
  title$(11)="same thing."
  title$(13)="As well as the green food, there are other"
  title$(14)="things that will appear on the screen. They"
  title$(15)="are yellow invulnerability snacks, white"
  title$(16)="super spin snacks, and nasty black poison."
  title$(18)="Be careful of the poison, it will cause the"
  title$(19)="end of your tail to drop off."
  title$(21)="Happy hunting."

  helplines=20
  dim help$(helplines)
  for a=1 to helplines
    help$(a)=""
  next a

  help$(1)="The aim of the game is to have a snake that"
  help$(2)="is "+str$(maxparts)+" segments long."
  help$(4)="The only controls are left and right which"
  help$(5)="are used to turn the snake's head left and"
  help$(6)="right.  The snake moves forwards on its own"
  help$(8)="The snakes mouth is between its eyes, so"
  help$(9)="don't get annoyed when you miss collecting a"
  help$(10)="piece of food because you side-swiped it."
  help$(12)="A quick reminder of the things you can collect:"
  help$(14)="     Green : Food, gain an extra body part"
  help$(15)="    Yellow : Temporary Invulnerability"
  help$(16)="     White : Increased turning ability"
  help$(17)="     Black : Poison, lose a body part"
  help$(19)="Don't forget you can gain extra body parts"
  help$(20)="by biting the tail of your opponent."

  numoptions=4
  dim options$(numoptions)
  options$(1)="Play Game"
  options$(2)="Options"
  options$(3)="Help"
  options$(4)="Return to title"

  numchoices=9
  dim choices$(numchoices)
  choices$(1)="Player 1 Type"
  choices$(2)="Player 1 Control"
  choices$(3)="Player 1 Reactions"
  choices$(4)="Player 1 Aggressiveness"
  choices$(5)="Player 2 Type"
  choices$(6)="Player 2 Control"
  choices$(7)="Player 2 Reactions"
  choices$(8)="Player 2 Aggressiveness"
  choices$(9)="Return to Menu"

  dim hints$(numchoices)
  hints$(1)="Controlled by Human or Computer"
  hints$(2)="Control method"
  hints$(3)="Computer reaction speed"
  hints$(4)="Computer aggressiveness and determination"
  hints$(5)="Controlled by Human or Computer"
  hints$(6)="Control method"
  hints$(7)="Computer reaction speed"
  hints$(8)="Computer aggressiveness and determination"
  hints$(9)="Press X to return to the Main Menu"

  dim memory(4)

  open window sw,sh
  clear window
return


