Al menos en mi tierra, el juego de las 3 en raya se compone de un tablero de 3x3, luego lo correcto para reflejar el estado del tablero sería una matriz de 3x3
dim Tablero(0 to 2, 0 to 2) as InfoCasillas ' casillero, donde se pintará cuando se ocupe una casilla.
Dim CasillasLibres as byte ' indica cuantas casillas hay libres hasta el momento
Cada casilla del tablero puede tener 3 estados, 0 = no ocupado, 1= ocupada por el jugador A, -1= ocupada por el jugador B
private enum InfoCasillas
CASILLA_JUGADOR_B = -1
CASILLA_VACIA = 0
CASILLA_JUGADOR_A = 1
end enum
Para dibujar el tablero dado que solo requiere unas pocas líneas podrías usar un control line, de hecho una matriz de line, basta con 4 rayas si el picture que hace de tablero lo delimita perimetralmente.
Luego podrías tener 2 imágenes ocultas, para indicar casilla ocupada por un jugador u otro, básicamente podría ser una imagen cuadrada roja y otra azul ambas cruzadas por una 'X' blanca (por ejemplo), luego al iniciar el formulario las podrías cargar desde fichero o si lo prefieres mantenerlas ocultas en un par de controles image.
' a nivel de formulario...
Dim ImgJugador(0 to 1) as IpictureDisp
private sub Form_Initialize
set ImgJugador(0)= loadpicture("ruta de la imagen del jugador A")
set ImgJugador(1)= loadpicture("ruta de la imagen del jugador B")
End Sub
El tablero puesto que es finito y de tamaño conocido podría ser escalado a las casillas que ha de contener (esto facilita luego su dibujado), entonces en el evento initiiialize del formulario o en el load, podrías poner la siguiente línea:
picture1.autoredraw=true ' para que no se nos borre el tablero cuando se coloque otra ventana encima...
call Picture1.Scale(0,0)-(3,3)
Como ya hemos escalado el tablero entonces podremos referirnos a las casillas como 0,1 y 2, para terminar de hacer cómodo el uso del tablero definimos también la medida de 1 casilla del tablero:
dim Cuadro as single ' esto a nivel del formulario
cuadro = picture1.scalewidth / 3 ' esto justo debajo de la línea que escala el picture.
' NOTA: si la picture no es cuadrado convendrá definir otra variable dedicando una para el ancho de las casillas y otra para el alto de las casillas
Luego convendrá que tengamos una rutina llamada iniciar partida... pero antes definimos nombres para los jugadores...
Dim turno as byte ' a nivel de formulario
dim nombreJugador(0 to 1) as string
' en el load del formulario
dim nombre as string
nombre = InputBox("especifique el nombre del jugador A: ", "Nombre de los contendientes...", "Jugador A")
if nombre ="" then
nombrejugador(0)="Jugador A"
else
nombrejugador(0)= nombre
end if
nombre = InputBox("especifique el nombre del jugador B: ", "Nombre de los contendientes...", "Jugador B")
if nombre ="" then
nombrejugador(1)="Jugador B"
else
if nombre <> nombrejugador(0) then
nombrejugador(1)= nombre
else
nombrejugador(1)="Jugador B"
end if
end if
Private sub IniciarPartida
picture1.cls ' borramos el tablero
erase tablero ' la matriz es estática, por tanto erase sólo borra el contenido
CasillasLibres = 9
' si hay algún sistema de puntuación actualizar aquí.
' echamos a suertes que jugador empieza, basado en un 50% (del 0 al 49 = 0, del 50 al 99 = 1)
turno= (100 *RND)50
msgbox "Empieza el Jugador : " & NombreJugador(turno)
' ahora AQUÍ se activan todos los controles de la interfaz para jugar la partida.
End Sub
También deberíamos tener una rutina que marque la jugada....
private sub Turnar(byval Fila as byte, byval Columna as byte)
' se omite la comprobamos de fila y columna fuera de rango, es obvio y si lo haces correctamente debería ser innecesario.
if CasillaLibre(Fila, Columna) = TRUE then
if CasillasLibres = 0 then
call VerificarResultado
' exhibir mensaje de quien ganó, indcar línea ganadora y se prevee actualizar puntuación de los juadores
' desactivar interfaz de jugada excepto los botones nueva partida y salir ( si se pulsa en nueva partida allí se habilita de nuevo la interfaz).
else
Picture1.PaintPicture ImgJugador(turno), columna, fila, cuadro, cuadro
' ahora cambiamos el turno del jugador
Turno= abs(turno -1)
msgbox "es el turno del jugador: " & nombrejugador(turno)
end if
else
bepp
msgbox "La casilla " & fila & "," & columna & " ya está ocupada. elija otra, jugador " & nombreJugador(turno)
end if
end sub
Como ya podrás averiguar por el código anterior necesitamos 2 nuevas funciones una que verifique si la casilla indicada está libre:
si está libre la marcamos 'fichada' por el jugador que ostenta elturno y restamos una casilla libre del tablero...
private function CasillaLibre(byval F as byte, byval C as byte) as boolean
if tablero(c,f) = 0 then ' si tiene un valor 0 estçá libre
tablero(c,f)= ((turno * 2) -1) ' entonces se la apropiamos al jugador que tiene el turno
CasillasLibres = Casillaslibres -1 ' restamos una casilla libre
CasillaLibre = TRUE ' y devolvemos el resultado 'estaba libre'
end if
end function
Como ves está casi todo, te dejo que resuelvas la función "VerificarResultado" para determinar quien ganó o si acabó en tablas... y algunos pequeños detalles... que corren de tu cuenta, como enviar la fila y columna elegida por un jugador a la rutina que evalúa el movimiento de la ficha a la casilla determinada por la fila y columna elegida...
Los controles 'line' para dibujar el resto del tablero 8las 4 rayas divisorias) puedes ubicarlas fácilmente una vez que hemos escalado el picture y obtenido el tamaño de cada casilla en la variable 'cuadro'....
Te invito también a que añadas código al evento resize del formulario para que al agrandarse éste también se agrande el tablero y las fichas ya colocadas...