rem Date: Oct. 20, 2006
rem Author: acelepage
rem Program: Maximum
rem coding challenge: maths game
 
set display mode 1024,768,32
hide mouse
backdrop on
color backdrop 0
sync on
dim titleblock#(7)
dim screenx#(2)
dim direction#(2)
dim score(2)
dim name$(2)
dim score_image(2)
dim playerbox(2)
dim selection$(2)
title$="MAXIMUM"
place$="2559232"
selection$(1)="row"
selection$(2)="column"
screenx#(1)=-50.0:screenx#(2)=270.0
direction#(1)=-4.0:direction#(2)=4.0
score(1)=0:score(2)=0
screeny#=-25.0
centerx#=105.0:centery#=105.0
factor=250
namefont$="arial"
scorefont$="courier"
rem Images
rem cubes: 1 - 64
rem title blocks: 65 - 71
score_image(1)=72
score_image(2)=73
boxframe_image=74
scorebox=75
rem Objects
rem cubes: 1 - 64
rem title blocks: 65 - 71
frame1=72
frame2=73
boxframe=74
playerbox(1)=75
playerbox(2)=76
 
rem Generate some arcade sounds
for num=1 to 3
  make_sound(num)
next num
set sound volume 1,100
set sound volume 2,90
set sound volume 3,90
rem Make the number cubes
create bitmap 1,20,20
for i=1 to 64
  make object cube i,20
  color object i,rgb(255,250,240)
  set object i,1,1,1,1,1,0,1
  set current bitmap 1
  ink rgb(0,0,255),0
  box 1,1,20,20
  set cursor 12-len(str$(i))*5,3
  ink rgb(255,255,255),0
  set text size 10
  print i
  get image i,1,1,20,20,1
  set current bitmap 0
  texture object i,i
  set object texture i,2,1
  hide object i
next i
delete bitmap 1
 
rem Title blocks
create bitmap 1,40,40
for x=1 to 7
  make object cube x+64,20
  ink rgb(0,0,255),0
  box 1,1,40,40
  set text font "arial"
  set text size 35
  for i=1 to 8
    ink rgb(i*25,i*25,i*25),0
    set cursor i+val(mid$(place$,x))+2,i
    print mid$(title$,x)
  next i
  get image x+64,1,1,40,40,1
  texture object x+64,x+64
  set object texture x+64,2,1
  hide object x+64
next x
 
rem selection box
create bitmap 1,2,2
ink rgb(255,0,0),0
box 1,1,2,2
get image boxframe,1,1,2,2
delete bitmap 1
make object box frame2,250,3,20
make mesh from object frame2,frame2
delete object frame2
make object plain boxframe,250,30
texture object boxframe,boxframe_image
add limb boxframe,1,frame2
offset limb boxframe,1,0.0,16.5,10.0
texture limb boxframe,1,boxframe_image
add limb boxframe,2,frame2
offset limb boxframe,2,0.0,-16.5,10.0
texture limb boxframe,2,boxframe_image
fade object boxframe,0
hide object boxframe
delete object frame2
delete mesh frame2
row=0
col=3
framex#=centerx#
framey#=row*30.0
framez#=15.0
 
rem score boxes
create bitmap 1,2,2
ink rgb(0,255,0),0
box 1,1,2,2
get image scorebox,1,1,2,2,1
delete bitmap 1
for x=1 to 2
  make object box playerbox(x),30,30,3
  texture object playerbox(x),scorebox
  make mesh from object frame2,playerbox(x)
  add limb playerbox(x),1,frame2
  rotate limb playerbox(x),1,0.0,90.0,0.0
  offset limb playerbox(x),1,13.9,0.0,13.6
  texture limb playerbox(x),1,scorebox
  add limb playerbox(x),2,frame2
  rotate limb playerbox(x),2,0.0,90.0,0.0
  offset limb playerbox(x),2,-13.9,0.0,13.6
  texture limb playerbox(x),2,scorebox
  add limb playerbox(x),3,frame2
  offset limb playerbox(x),3,0.0,0.0,28.5
  texture limb playerbox(x),3,scorebox
next x
delete object frame2
delete mesh frame2
rem Prepare for applying player names to score boxes
create bitmap 1,60,60
set current bitmap 0
 
camx#=120.0:camy#=120.0:camz#=-300.0
position light 0,100.0,100.0,-250.0
position camera camx#,camy#,camz#
point camera camx#,camy#,0.0
 
start_main:
hide object playerbox(1)
hide object playerbox(2)
position object playerbox(1),screenx#(1),screeny#,framez#-45.0
position object playerbox(2),screenx#(2),screeny#,framez#-45.0
show_title(boxframe,centerx#)
 
rem Get player's names
name$(1)=""
name$(2)=""
pick=0
player=1
while player<3
  ink rgb(0,0,255),0
  box factor*player-20,360,factor*player+200,460
  ink rgb(0,0,64),0
  box factor*player-15,365,factor*player+195,455
  if player=2
    ink rgb(0,0,255),0
    box factor-20,360,factor+200,460
    ink rgb(0,0,64),0
    box factor-15,365,factor+195,455
    ink rgb(255,255,255),0
    set text font "courier"
    set text size 10:set cursor factor,380
    print "Player 1"
    set cursor factor,405
    print "Name: ";name$(1)
  endif
  ink rgb(255,255,255),0
  set text font "courier"
  if pick=0
    set text size 10:set cursor factor*player,380
    print "Player ";player
    set cursor factor*player,405
    print "A) Human"
    set cursor factor*player,430
    print "B) Computer"
  endif
  i$=entry$():clear entry buffer
  if (i$="A" or i$="a") and pick=0
    pick=1
    i$="":while inkey$()<>"":endwhile
  endif
  if (i$="B" or i$="b") and pick=0
    pick=2
    i$="":while inkey$()<>"":endwhile
  endif
  if pick=1
    set text size 10:set cursor factor*player,380
    print "Player ";player
    set cursor factor*player,405
    print "Name: ";name$(player);
    if ((int(timer()/500)) && 1) then print "_"
    if i$=chr$(13)
      pick=3
    else
      if i$=chr$(8)
        if len(name$(player))>1
          name$(player)=left$(name$(player),len(name$(player))-1)
        else
          name$(player)=""
        endif
      else
        name$(player)=name$(player)+i$
      endif
    endif
  endif
  if pick=2
    name$(player)="Computer"
    pick=3
  endif
  if pick=3
    inc player
    pick=0
  endif
  instructions()
  sync
endwhile
for x=1 to 7
  hide object x+64
next x
hide object boxframe
 
rem Put names on score boxes
for player=1 to 2
  set current bitmap 1
  ink rgb(0,255,0),0
  box 1,1,60,60
  ink rgb(255,0,0),0
  set text font namefont$
  set text size 12
  set text to bold
  text 30-len(name$(player))*3,10,name$(player)
  get image score_image(player),1,1,60,60,1
  set current bitmap 0
  texture limb playerbox(player),0,score_image(player)
next player
 
rem Randomize the numbers on screen
dim num(64)
dim numz#(64)
initialz#=300.0
zoom#=10.0
for i=1 to 64
  num(i)=0
next i
match=1
randomize timer()
play sound 1
while ( match <= 64)
  if (match = 64)
    for i=1 to 64
      if (num(i)=0) then x=i
    next i
  else
    x=rnd(63)+1
  endif
  if num(x)=0
    num(x)=match
    numz#(x)=initialz#
    position object match,int((x-1)/8)*30,(8-((x-1) mod 8))*30,numz#(x)
    show object match
    inc match
  endif
  for i=1 to 64
    if num(i)>0 and numz#(i)>0.0
      numz#(i)=numz#(i)-zoom#
      position object num(i),int((i-1)/8)*30,((i-1) mod 8)*30,numz#(i)
    endif
  next i
  sync
endwhile
lineup=0
while not lineup
  lineup=1
  for i=1 to 64
    if num(i)>0 and numz#(i)>0.0
      lineup=0
      numz#(i)=numz#(i)-zoom#
      position object num(i),int((i-1)/8)*30,((i-1) mod 8)*30,numz#(i)
    endif
  next i
  sync
endwhile
 
fade=0
show object playerbox(1)
show object playerbox(2)
show object boxframe
position object boxframe,framex#,framey#,framez#
while fade<100
  fade object boxframe,fade
  fade=fade+2
  sync
endwhile
 
rem Start with horizontal player
picks=0
player=1
if name$(player)="Computer"
  computer_pick=1
  hide mouse
else
  computer_pick=0
  show mouse
endif
 
while (picks<64)
  if mouseclick()=1 or computer_pick=1
    if computer_pick=0
      test=pick object(mousex(),mousey(),1,64)
    else
      gosub computer_move
    endif
    if test>0
      posx#=object position x(test)
      posy#=object position y(test)
      posz#=object position z(test)
      correct=0
      if player=1
        if posy#=(row*30.0)
          correct=1
        endif
      else
        if posx#=(col*30.0)
          correct=1
        endif
      endif
      if correct=1
        inc picks
        row=int(posy#/30.0)
        col=int(posx#/30.0)
        if player=2
          movementy#=(posy#-framey#)/45
          movementx#=0.0
        else
          movementx#=(posx#-framex#)/45
          movementy#=0.0
        endif
        rem Shrink frame to selected block
        play sound 2
        for size=99 to 9 step -2
          scale object boxframe,size,100,100
          framex#=framex#+movementx#
          framey#=framey#+movementy#
          position object boxframe,framex#,framey#,framez#
          sync
        next size
        framex#=posx#
        framey#=posy#
        rem Move block forward
        for z#=framez# to framez#-20.0 step -1.0
          position object boxframe,framex#,framey#,z#
          posz#=posz#-0.5
          position object test,posx#,posy#,posz#
          sync
        next z#
        rem Rotate frame
        if player=2
          for a#=90.0 to 0.0 step -5.0
            zrotate object boxframe,a#
            sync
          next a#
        endif
        rem Move block to side of screen
        set sound volume 3,100
        play sound 3
        for x#=posx# to screenx#(player) step direction#(player)
          position object test,x#,posy#,posz#
          sync
        next x#
        rem Move block into score box
        for y#=posy# to screeny# step -4.0
          position object test,x#,y#,posz#
          sync
        next y#
        hide object test
        rem Update score
        set text transparent
        set text to normal
        newscore=score(player)+test
        while score(player)<newscore
          if sound volume(3)>0 then set sound volume 3,sound volume(3)-1
          set current bitmap 1
          ink rgb(0,255,0),0
          box 1,1,60,60
          ink rgb(255,0,0),0
          jump=int((newscore-score(player))/10+1)
          score(player)=score(player)+jump
          set text font namefont$
          set text size 12
          set text to bold
          text 30-len(name$(player))*3,10,name$(player)
          set text font scorefont$
          set text size 20
          text 30-len(str$(score(player)))*8,30,str$(score(player))
          get image score_image(player),1,1,60,60,3
          set current bitmap 0
          texture limb playerbox(player),0,score_image(player)
          sync
        endwhile
        fade object playerbox(player),100
        rem Rotate frame
        if player=1
          for a#=0.0 to 90.0 step 5.0
            zrotate object boxframe,a#
            sync
          next a#
        endif
        rem Move frame back into play
        for z#=framez#-20.0 to framez#
          position object boxframe,framex#,framey#,z#
          sync
        next z#
        rem Expand frame
        if player=1
          movementy#=(centery#-framey#)/45
          movementx#=0.0
        else
          movementx#=(centerx#-framex#)/45
          movementy#=0.0
        endif
        for size=10 to 100 step 2
          scale object boxframe,size,100,100
          framex#=framex#+movementx#
          framey#=framey#+movementy#
          position object boxframe,framex#,framey#,framez#
          sync
        next size
        if player=1
          framex#=col*30.0
          framey#=centery#
        else
          framey#=row*30.0
          framex#=centerx#
        endif
        rem Remove number from grid
        for x=1 to 64
          if num(x)=test then num(x)=0
        next x
        rem Switch to other player
        inc player
        if player=3 then player=1
        if (name$(player) = "Computer")
          hide mouse
          computer_pick=1
        else
          show mouse
          computer_pick=0
          gosub check_for_end
        endif
      endif
    endif
  else
    set text font "arial"
    set text size 30
    set text to bold
    ink rgb(255,255,255),0
    text 250,10,name$(player)+", select a number from the "+selection$(player)
  endif
  sync
endwhile
if score(1)>score(2)
  score(1)=1
  score(2)=0
else
  if score(2)>score(1)
    score(2)=1
    score(1)=0
  else
    score(1)=1
    score(2)=1
  endif
endif
hide object boxframe
grow=100
play sound 1
while grow<200
  for x=1 to 2
    if score(x)=1
      scale object playerbox(x),grow,grow,grow
      position object playerbox(x),object position x(playerbox(x))-direction#(x)/2.0,object position y(playerbox(x))+2.0,object position z(playerbox(x))
    else
      fade object playerbox(x),fade
      dec fade
    endif
  next x
  grow=grow+2
  sync
endwhile
set text font "arial"
set text size 20
set text to bold
text 450,10,"Press any key"
sync
while inkey$()<>"":endwhile
while inkey$()="":endwhile
scale object playerbox(1),100,100,100
scale object playerbox(2),100,100,100
for x=1 to 64
  hide object x
next x
goto start_main
end
 
check_for_end:
  found=0
  set cursor 0,10
  for x=1 to 8
    if player=1
      i=(x-1)*8+row+1
    else
      i=col*8+x
    endif
    if num(i)>0
      found=1
    endif
  next x
  if found=0
    picks=65
  endif
return
computer_move:
  count=1
  top=-64
  comppick=0
  found=0
  set cursor 0,10
  for x=1 to 8
    if player=1
      i=(x-1)*8+row+1
    else
      i=col*8+x
    endif
    if num(i)>0
      found=1
      max=0
      for y=0 to 7
        if player=1
          j=(x-1)*8+y+1
        else
          j=y*8+x
        endif
        if j<>i
          if num(j)>max then max=num(j)
        endif
      next y
      diff=num(i)-max
      if diff>top
        top=diff
        comppick=num(i)
      endif
    endif
  next x
  if found=0
    picks=65
    test=0
  else
    test=comppick
  endif
return
function make_sound(number)
  format as dword
  channels as dword
  sampleRate as dword
  adr as dword
  chunkSize as dword
  sampleSize as dword
  dword7 as dword
  format=1
  channels=1
  sampleRate=22050
  sampleSize=16
  chunkSize=(int(sampleSize / 8.0+0.5))*channels
  adr=sampleRate*chunkSize
  dword7=0
  select number
    case 1
      wave#=0.0
      increment#=10.0
      gain#=0.05
      amplitude=65535
      decay=0
      length = 3000
    endcase
    case 2
      wave#=0.0
      increment#=1.0
      gain#=0.01
      amplitude=65000
      decay=100
      length = 1000
    endcase
    case 3
      wave#=0.0
      increment#=-1.0
      gain#=0.0
      amplitude=65000
      decay=1
      length = 2000
    endcase
  endselect
  samples = length*sampleRate/1000
  size = samples*int(sampleSize/8.0+0.5) + 28
  make memblock 1, size
  write memblock dword 1, 0, format
  write memblock dword 1, 4, channels
  write memblock dword 1, 8, sampleRate
  write memblock dword 1, 12, adr
  write memblock dword 1, 16, chunkSize
  write memblock dword 1, 20, sampleSize
  write memblock dword 1, 24, dword7
  pos=28
  out as word
  for i=1 to samples
      out=sin(wave#)*amplitude
      write memblock word 1, pos, out
      inc pos, 2
      wave#=wave#+increment#
      if wave#>360.0
        wave#=wave#-360.0
        increment#=increment#-gain#
      endif
      amplitude=amplitude-decay
  next i
  make sound from memblock number,1
  delete memblock 1
endfunction
function instructions()
  left=50
  top=550
  ink rgb(0,255,0),0
  box left-10,top-10,left+900,top+140
  ink rgb(0,64,0),0
  box left-5,top-5,left+895,top+135
  ink rgb(255,255,255),0
  set text font "arial"
  set text size 16
  set text to normal
  set cursor left,top
  print "Object: get a higher score than your opponent"
  set cursor left,top+30
  print "Game Play: players take turns picking numbers from an 8x8 grid or 64 numbers."
  set cursor left+70,top+50
  print " First player selects from a row, second player selects from a column."
  set cursor left+70,top+70
  print " The number you pick defines the next row or column for the next move."
  set cursor left,top+110
  print "Winning: the game is completed when all numbers have been picked, or no numbers are left in your column/row"
endfunction
function show_title(boxframe,centerx#)
  show object boxframe
  fade object boxframe,100
  position object boxframe,centerx#,162.0,-60.0
  play sound 3
  for x=1 to 7
    show object x+64
    for y=300 to centerx#+(x-4)*30 step -8
      position object x+64,y,160.0,-80.0
      sync
    next y
    y=centerx#+(x-4)*30
    position object x+64,y,160.0,-80.0
  next x
endfunction