Challenge: 
Winner?: 
Yes
Code Snippet: 
sync on
sync rate 60

disable escapekey

color backdrop rgb(0,0,0)
global blackimage = 1
get image blackimage, 0, 0, screen width(), screen height(), 1

global greenimage = 2
create bitmap 1, 10, 10
box 0, 0, 10, 10, rgb(0, 255, 0), rgb(0, 255, 0), rgb(0, 255, 0), rgb(0, 255, 0)
get image greenimage, 0, 0, 10, 10
delete bitmap 1

global redimage = 3
create bitmap 1, 10, 10
box 0, 0, 10, 10, rgb(255, 0, 0), rgb(255, 0, 0), rgb(255, 0, 0), rgb(255, 0, 0)
get image redimage, 0, 0, 10, 10
delete bitmap 1

`board
type boardtype
   objid
   xpos
   ypos
   piece$
   player
endtype

dim board(3,3) as boardtype

overlap = 1

for x = 1 to 3
   for y = 1 to 3
      board(x,y).objid = freeid()
      make object cube board(x,y).objid, 10 + overlap
      ghost object on board(x,y).objid
      position object board(x,y).objid, x*10 - 20, y*10 - 20, 0
      board(x,y).xpos = x*10 - 20
      board(x,y).ypos = y*10 - 20
   next y
next x
`/board

`pieces
type piecetype
   objoid
   objxid
   type$
endtype

dim piece(3,3) as piecetype

osize = 6
xsize = 8

for x = 1 to 3
   for y = 1 to 3
      `O
      piece(x,y).objoid = freeid()
      make object sphere piece(x,y).objoid, osize
      
      set object ambient piece(x,y).objoid, 0
      exclude object on piece(x,y).objoid
      
      `X
      piece(x,y).objxid = freeid()
      make object box piece(x,y).objxid, xsize, xsize/5, xsize/5
      
      make mesh from object 1, piece(x,y).objxid
      zrotate object piece(x,y).objxid, 135
      
      add limb piece(x,y).objxid, 1, 1
      rotate limb piece(x,y).objxid, 1, 0, 0, 90  
      delete mesh 1
      
      set object ambient piece(x,y).objxid, 0
      exclude object on piece(x,y).objxid
   next y
next x

`/pieces

`camera
position camera 0, 0, -30
point camera 0,0,0
`/camera

`does the computer go first?
global computerfirst = 0

menuplace:
gosub menu

`if the computer gets to go first
if computerfirst = 1
   `place it's first piece in any one of the four corners
   select (rnd(3) + 1)
      case 1
         place_piece(1, 1, "X", 1)
      endcase
      case 2
         place_piece(1, 3, "X", 1)
      endcase
      case 3
         place_piece(3, 1, "X", 1)
      endcase
      case 4
         place_piece(3, 3, "X", 1)
      endcase
   endselect
endif

`records what the human player does
dim playermove(4) as string
global currentplayermove = 0

global placed = 0
global playertype$
global computertype$

if computerfirst = 1
   playertype$ = "O"
   computertype$ = "X"
else
   playertype$ = "X"
   computertype$ = "O"
endif

do
   center text screen width()/2, 30, "Place your " + playertype$
   
   if placed = 0
      gosub selectsquare
   endif
   
   gosub check_for_win
   
   if placed = 1
      gosub computerturn
   endif
   
   gosub check_for_win
   
   if escapekey() = 1
      gosub clearpieces
      goto menuplace
   endif
 
   sync   
loop

function place_piece(x as integer, y as integer, type$, computer)
   if type$ = "O"
      tempid = piece(x,y).objoid
   endif
   if type$ = "X"
      tempid = piece(x,y).objxid
   endif
   
   exclude object off tempid
      
   if computer = 1
      texture object tempid, redimage
      board(x,y).player = 1
   else
      texture object tempid, greenimage
      board(x,y).player = -10
   endif
   
   position object tempid, board(x,y).xpos, board(x,y).ypos, 0
   
   board(x,y).piece$ = type$
endfunction


`this function goes through the objects and finds the first object id that is not used
function freeid() 
   id = 0 
   i = 0 
   repeat
      inc i 
      if object exist(i) = 0 then id = i 
   until id > 0 `go until we find a "empty" i and assign it to id
   lastfreeobject = id
endfunction id

computerturn:
   computerplayed = 0
   
   `first check to see if we can win

   `horizontals
   for y = 1 to 3
      `if we have two on a row
      if (board(1,y).player + board(2,y).player + board(3,y).player) = 2
         for x = 1 to 3
            if board(x,y).piece$ = "" and computerplayed = 0
               place_piece(x, y, computertype$, 1)
               computerplayed = 1
            endif
         next x
      endif
   next y
   `verticals
   for x = 1 to 3
      `if we have two on a column
      if (board(x,1).player + board(x,2).player + board(x,3).player) = 2
         for y = 1 to 3
            if board(x,y).piece$ = "" and computerplayed = 0
               place_piece(x, y, computertype$, 1)
               computerplayed = 1
            endif
         next y
      endif
   next x
   `diagonals
   if (board(1,1).player + board(2,2).player + board(3,3).player) = 2
      for i = 1 to 3
         if board(i,i).piece$ = "" and computerplayed = 0
            place_piece(i, i, computertype$, 1)
            computerplayed = 1
         endif
      next i
   endif
   if (board(1,3).player + board(2,2).player + board(3,1).player) = 2
      if board(1,3).piece$ = "" and computerplayed = 0
         place_piece(1, 3, computertype$, 1)
         computerplayed = 1
      endif
      if board(3,1).piece$ = "" and computerplayed = 0
         place_piece(3, 1, computertype$, 1)
         computerplayed = 1
      endif
      if board(2,2).piece$ = "" and computerplayed = 0
         place_piece(2, 2, computertype$, 1)
         computerplayed = 1
      endif
   endif
   
   `if we haven't moved yet, see if we need to block the human player
   `horizontals
   for y = 1 to 3
      if board(1,y).player + board(2,y).player + board(3,y).player = -20
         for x = 1 to 3
            if board(x,y).piece$ = "" and computerplayed = 0
               place_piece(x, y, computertype$, 1)
               computerplayed = 1
            endif
         next x
      endif
   next y
   `verticals
   for x = 1 to 3
      if board(x,1).player + board(x,2).player + board(x,3).player = -20
         for y = 1 to 3
            if board(x,y).piece$ = "" and computerplayed = 0
               place_piece(x, y, computertype$, 1)
               computerplayed = 1
            endif
         next y
      endif
   next x
   
   `diagonals
   if (board(1,1).player + board(2,2).player + board(3,3).player) = -20
      for i = 1 to 3
         if board(i,i).piece$ = "" and computerplayed = 0
            place_piece(i, i, computertype$, 1)
            computerplayed = 1
         endif
      next i
   endif
   if (board(1,3).player + board(2,2).player + board(3,1).player) = -20
      if board(1,3).piece$ = "" and computerplayed = 0
         place_piece(1, 3, computertype$, 1)
         computerplayed = 1
      endif
      if board(3,1).piece$ = "" and computerplayed = 0
         place_piece(3, 1, computertype$, 1)
         computerplayed = 1
      endif
      if board(2,2).piece$ = "" and computerplayed = 0
         place_piece(2, 2, computertype$, 1)
         computerplayed = 1
      endif
   endif
   
   
   `now if we haven't moved we need to use some strategy
   if computerplayed = 0
      `if the computer is the X
      if computerfirst = 1
         if playermove(0) = "Corner"
            if currentplayermove = 1 or currentplayermove = 2
               `play a open corner square
               if board(1,1).piece$ = ""
                  place_piece(1, 1, computertype$, 1)
                  computerplayed = 1
               else
                  if board(1,3).piece$ = ""
                     place_piece(1, 3, computertype$, 1)
                     computerplayed = 1
                  else
                     if board(3,3).piece$ = ""
                        place_piece(3, 3, computertype$, 1)
                        computerplayed = 1
                     else
                        if board(3,1).piece$ = ""
                           place_piece(3, 1, computertype$, 1)
                           computerplayed = 1
                        endif
                     endif
                  endif
               endif
               `/play a open corner square
            endif
         endif
         
         if playermove(0) = "Edge"
            if currentplayermove = 1
               `play the center
               place_piece(2, 2, computertype$, 1)
               computerplayed = 1
            endif
            if currentplayermove = 2
               `play a corner not bordered by a human edge piece
               if board(1,1).piece$ = "" and board(1,2).piece$ <> playertype$ and board(2,1).piece$ <> playertype$
                  place_piece(1, 1, computertype$, 1)
                  computerplayed = 1
               else
                  if board(3,1).piece$ = "" and board(2,1).piece$ <> playertype$ and board(3,2).piece$ <> playertype$
                     place_piece(3, 1, computertype$, 1)
                     computerplayed = 1
                  else
                     if board(3,3).piece$ = "" and board(2,3).piece$ <> playertype$ and board(3,2).piece$ <> playertype$
                        place_piece(3, 3, computertype$, 1)
                        computerplayed = 1
                     else
                        if board(1,3).piece$ = "" and board(1,2).piece$ <> playertype$ and board(2,3).piece$ <> playertype$
                           place_piece(1, 3, computertype$, 1)
                           computerplayed = 1
                        endif
                     endif
                  endif
               endif
            endif
         endif
         if playermove(0) = "Center"
            if currentplayermove = 1
               `play the opposite corner from our original play
               if board(1,1).player = 1
                  place_piece(3, 3, computertype$, 1)
                  computerplayed = 1
               endif
               if board(1,3).player = 1
                  place_piece(3, 1, computertype$, 1)
                  computerplayed = 1
               endif
               if board(3,1).player = 1
                  place_piece(1, 3, computertype$, 1)
                  computerplayed = 1
               endif
               if board(3,3).player = 1
                  place_piece(1, 1, computertype$, 1)
                  computerplayed = 1
               endif
            endif      
         endif
         
      endif
  
   
      `if the computer is the O
      if computerfirst = 0
         if playermove(0) <> "Center" `the human player played somewhere besides the center
            if currentplayermove = 1
               `play the center
               if board(2,2).piece$ = ""
                  place_piece(2, 2, computertype$, 1)
                  computerplayed = 1
               endif
               `/play the center
            endif
            
            if currentplayermove = 2
               if (playermove(0) = "Corner" and playermove(1) = "Edge") or (playermove(1) = "Corner" and playermove(0) = "Edge")
                  if board(1,1).piece$ = playertype$
                     place_piece(3, 3, computertype$, 1)
                     computerplayed = 1
                  endif
                  if board(1,3).piece$ = playertype$
                     place_piece(3, 1, computertype$, 1)
                     computerplayed = 1
                  endif
                  if board(3,1).piece$ = playertype$
                     place_piece(1, 3, computertype$, 1)
                     computerplayed = 1
                  endif
                  if board(3,3).piece$ = playertype$
                     place_piece(1, 1, computertype$, 1)
                     computerplayed = 1
                  endif
               endif
               
               if playermove(0) = "Corner" and playermove(1) = "Corner"
                  select (rnd(3)+1)
                     case 1
                        place_piece(1, 2, computertype$, 1)
                        computerplayed = 1
                     endcase
                     case 2
                        place_piece(2, 1, computertype$, 1)
                        computerplayed = 1
                     endcase
                     case 3
                        place_piece(3, 2, computertype$, 1)
                        computerplayed = 1
                     endcase
                     case 4
                        place_piece(2, 3, computertype$, 1)
                        computerplayed = 1
                     endcase  
                  endselect
               endif
               
               if playermove(0) = "Edge" and playermove(1) = "Edge"
                  if board(1,1).piece$ = "" and board(2,1).piece$ = playertype$ and board(1,2).piece$ = playertype$
                     place_piece(1, 1, computertype$, 1)
                     computerplayed = 1
                  endif
                  if board(3,1).piece$ = "" and board(2,1).piece$ = playertype$ and board(3,2).piece$ = playertype$
                     place_piece(3, 1, computertype$, 1)
                     computerplayed = 1
                  endif
                  if board(3,3).piece$ = "" and board(2,3).piece$ = playertype$ and board(3,2).piece$ = playertype$
                     place_piece(3, 3, computertype$, 1)
                     computerplayed = 1
                  endif
                  if board(1,3).piece$ = "" and board(1,2).piece$ = playertype$ and board(2,3).piece$ = playertype$
                     place_piece(1, 3, computertype$, 1)
                     computerplayed = 1
                  endif
                  
                  if board(1,2).piece$ = playertype$ and board(3,2).piece$ = playertype$
                     if rnd(1)
                        place_piece(2, 3, computertype$, 1)
                        computerplayed = 1
                     else
                        place_piece(2, 1, computertype$, 1)
                        computerplayed = 1
                     endif
                  endif
                  if board(2,3).piece$ = playertype$ and board(2,1).piece$ = playertype$
                     if rnd(1)
                        place_piece(1, 2, computertype$, 1)
                        computerplayed = 1
                     else
                        place_piece(3, 2, computertype$, 1)
                        computerplayed = 1
                     endif
                  endif
               endif
            endif
            
            if currentplayermove = 3
               if playermove(0) = "Edge" and playermove(1) = "Edge"
                  if board(1,2).piece$ = playertype$ and board(3,2).piece$ = playertype$
                     if board(2, 3).piece$ = computertype$
                        if rnd(1)
                           place_piece(1, 3, computertype$, 1)
                           computerplayed = 1
                        else
                           place_piece(3, 3, computertype$, 1)
                           computerplayed = 1
                        endif
                     endif
                     if board(2, 1).piece$ = computertype$
                        if rnd(1)
                           place_piece(1, 1, computertype$, 1)
                           computerplayed = 1
                        else
                           place_piece(3, 1, computertype$, 1)
                           computerplayed = 1
                        endif
                     endif
                  endif
                  if board(2,3).piece$ = playertype$ and board(2,1).piece$ = playertype$
                     if board(1, 2).piece$ = computertype$
                        if rnd(1)
                           place_piece(1, 3, computertype$, 1)
                           computerplayed = 1
                        else
                           place_piece(1, 1, computertype$, 1)
                           computerplayed = 1
                        endif
                     endif
                     if board(3, 2).piece$ = computertype$
                        if rnd(1)
                           place_piece(3, 1, computertype$, 1)
                           computerplayed = 1
                        else
                           place_piece(3, 3, computertype$, 1)
                           computerplayed = 1
                        endif
                     endif
                  endif
               endif
            endif
         else `the human player played to the center
            if currentplayermove = 1
               `play a random corner square
               select (rnd(3) + 1)
                  case 1
                     place_piece(1, 1, computertype$, 1)
                     computerplayed = 1
                  endcase
                  case 2
                     place_piece(1, 3, computertype$, 1)
                     computerplayed = 1
                  endcase
                  case 3
                     place_piece(3, 1, computertype$, 1)
                     computerplayed = 1
                  endcase
                  case 4
                     place_piece(3, 3, computertype$, 1)
                     computerplayed = 1
                  endcase
               endselect
               `/play a open corner square
            endif
            
            
            if currentplayermove = 2
               if playermove(1) = "Corner"
                  `play a open corner square
                  if board(1,1).piece$ = ""
                     place_piece(1, 1, computertype$, 1)
                     computerplayed = 1
                  else
                     if board(1,3).piece$ = ""
                        place_piece(1, 3, computertype$, 1)
                        computerplayed = 1
                     else
                        if board(3,3).piece$ = ""
                           place_piece(3, 3, computertype$, 1)
                           computerplayed = 1
                        else
                           if board(3,1).piece$ = ""
                              place_piece(3, 1, computertype$, 1)
                              computerplayed = 1
                           endif
                        endif
                     endif
                  endif
                  `/play a open corner square
               endif
            endif
            
         endif
      endif
   endif
   
   `if there is no possible strategy left, just pick a random square man!
   if computerplayed = 0
      found = 0
      repeat
         x = rnd(2) + 1 ` a 1 to 3 range
         y = rnd(2) + 1
         if board(x,y).piece$ = ""
            place_piece(x, y, computertype$, 1)
            computerplayed = 1
            found = 1
         endif
      until found = 1
   endif
 
   `reset this so the player can go again
   placed = 0
return

selectsquare:
   tempid = pick object(mousex(), mousey(), 1, 9)
   
   for i = 1 to 9
      ghost object on i
   next i
   
   if tempid > 0
      if tempid < 4
         x = 1
         y = tempid
         if board(x, y).piece$ = ""
            ghost object off tempid
            if mouseclick() = 1
               place_piece(x, y, playertype$, 0)
               placed = 1
               ghost object on tempid
            endif
         endif
      endif
         
      if tempid > 3 and tempid < 7
         x = 2
         y = tempid - 3
         if board(x, y).piece$ = ""
            ghost object off tempid
            if mouseclick() = 1
               place_piece(x, y, playertype$, 0)
               placed = 1
               ghost object on tempid
            endif
         endif
      endif
      
      if tempid > 6
         x = 3
         y = tempid - 6
         if board(x, y).piece$ = ""
            ghost object off tempid
            if mouseclick() = 1
               place_piece(x, y, playertype$, 0)
               placed = 1
               ghost object on tempid
            endif
         endif
      endif
      
      if placed = 1
         `if computerfirst = 1
            `player is the Os
            `if currentplayermove = 0
               if (x = 1 and y = 1) or (x = 1 and y = 3) or (x = 3 and y = 1) or (x = 3 and y = 3)
                  playermove(currentplayermove) = "Corner"
               endif
               if (x = 1 and y = 2) or (x = 2 and y = 1) or (x = 3 and y = 2) or (x = 2 and y = 3)
                  playermove(currentplayermove) = "Edge"
               endif
               if (x = 2 and y = 2)
                  playermove(currentplayermove) = "Center"
               endif
            `endif
            
         `else
            `player is the Xs
         `endif
         
         inc currentplayermove
      endif
      
   endif
return

check_for_win:
   `horizontals
   for y = 1 to 3
      if board(1, y).piece$ = playertype$ and board(2, y).piece$ = playertype$ and board(3, y).piece$ = playertype$
         humanwin = 1
      endif
      if board(1, y).piece$ = computertype$ and board(2, y).piece$ = computertype$ and board(3, y).piece$ = computertype$
         computerwin = 1
      endif
   next y
   `verticals
   for x = 1 to 3
      if board(x, 1).piece$ = playertype$ and board(x, 2).piece$ = playertype$ and board(x, 3).piece$ = playertype$
         humanwin = 1
      endif
      if board(x, 1).piece$ = computertype$ and board(x, 2).piece$ = computertype$ and board(x, 3).piece$ = computertype$
         computerwin = 1
      endif
   next x
   `diagonals
   if board(1, 1).piece$ = playertype$ and board(2, 2).piece$ = playertype$ and board(3, 3).piece$ = playertype$
      humanwin = 1
   endif
   if board(1, 1).piece$ = computertype$ and board(2, 2).piece$ = computertype$ and board(3, 3).piece$ = computertype$
      computerwin = 1
   endif
   if board(1, 3).piece$ = playertype$ and board(2, 2).piece$ = playertype$ and board(3, 1).piece$ = playertype$
      humanwin = 1
   endif
   if board(1, 3).piece$ = computertype$ and board(2, 2).piece$ = computertype$ and board(3, 1).piece$ = computertype$
      computerwin = 1
   endif
   
   if humanwin = 1
      `the human won!
      `what! impossible! :P
      sync `this sync is nessecary to make the last piece played shown
      center text screen width()/2, screen height()/2, "You win!"
      sync
      wait key
      gosub clearpieces
      goto menuplace
   endif
   
   if computerwin = 1
      `the computer won!
      sync `this sync is nessecary to make the last piece played shown
      center text screen width()/2, screen height()/2, "The computer won!"
      sync
      wait key
      gosub clearpieces
      goto menuplace
   endif
   
   
   `Check for a tie!
   empty = 0
   for x = 1 to 3
      for y = 1 to 3
         if board(x, y).piece$ = "" then empty = 1   
      next y
   next x
   if empty = 0
      `ze cat got the game
      sync `this sync is nessecary to make the last piece played shown
      center text screen width()/2, screen height()/2, "The cat got the game..."
      sync
      wait key
      gosub clearpieces
      goto menuplace
   endif
return

clearpieces:
   for x = 1 to 3
      for y = 1 to 3
         board(x,y).piece$ = ""
         board(x,y).player = 0
         exclude object on piece(x,y).objoid
         exclude object on piece(x,y).objxid
      next y
   next x
   
   humanwin = 0
   computerwin = 0
return 

menu:
   clear entry buffer
   
   if escapekey() = 1 then escapehold = 1
   do
      cls
      paste image blackimage, 0, 0
      center text screen width()/2, screen height()/2, "Which do you want to play as? X or O? (X goes first)"
      center text screen width()/2, screen height()/2 + 20, entry$()
      
      if right$(entry$(), 1) = "O" or right$(entry$(), 1) = "o"  or right$(entry$(), 1) = "0" 
         computerfirst = 1
         exit
      else
         if right$(entry$(), 1) = "X" or right$(entry$(), 1) = "x"
            computerfirst = 0
            exit
         else
            if right$(entry$(), 1) <> "" and escapekey() = 0
               cls
               paste image blackimage, 0, 0
               center text screen width()/2, screen height()/2, "Please enter either X or O"
               sync
               wait 1000
               clear entry buffer
               paste image blackimage, 0, 0
            endif
         endif
      endif
      
      if escapekey() = 1 and escapehold = 0 then end
      
      if escapekey() = 0 then escapehold = 0
      
      sync
   loop
return