Proyecto avanzado en PSeInt: crear un Ta-Te-Ti contra la computadora con matrices y SubProcesos


En este proyecto vamos a crear un Ta-Te-Ti en PSeInt contra la computadora. El objetivo es practicar matrices, validaciones, Funciones, SubProcesos y lógica de decisiones construyendo un juego completo.

El jugador utilizará la ficha X y la computadora la ficha O. La CPU no jugará completamente al azar: primero intentará ganar, luego bloquear al jugador, después priorizará el centro y las esquinas.

¿Qué vamos a practicar?

  • matrices de 3 x 3;
  • recorridos con ciclos;
  • validación de posiciones;
  • Funciones y SubProcesos;
  • detección de victoria;
  • detección de empate;
  • lógica básica para una CPU;
  • uso de valores aleatorios.

Reglas del Ta-Te-Ti

El tablero tiene 9 posiciones. Cada jugador coloca una ficha por turno.

  • el jugador usa X;
  • la computadora usa O;
  • gana quien consiga tres fichas iguales en línea;
  • la línea puede ser horizontal, vertical o diagonal;
  • si se ocupan las 9 posiciones y nadie gana, hay empate.

Representar el tablero

Usaremos una matriz de 3 x 3:

Dimension tablero[3,3];

Cada casillero podrá contener:

" "  = libre
"X"  = jugador
"O"  = computadora

Código completo

SubProceso InicializarTablero(tablero Por Referencia)
    Definir fila, columna Como Entero;

    Para fila <- 1 Hasta 3 Hacer
        Para columna <- 1 Hasta 3 Hacer
            tablero[fila,columna] <- " ";
        FinPara
    FinPara
FinSubProceso


SubProceso MostrarTablero(tablero)
    Definir fila Como Entero;

    Limpiar Pantalla;

    Escribir "==========================";
    Escribir "        TA-TE-TI";
    Escribir "==========================";
    Escribir "";

    Para fila <- 1 Hasta 3 Hacer
        Escribir " ", tablero[fila,1], " | ", tablero[fila,2], " | ", tablero[fila,3];

        Si fila < 3 Entonces
            Escribir "---+---+---";
        FinSi
    FinPara

    Escribir "";
FinSubProceso


Funcion libre <- PosicionLibre(tablero, fila, columna)
    libre <- tablero[fila,columna] = " ";
FinFuncion


Funcion ganador <- HayGanador(tablero, ficha)
    Definir i Como Entero;

    ganador <- Falso;

    Para i <- 1 Hasta 3 Hacer
        Si tablero[i,1] = ficha Y tablero[i,2] = ficha Y tablero[i,3] = ficha Entonces
            ganador <- Verdadero;
        FinSi

        Si tablero[1,i] = ficha Y tablero[2,i] = ficha Y tablero[3,i] = ficha Entonces
            ganador <- Verdadero;
        FinSi
    FinPara

    Si tablero[1,1] = ficha Y tablero[2,2] = ficha Y tablero[3,3] = ficha Entonces
        ganador <- Verdadero;
    FinSi

    Si tablero[1,3] = ficha Y tablero[2,2] = ficha Y tablero[3,1] = ficha Entonces
        ganador <- Verdadero;
    FinSi
FinFuncion


Funcion lleno <- TableroLleno(tablero)
    Definir fila, columna Como Entero;

    lleno <- Verdadero;

    Para fila <- 1 Hasta 3 Hacer
        Para columna <- 1 Hasta 3 Hacer
            Si tablero[fila,columna] = " " Entonces
                lleno <- Falso;
            FinSi
        FinPara
    FinPara
FinFuncion


SubProceso TurnoJugador(tablero Por Referencia)
    Definir fila, columna Como Entero;
    Definir valida Como Logico;

    valida <- Falso;

    Mientras NO valida Hacer
        Escribir "Elegí una fila (1 a 3): ";
        Leer fila;

        Escribir "Elegí una columna (1 a 3): ";
        Leer columna;

        Si fila >= 1 Y fila <= 3 Y columna >= 1 Y columna <= 3 Entonces
            Si PosicionLibre(tablero, fila, columna) Entonces
                tablero[fila,columna] <- "X";
                valida <- Verdadero;
            SiNo
                Escribir "Esa posición ya está ocupada.";
            FinSi
        SiNo
            Escribir "Fila o columna inválida.";
        FinSi
    FinMientras
FinSubProceso


Funcion encontro <- BuscarJugada(tablero Por Referencia, ficha)
    Definir fila, columna Como Entero;

    encontro <- Falso;

    Para fila <- 1 Hasta 3 Hacer
        Para columna <- 1 Hasta 3 Hacer
            Si NO encontro Y tablero[fila,columna] = " " Entonces
                tablero[fila,columna] <- ficha;

                Si HayGanador(tablero, ficha) Entonces
                    encontro <- Verdadero;
                SiNo
                    tablero[fila,columna] <- " ";
                FinSi
            FinSi
        FinPara
    FinPara
FinFuncion


SubProceso TurnoCPU(tablero Por Referencia)
    Definir jugo Como Logico;
    Definir fila, columna, esquina, intentos Como Entero;

    jugo <- Falso;

    /// 1. Intentar ganar
    Si BuscarJugada(tablero, "O") Entonces
        jugo <- Verdadero;
    FinSi

    /// 2. Bloquear al jugador
    Si NO jugo Entonces
        Para fila <- 1 Hasta 3 Hacer
            Para columna <- 1 Hasta 3 Hacer
                Si NO jugo Y tablero[fila,columna] = " " Entonces
                    tablero[fila,columna] <- "X";

                    Si HayGanador(tablero, "X") Entonces
                        tablero[fila,columna] <- "O";
                        jugo <- Verdadero;
                    SiNo
                        tablero[fila,columna] <- " ";
                    FinSi
                FinSi
            FinPara
        FinPara
    FinSi

    /// 3. Priorizar el centro
    Si NO jugo Y tablero[2,2] = " " Entonces
        tablero[2,2] <- "O";
        jugo <- Verdadero;
    FinSi

    /// 4. Elegir una esquina libre
    Si NO jugo Entonces
        intentos <- 0;

        Mientras NO jugo Y intentos < 20 Hacer
            esquina <- Aleatorio(1,4);

            Segun esquina Hacer
                1:
                    fila <- 1;
                    columna <- 1;
                2:
                    fila <- 1;
                    columna <- 3;
                3:
                    fila <- 3;
                    columna <- 1;
                4:
                    fila <- 3;
                    columna <- 3;
            FinSegun

            Si tablero[fila,columna] = " " Entonces
                tablero[fila,columna] <- "O";
                jugo <- Verdadero;
            FinSi

            intentos <- intentos + 1;
        FinMientras
    FinSi

    /// 5. Elegir cualquier posición libre
    Si NO jugo Entonces
        Para fila <- 1 Hasta 3 Hacer
            Para columna <- 1 Hasta 3 Hacer
                Si NO jugo Y tablero[fila,columna] = " " Entonces
                    tablero[fila,columna] <- "O";
                    jugo <- Verdadero;
                FinSi
            FinPara
        FinPara
    FinSi
FinSubProceso


Proceso TaTeTi
    Definir tablero Como Cadena;
    Definir terminado Como Logico;

    Dimension tablero[3,3];

    InicializarTablero(tablero);

    terminado <- Falso;

    Mientras NO terminado Hacer
        MostrarTablero(tablero);

        TurnoJugador(tablero);

        Si HayGanador(tablero, "X") Entonces
            terminado <- Verdadero;
            MostrarTablero(tablero);
            Escribir "¡Ganaste!";
        SiNo
            Si TableroLleno(tablero) Entonces
                terminado <- Verdadero;
                MostrarTablero(tablero);
                Escribir "Empate.";
            SiNo
                TurnoCPU(tablero);

                Si HayGanador(tablero, "O") Entonces
                    terminado <- Verdadero;
                    MostrarTablero(tablero);
                    Escribir "Ganó la computadora.";
                SiNo
                    Si TableroLleno(tablero) Entonces
                        terminado <- Verdadero;
                        MostrarTablero(tablero);
                        Escribir "Empate.";
                    FinSi
                FinSi
            FinSi
        FinSi
    FinMientras
FinProceso

¿Cómo detectamos una victoria?

La función HayGanador() revisa:

  • las 3 filas;
  • las 3 columnas;
  • la diagonal principal;
  • la diagonal secundaria.

Si encuentra tres fichas iguales devuelve Verdadero.

La lógica de la computadora

La CPU sigue un orden de prioridades.

1. Intentar ganar

Primero prueba cada casillero libre colocando temporalmente una O. Si esa jugada produce una victoria, conserva la ficha.

2. Bloquear al jugador

Si no puede ganar, prueba posiciones libres con una X. Si descubre que el jugador ganaría en ese casillero, reemplaza esa ficha temporal por una O.

3. Tomar el centro

Si el centro está libre, la computadora lo elige porque es una de las mejores posiciones estratégicas.

4. Elegir una esquina

Si el centro no está disponible, intenta ocupar una de las cuatro esquinas.

5. Usar cualquier posición libre

Como último recurso utiliza el primer casillero que encuentre disponible.

¿Es una inteligencia artificial?

No en el sentido moderno del término. La computadora utiliza una serie de reglas programadas para decidir qué hacer.

Sin embargo, es un excelente ejercicio para introducir el concepto de toma de decisiones automática: analizar un estado, evaluar opciones y ejecutar una acción según prioridades.

Desafíos para mejorar el proyecto

  • permitir que el jugador elija X u O;
  • hacer que la computadora pueda comenzar la partida;
  • agregar marcador de partidas ganadas;
  • permitir jugar varias rondas;
  • mostrar números del 1 al 9 para elegir casillas;
  • crear niveles de dificultad;
  • mejorar la CPU para detectar jugadas estratégicas futuras;
  • implementar el algoritmo Minimax.

Desafío avanzado: Minimax

Una evolución interesante sería reemplazar las reglas actuales por el algoritmo Minimax. Ese algoritmo analiza las posibles jugadas futuras y permite construir una computadora que juegue Ta-Te-Ti de forma óptima.

Es un excelente siguiente paso para empezar a estudiar algoritmos relacionados con juegos e inteligencia artificial.

¿Te sirvió este proyecto? ☕

Si este contenido te ayudó y querés apoyar a Club Programador para seguir publicando ejercicios, juegos y guías gratuitas, podés colaborar mediante:

☕ Apoyar con Mercado Pago

🌎 Apoyar con PayPal

Seguí aprendiendo PSeInt

Encontrá todos los ejercicios, guías y proyectos en nuestra página principal de PSeInt:

Aprender PSeInt: guía completa y ejercicios resueltos →


Descubre más desde Club Programador

Suscríbete y recibe las últimas entradas en tu correo electrónico.

Deja un comentario

Descubre más desde Club Programador

Suscríbete ahora para seguir leyendo y obtener acceso al archivo completo.

Seguir leyendo