Hello ablade,
Welcome to the board

Having looked at your code I can see that the biggest problem you have is the ComputerMove() function. Your looping through each square and cheking if its empty then filling in the square with an X. What it should do is find a free square then fill it in with an X then stop, rather that continue through all the squares. However, that method does not attempt to win in any way.
Before I start with a possible solution I'd like to change a few thing about you program if thats ok. Not to say what you have done is wrong, but Blitz has some functionality that will make the code a little simpler to write. I have no idea of your experience with programming in Blitz, but I will write it for someone who is resonable new to Blitz, so that its more useful to more people.
Firstly and mostly is the images you are using. Blitz has a great function called LoadAnimImage() This function allows you to load a single image and split it up into sections. What this means is that you could combine all your images into one long image and save your self the effort of loading each image sepperately. What i've done is create an image of width 500 (125*4) and height 125. Each tile you have created will be lined up side by side in this image. I'll also save it in png format wich will reduce the image file size, especially with this type of image where there are long lengths of the same color, i.e the black. This is however more usefull on larger images of this nature.
I will then use LoadAnimImage("Tiles.png", 125,125, 0,4 ) to load it into memory and seperate the individual frames in the image. I can then access each frame using the normal DrawImage() command with the optional frame variable set. In this case there will be 4 frames 0 -> 3.
An alternative to loading images is to create one using Blitz graphics commands. You get stuff like Line and then Rect and Oval that can be outlined or floodfilled squares and circles. I'll include this method too in the code.
The second thing I'm going to do is add some constants that will help with the image frame number and playing field state ( empty, cross, circle ).
As for the game AI, the simplest way I can see to tackle the problem is to break it down into the steps the players would take.
1. Can the computer win on this go?
If Yes then Mark the winnig block, game over computer wins
If No the goto step 2
2. Is the player going to win on their next go?
If Yes then block them using the computers go.
If No then goto step 3
3. Mark a random empty block
or a more advanced AI would
3. Mark the block most likey to get the Computer a win
This will be the position that give you the maximun number of possible lines.
When there are multiple equally possible positions,
then choose the one that reduces the number of possible lines the player has.
otherwise randomly pick one.
But the more advanced version would be harder to code and near impossible to win, so I'm sticking with the random method. That way the player has a chance of winning as much as the computer. Althoug, eventually the player could learn how to win everytime.
Thats about it from me. I'll attach the new image and code to go with what I have explained here. Note the code doesnt actually require the image, but I have included a variable wich you can set to True to load the image file instead of generating the shapes.
;---------------------------------------------------
;
; TicTacToe writen by Tetra to aid the mebers at
;
; www.dbfinteractive.com
;
;---------------------------------------------------
AppTitle "TicTacToe - Press Escape to quit"
;-- Constants --------------------------------
;-- Square states / Image index ----------
;
; These constants double up in use,
; firstly to reprisent the square state
; in the array, secondly they reprisent
; the corresponding image frame for that
; shape
;
Const STATE_BLANK = 0
Const STATE_CIRCLE = 1
Const STATE_CROSS = 2
Const CURSOR_SQUARE = 3 ; The cursor image
Const SHAPE_PLAYER = STATE_CIRCLE ; Player is the circle
Const SHAPE_COMPUTER = STATE_CROSS ; Computer is the cross
;--------------------------------------------/
;-- Program Constants ------------------------
;-------------------------------------
; True: Loads the Tiles image
; False: Use Blitz graphics commands
;
Const USE_IMAGE_FILE = False
;-------------------------------------
; Tile information
;
Const TILE_WIDTH = 125
Const TILE_HEIGHT = 125
Const TILE_FRAMES = 4
Const TILE_FILENAME$ = "Tiles.png"
;--------------------------------------------/
;-- Globals ----------------------------------
;-- Square states / Image index --
Global tiles ; Global variable that will hold the tile images
Dim playing_field( 9 ) ; This stores the states/image_frame of the playing field
; |0|1|2|
; |3|4|5|
; |6|7|8|
;-- Playing Field information -----
Global playing_field_x = 132
Global playing_field_y = 52
Global winning_pos ; used for passing information from CheckLine() to CanPlayerWin()
Global whos_go = SHAPE_PLAYER ; whos go is it currently?
Global next_move ; used as a tempoary value in the main loop
;--------------------------------------------/
;-- Initialize ----------------------------------
Graphics 640,480,32,2
SeedRnd( MilliSecs() )
CreateTileImages()
;--------------------------------------------/
;-- Main Loop -------------------------------
SetBuffer( BackBuffer() )
While Not KeyDown(1)
;-----------------------------
; Check whos go it is and call
; the according function
;
If ( whos_go = SHAPE_PLAYER )
next_move = PlayerGo()
If ( next_move > -1 )
playing_field( next_move ) = SHAPE_PLAYER
whos_go = SHAPE_COMPUTER
CheckForWinner()
EndIf
ElseIf ( whos_go = SHAPE_COMPUTER )
next_move = ComputerGo()
If ( next_move > -1 )
playing_field( next_move ) = SHAPE_COMPUTER
whos_go = SHAPE_PLAYER
CheckForWinner()
EndIf
Else
;-----------------------------
; Display the correct message
;
Color( 255,255,255 )
Select ( whos_go )
Case -1
Text 10,10,"You have Won, well done!"
Text 10,30,"Press F1 to play again."
Case -2
Text 10,10,"You have Lost."
Text 10,30,"Press F1 to try again."
Case -3
Text 10,10,"The game was a Draw."
Text 10,30,"Press F1 to try again."
End Select
;-----------------------------
; Reset the playing field if
; F1 is pressed. Also randomly
; choose the player or
; computer to go first
;
If ( KeyDown( 59 ) )
If ( Rand(0,1) = 0 )
whos_go = SHAPE_PLAYER
Else
whos_go = SHAPE_COMPUTER
EndIf
For i = 0 To 8
playing_field( i ) = STATE_BLANK
Next
EndIf
EndIf
DrawPlayingField()
Flip
Cls
Wend
;--------------------------------------------/
;-- Program Ends ----------------------------
End
;--------------------------------------------/
;======================================================
;
; Functions
;
;======================================================
;-------------------------------------
; This function either loads or
; creates the tile images based on
; a Program Constants
;
Function CreateTileImages()
;-------------------------------------
; Load or Create the Tile images?
;
If ( USE_IMAGE_FILE )
;----------------------------------------
; Load the image and seperates the frames
;
tiles = LoadAnimImage( TILE_FILENAME$, TILE_WIDTH,TILE_HEIGHT, 0,TILE_FRAMES )
Else
;----------------------------------------
; Create an image with the right number
; of frames
;
tiles = CreateImage( TILE_WIDTH,TILE_HEIGHT, TILE_FRAMES )
;----------------------------------------
; Sets the drawing surface to the tile
; image, Blank frame
;
SetBuffer( ImageBuffer( tiles, STATE_BLANK ) )
Color( 128,128,64 )
Rect( 0,0, TILE_WIDTH,TILE_HEIGHT, False ) ; draw an outline Square
;----------------------------------------
; Sets the drawing surface to the tile
; image, Circle frame
;
SetBuffer( ImageBuffer( tiles, STATE_CIRCLE ) )
Color( 128,128,64 )
Rect( 0,0, TILE_WIDTH,TILE_HEIGHT, False ) ; draw an outline square
Color( 255,60,66 )
Oval( 15,20,93,89, False ) ; draw an outline Circle
;----------------------------------------
; Sets the drawing surface to the tile
; image, Cross frame
;
SetBuffer( ImageBuffer( tiles, STATE_CROSS ) )
Color( 128,128,64 )
Rect( 0,0, TILE_WIDTH,TILE_HEIGHT, False ) ; draw an outline square
Color( 0,0,255 )
Line( 14, 14, 110,110 ) ; Draw one side of the \
Line( 14,110, 110, 14 ) ; Draw the other side of the /
;----------------------------------------
; Sets the drawing surface to the tile
; image, Cursor frame
;
SetBuffer( ImageBuffer( tiles, CURSOR_SQUARE ) )
Color( 255,128,64 )
Rect( 26,26, 72,72, True ) ; draw a floodfilled Rectangle
Color( 0,0,0 )
Rect( 28,28, 68,68, True ) ; draw a floodfilled Rectangle
EndIf
End Function
;-------------------------------------
; Draws the Playing Field to the
; screen
;
Function DrawPlayingField()
Local x,y
For y = 0 To 2
For x = 0 To 2
DrawImage( tiles, playing_field_x + ( TILE_WIDTH * x ), playing_field_y + ( TILE_HEIGHT * y ), playing_field( x + ( y * 3 ) ) )
Next
Next
End Function
;-------------------------------------
; Returns the position the computer
; want to mark
;
Function PlayerGo()
Local pos = -1
Local x,y
;------------------------
; Did the player try to
; click on the playing
; field?
;
If ( MouseDown(1) )
;------------------------------
; If the mouse is over the
; playing field, then calculate
; he position its over
;
x = ( MouseX() - playing_field_x ) / TILE_WIDTH
y = ( MouseY() - playing_field_y ) / TILE_HEIGHT
If ( x >= 0 )And( x < 3 )And( y >=0 )And( y < 3 ) Then pos = x + ( y * 3 )
;------------------------------
; Make sure the selected block
; is blank
;
If ( playing_field( pos ) <> STATE_BLANK ) Then pos = -1
EndIf
Return pos
End Function
;-------------------------------------
; Returns the position the computer
; want to mark
;
Function ComputerGo()
Local pos = -1
;-----------------------------------
; Can the computer win on this go?
; If yes Return the winning move
; position
;
pos = CanPlayerWin( SHAPE_COMPUTER )
If ( pos > -1 ) Then Return pos
;-----------------------------------
; Can the player win?
; If yes Return the blocking move
; position
;
pos = CanPlayerWin( SHAPE_PLAYER )
If ( pos > -1 ) Then Return pos
;-----------------------------------
; Choose a random block to mark
;
pos = Rand(0,8)
While ( playing_field( pos ) <> STATE_BLANK )
pos = Rand(0,8)
Wend
;-----------------------------------
; Return the computers next move
;
Return pos
End Function
;-------------------------------------
; Checks to see if the player can win
; on their next go.
; Returns the wining position if true
; otherwise it returns -1
;
Function CanPlayerWin( aPlayer )
Local x,y
If ( CheckLine( 0,1,2, aPlayer ) ) Then Return winning_pos
If ( CheckLine( 3,4,5, aPlayer ) ) Then Return winning_pos
If ( CheckLine( 6,7,8, aPlayer ) ) Then Return winning_pos
If ( CheckLine( 0,3,6, aPlayer ) ) Then Return winning_pos
If ( CheckLine( 1,4,7, aPlayer ) ) Then Return winning_pos
If ( CheckLine( 2,5,8, aPlayer ) ) Then Return winning_pos
If ( CheckLine( 0,4,8, aPlayer ) ) Then Return winning_pos
If ( CheckLine( 2,4,6, aPlayer ) ) Then Return winning_pos
Return -1 ; the player cannot win on next go
End Function
;-------------------------------------
; Checks for a possible winning line
;
Function CheckLine( pos1, pos2, blank, aPlayer )
If ( playing_field( pos1 ) = aPlayer )And( playing_field( pos2 ) = aPlayer )And( playing_field( blank ) = STATE_BLANK )
winning_pos = blank
Return True
ElseIf ( playing_field( blank ) = aPlayer )And( playing_field( pos2 ) = aPlayer )And( playing_field( pos1 ) = STATE_BLANK )
winning_pos = pos1
Return True
ElseIf ( playing_field( pos1 ) = aPlayer )And( playing_field( blank ) = aPlayer )And( playing_field( pos2 ) = STATE_BLANK )
winning_pos = pos2
Return True
Else
Return False
EndIf
End Function
;-------------------------------------
;
Function CheckForWinner()
;--------------------------
; Has the player won?
;
If ( CheckWinningLine( 0,1,2, SHAPE_PLAYER ) ) Then whos_go = -1
If ( CheckWinningLine( 3,4,5, SHAPE_PLAYER ) ) Then whos_go = -1
If ( CheckWinningLine( 6,7,8, SHAPE_PLAYER ) ) Then whos_go = -1
If ( CheckWinningLine( 0,3,6, SHAPE_PLAYER ) ) Then whos_go = -1
If ( CheckWinningLine( 1,4,7, SHAPE_PLAYER ) ) Then whos_go = -1
If ( CheckWinningLine( 2,5,8, SHAPE_PLAYER ) ) Then whos_go = -1
If ( CheckWinningLine( 0,4,8, SHAPE_PLAYER ) ) Then whos_go = -1
If ( CheckWinningLine( 2,4,6, SHAPE_PLAYER ) ) Then whos_go = -1
;--------------------------
; Has the computer won?
;
If ( CheckWinningLine( 0,1,2, SHAPE_COMPUTER ) ) Then whos_go = -2
If ( CheckWinningLine( 3,4,5, SHAPE_COMPUTER ) ) Then whos_go = -2
If ( CheckWinningLine( 6,7,8, SHAPE_COMPUTER ) ) Then whos_go = -2
If ( CheckWinningLine( 0,3,6, SHAPE_COMPUTER ) ) Then whos_go = -2
If ( CheckWinningLine( 1,4,7, SHAPE_COMPUTER ) ) Then whos_go = -2
If ( CheckWinningLine( 2,5,8, SHAPE_COMPUTER ) ) Then whos_go = -2
If ( CheckWinningLine( 0,4,8, SHAPE_COMPUTER ) ) Then whos_go = -2
If ( CheckWinningLine( 2,4,6, SHAPE_COMPUTER ) ) Then whos_go = -2
Local pos = 0
;------------------------------
; Are there any blank blocks?
While ( pos < 9 )
If ( playing_field( pos ) = STATE_BLANK ) Then pos = 10
pos = pos + 1
Wend
;------------------------------
; If all the blocks are filled
; then its a draw
If ( pos = 9 )
whos_go = -3
EndIf
End Function
;-------------------------------------
; Checks for an actual winning line
;
Function CheckWinningLine( pos1, pos2, pos3, aPlayer )
If ( playing_field( pos1 ) = aPlayer )And( playing_field( pos2 ) = aPlayer )And( playing_field( pos3 ) = aPlayer )
Return True
Else
Return False
EndIf
End Function