remstart
   ==============================================================
   =  Title  : tic tac toe
   =  Author : latch
   =  Date   : 07/09/2007
   =  Update :
   =  Version: v.01
   ==============================================================
   Comments
   ==============================================================
remend
 
rem =============================================================
rem = SET UP DISPLAY
rem =============================================================
   autocam off
   set display mode 800,600,32
   sync on
   sync rate 60
 
rem =============================================================
rem = MAIN
rem =============================================================
   gosub _init
   do
 
      gosub _redraw_board
      gosub _player_move
      gosub _winner
      gosub _ai
 
      sync
   loop
 
   end
 
rem =============================================================
rem = SUBROUTINES - PROCEDURES
rem =============================================================
   _init:
      randomize timer()
      player=rnd(1)
      dim square(9)
      for n=1 to 9
         square(n)=0
      next n
      dim linerun(8,3)
      count=0
      lineup=0
      movecount=0
 
      gosub _linesetup
   return
`----------------------------------------------------------------
   _linesetup:
      rem vertical
      for n=1 to 3
         inc count
         linerun(count,1)=n
         linerun(count,2)=n+3
         linerun(count,3)=n+6
      next n
 
      rem horizontal
      for n=1 to 7 step 3
         inc count
         linerun(count,1)=n
         linerun(count,2)=n+1
         linerun(count,3)=n+2
      next n
 
      rem diaganol
      linerun(7,1)=1
      linerun(7,2)=5
      linerun(7,3)=9
      linerun(8,1)=3
      linerun(8,2)=5
      linerun(8,3)=7
   return
`----------------------------------------------------------------
   _ai:
      rem computers turn
      if movecount < 9
 
         if player=0
            `text 0,120,"AI's Turn"
            rem check for winning
            for n=1 to 8
               for m=1 to 3
                  a=a+square(linerun(n,m))
               next m
               if a=-2
                  lineup=n
                  a=0
                  goto _b_or_w
               else
                  a=0
               endif
            next n
 
            rem check for blocking
            `a=0
            for n=1 to 8
               for m=1 to 3
                  a=a+square(linerun(n,m))
               next m
               if a=2
                  lineup=n
                  a=0
               else
                  a=0
               endif
            next n
 
            _b_or_w:
            rem block or win
            if lineup > 0
               for m=1 to 3
                  if square(linerun(lineup,m))=0
                     square(linerun(lineup,m))=-1
                  endif
               next m
               inc movecount
            else
               rem move in the center if it's available
               if square(5)=0
                  square(5)=-1
               else
                  while moved = 0
                     choice=rnd(8)+1
                     if square(choice)=0
                        square(choice)=-1
                        moved=1
                     endif
                  endwhile
                  moved=0
               endif
               inc movecount
            endif
            lineup=0
            player = 1-player
            gosub _redraw_board
         endif
      endif
   return
`----------------------------------------------------------------
   _redraw_board:
      cls
      horz=3
      vert=3
      sizex=150
      sizey=150
      x1=150
      y1=100
      set text font "Arial"
      set text size 172
      grid(x1,y1,horz,vert,sizex,sizey,RGB(255,255,0),RGB(128,128,192))
      for y=0 to 2
         for x=1 to 3
            cell=(horz*y)+x
            if square(cell)=1
               text ((x-1)*sizex)+x1+18,(y*sizey)+y1,"O"
            endif
            if square(cell)=-1
               text ((x-1)*sizex)+x1+26,(y*sizey)+y1,"X"
            endif
         next x
      next y
      set text size 72
      center text screen width()/2 - 30,0,"TIC TAC TOE"
      set text size 20
      center text screen width()/2 -30,68,"by Latch"
      mouse_cell(horz,vert,sizex,sizey,x1,y1)
   return
`----------------------------------------------------------------
   _player_move:
      if player=1
         if mouseclick()=1
            cell=mouse_cell(horz,vert,sizex,sizey,x1,y1)
            if cell > 0
               if square(cell)=0
                  square(cell)=1
                  repeat
                     rem wait for mouse release
                  until mouseclick()=0
                  player=1-player
                  inc movecount
                  gosub _redraw_board
               endif
               `if movecount=9 then break
            endif
         endif
      endif
   return
`----------------------------------------------------------------
   _winner:
      a=0
      set text size 88
      set text opaque
      ink rgb(255,0,0),0
      if movecount=9
         for n=1 to 8
            for m=1 to 3
               a=a+square(linerun(n,m))
            next m
            if a=3
               gosub _victory_line
               Repeat
                  center text screen width()/2,0,"Human Wins!!!"
                  sync
               Until scancode()<>0
               rem reset everything
               for j=1 to 9
                  square(j)=0
                  movecount=0
                  lineup=0
                  n=8
                  player=rnd(1)
               next j
            endif
            if a=-3
               gosub _victory_line
               Repeat
                  center text screen width()/2,0,"Computer Wins!!!"
                  sync
               Until scancode()<>0
               rem reset everything
               for j=1 to 9
                  square(j)=0
                  movecount=0
                  lineup=0
                  n=8
                  player=rnd(1)
               next j
            endif
            a=0
         next n
         if a=0
            Repeat
               center text screen width()/2,screen height()/2,"It's a Cat!!!"
               sync
            Until scancode()<>0
               rem reset everything
               for j=1 to 9
                  square(j)=0
                  movecount=0
                  lineup=0
                  n=8
                  player=rnd(1)
               next j
         endif
      else
         a=0
         for n=1 to 8
            for m=1 to 3
               a=a+square(linerun(n,m))
            next m
            if a=3
               gosub _victory_line
               Repeat
                  center text screen width()/2,0,"Human Wins!!!"
                  sync
               Until returnkey()=1
               rem reset everything
               for j=1 to 9
                  square(j)=0
                  movecount=0
                  lineup=0
                  n=8
                  player=rnd(1)
               next j
            endif
            if a=-3
               gosub _victory_line
               Repeat
                  center text screen width()/2,0,"Computer Wins!!!"
                  sync
               Until returnkey()=1
               rem reset everything
               for j=1 to 9
                  square(j)=0
                  movecount=0
                  lineup=0
                  n=8
                  player=rnd(1)
               next j
            endif
            a=0
         next n
      endif
      set text transparent
   return
`----------------------------------------------------------------
   _victory_line:
      select n
         case 1 : thick_line(150+75,100,150+75,100+(3*150),10) : endcase
         case 2 : thick_line(150+75+(1*150),100,150+75+(1*150),100+(3*150),10) : endcase
         case 3 : thick_line(150+75+(2*150),100,150+75+(2*150),100+(3*150),10) : endcase
         case 4 : thick_line(150,100+(150/2),150+(3*150),100+(150/2),10) : endcase
         case 5 : thick_line(150,100+(150/2)+150,150+(3*150),100+(150/2)+150,10) : endcase
         case 6 : thick_line(150,100+(150/2)+(2*150),150+(3*150),100+(150/2)+(2*150),10) : endcase
         case 7 : thick_line(150,100,150+(3*150),100+(3*150),10) : endcase
         case 8 : thick_line(150,100+(3*150),150+(3*150),100,10) : endcase
      endselect
   return
rem =============================================================
rem = FUNCTIONS
rem =============================================================
   Function Grid(XPosition,YPosition,Columns,Rows,XSize,YSize,CellColourF,CellColourB)
      rem grid function by TDK_Man
      Ink CellColourB,0
      Box XPosition,YPosition,XPosition+(Columns*(XSize+1)),YPosition+(Rows*(YSize+1))
      Ink CellColourF,0
      For N=0 To Rows
         Line XPosition,  N*(YSize+1)+YPosition,  Columns*(XSize+1)+XPosition,  N*(YSize+1)+YPosition
      Next N
      For N=0 To Columns
         Line N*(XSize+1)+XPosition,  YPosition,  N*(XSize+1)+XPosition,  Rows*(YSize+1)+YPosition
      Next N
   Endfunction
`----------------------------------------------------------------
   function thick_line(x1,y1,x2,y2,thickness)
      for n=0 to thickness-1
         if x1<>x2 then line x1,y1+n,x2,y2+n
         if x1=x2 then line x1+n,y1,x2+n,y2
      next n
   endfunction
`----------------------------------------------------------------
`----------------------------------------------------------------
   function mouse_cell(horz,vert,cellsizex,cellsizey,x1offset,y1offset)
      result=0
      rem find actual cell
      cellx=int((mousex()-x1offset)/(cellsizex+1))+1
      celly=int((mousey()+(cellsizey-y1offset))/(cellsizey+1))+1
      celly=vert-((vert-celly)+1)
      if (cellx > horz or cellx < 1 or mousex()< x1offset) or (celly > vert or celly < 1 or mousey()<y1offset)
         cellx=0
         celly=0
      endif
      curcell=((celly-1)*horz)+cellx
      if curcell <= 0 then curcell=0
 
      rem return selected cell
      if mouseclick()=1 and curcell > 0
         result=curcell
      endif
   endfunction result