Tres en raya con IA: Tutorial de Python (Parte 2)
Índice
- Introducción rápida
- AI y cosas más interesantes
- El algoritmo básico
- Paso 1: Mover para ganar
- Paso 2: Bloquear el movimiento del jugador
- Paso 3: Mover a una esquina abierta
- Paso 4: Mover al centro abierto
- Paso 5: Mover a cualquier borde abierto
- No hay movimientos posibles
- Conclusión
Introducción rápida
¡Hola chicos! Estaba editando este video y quería hacer una rápida introducción para la segunda parte. Hay algunos errores que encontré al final del video, así que es realmente importante que vean todo el video, porque soluciono esos errores al final. Si no lo ven, no encontrarán la solución y se preguntarán qué estaba pasando. En fin, espero que disfruten el video. Si lo hacen, asegúrense de darle like y suscribirse. Ahora vamos a pasar a la parte más divertida, que es la AI.
AI y cosas más interesantes
La parte de la AI es un poco más interesante y tal vez un poco más avanzada. Hasta ahora, lo que hemos hecho es principalmente código básico, simplemente ejecutando diferentes funciones. Ahora voy a entrar en mi función principal y voy a editar esta pequeña sección que he escrito aquí. Esto es porque la forma en que vamos a hacer las cosas es que nuestro movimiento de la computadora nos va a devolver un movimiento. Así que lo que quiero decir es que quiero decir que el movimiento es igual al movimiento de la computadora, ¿vale?
Después de eso, no vamos a imprimir el tablero todavía porque queremos verificar Algo. Quiero decir si el movimiento es igual a cero, y esto va a significar que nuestra función de movimiento de la computadora no fue capaz de encontrar un movimiento, ya sea porque el tablero está lleno debido al movimiento del jugador en la última posición o por cualquier otra razón extraña. Vamos a simplemente imprimir "Empate" porque si no hay más movimientos que la computadora pueda hacer, entonces el juego debe ser un empate. De lo contrario, eso significa que tenemos un movimiento que no es cero, así que fue de uno a nueve. Vamos a insertar ese movimiento en el tablero y, en este caso, ¿cómo lo llamamos? Vamos a decir que la letra insertada, esa letra o lo que sea. En este caso, nuestra computadora va a ser una 'x' así. Y luego vamos a imprimir un pequeño mensaje que le diga al usuario lo que sucedió. Esto también sirve para hacer una pausa y ver la cuadrícula que vamos a imprimir. Y voy a decir "La computadora juega en la posición [movimiento]". Después de eso, simplemente voy a poner dos barras invertidas de nuevo y OH, en la posición [movimiento]. Y luego de eso, voy a poner dos puntos porque por qué no.
Después de hacer esto, vamos a imprimir el tablero porque queremos esperar hasta que hayamos insertado la letra en el tablero antes de imprimirlo. Y eso es básicamente todo para nuestra pequeña serie de instrucciones de movimiento de la computadora. Ahora podemos pasar a la verdadera AI. Básicamente, la forma en que esto va a funcionar es que vamos a seguir un algoritmo muy básico que tiene cinco pasos. El primer paso es decir: ¿hay un movimiento que podamos hacer que nos lleve a ganar? Si es así, tomemos ese movimiento porque eso significa que el juego va a terminar y ganaremos como computadora. El siguiente paso es decir: "Bueno, si no podemos ganar con un movimiento, ¿hay un movimiento que el jugador pueda hacer en su siguiente turno que lo haga ganar el juego? Si encontramos ese movimiento, entonces vamos a decir: "No, no te vamos a dejar hacer eso, vamos a bloquear ese movimiento moviéndonos a esa posición". Después de eso, decimos: "Bueno, no podemos ganar, el jugador no puede ganar, así que no importa mucho hacia dónde nos movemos. Vamos a elegir una esquina en la que movernos". Bien, si no hay esquinas a las que moverse, todas están ocupadas, vamos a verificar si el centro ha sido ocupado. Si el centro no ha sido ocupado aún, vamos a tomar el centro. Y después de eso, vamos a movernos a cualquier borde abierto. Los bordes son bastante simples, son los que están al lado de la esquina, no son el centro. Así que esos son los cinco pasos principales que vamos a seguir como computadora. Vamos a recorrer ese algoritmo para determinar hacia dónde nos vamos a mover.
Paso 1: Mover para ganar
Lo primero que quiero hacer es hacer una lista de movimientos posibles. Los movimientos posibles serán cualquier cuadro vacío que aún quede en el tablero. Para hacer esto, simplemente voy a decir "movimientos posibles" es igual a una lista vacía. Y luego voy a decir for i, letter in enumerate(board)
: Esto puede que no sepan lo que significa, pero lo explicaré en un segundo. Si letter == " "
y i != 0
: Estos se ven un poco confusos, pero básicamente lo que estamos diciendo aquí es que estamos ejecutando un bucle for
, y lo hago en una sola línea solo porque es más rápido. Digo for i, letter
, esto será nuestro índice y este será el valor real en enumerar el board
. Entonces, lo que enumerate
hace es que nos da todos los índices y los valores reales de las cosas en nuestra lista. Por ejemplo, en el board
, nos dará algo como 0 "espacio en blanco" 1 "X" 2 "O"
y eso se almacenará apropiadamente en i
y en letter
. Luego comprobamos, y esto es en la misma línea, simplemente lo escribo porque es más rápido, si letter
es un espacio en blanco, lo que significa que no tenemos nada allí, y el índice no es 0, porque siempre tenemos ese espacio en blanco que vemos al principio de nuestra lista, por lo que no queremos que la computadora piense que puede moverse a la posición 0, porque eso no está permitido. Así que eso es por qué solo puse esto aquí i != 0
, esto solo verifica los índices de todas las posiciones posibles a las que podemos movernos que aún no están llenas, y las coloca en una lista. Creará una lista como "1, 4 o 5, 6" o algo así, cualquier posición que aún no esté llena. Eso es lo que hace movimientos posibles
.
Después de eso, solo voy a establecer una variable de movimiento predeterminada aquí igual a 0, para que cuando lleguemos al final de nuestro programa, si todavía no hemos encontrado un movimiento para hacer, vamos a retornar el movimiento, que será 0. Y luego vamos a decir tomando nuestro turno en el programa
. Ahora tenemos que ir al primer paso y el primer paso es verificar si hay un movimiento que podamos hacer que resulte en una victoria. Ahora hay varias formas de hacer esto, la forma en que he descubierto que es más eficiente y tiene más sentido es hacer una copia del tablero. Vamos a comprobar cada posición vacía y ver si, cuando nos movamos a esa posición en la copia de nuestro tablero, es una posición ganadora o no. Puede Sonar confuso, es difícil de explicar, pero déjenme pasar por el código con ustedes. Como vamos a tener que comprobar si ganamos y luego podemos comprobar si el jugador puede ganar en su siguiente turno, hagamos esto en un pequeño bucle for
. Voy a decir for let in ["O", "X"]
: Esto simplemente significa "para let in" y esto solo representa la letra "O", porque esa será nuestra letra, y luego "X" de la misma manera. Ahora voy a decir for i in movimientos posibles
: Esto nos dará todas nuestras posiciones como 1, 3, etc., cualquier que sea un espacio en blanco. Vamos a hacer una copia de la tabla simplemente llamada "copia de tablero". Para hacer esto podríamos hacer un alias, que sería simplemente hacer esto, pero si hacemos esto, eso significa que cuando usamos la referencia a la copia del tablero en nuestro programa y cambiamos algo en la copia de la lista, en realidad cambiaría la lista original. Así que lo que necesitamos hacer para hacer una copia es poner dos puntos como esto, para que el programa sepa que no queremos simplemente hacer referencia a esto con un nuevo nombre, queremos realmente hacer una copia y crear un nuevo espacio en la memoria para eso. Puedo explicar eso en otro video cómo funciona exactamente en Python, creo que hay algo como inmutable y mutable, creo que eso es lo que se llama variables porque las listas son mutables, es por eso que puedes hacer algo como eso, de todos modos avancemos al siguiente paso. Voy a decir board_copy[i] = let
. Ahora, lo que esto va a hacer es que hemos hecho una copia de nuestro tablero, ahora vamos a simplemente colocar nuestra letra, que será "o" o "x" según lo que estemos comprobando, en el índice e en el bucle de movimientos posibles. Así que si la primera posición vacía es, digamos, 1, que sería arriba a la izquierda, vamos a decir simplemente que arriba a la izquierda es igual a "o" o algo así. Y luego, ahora vamos a comprobar si eso resulta en un juego ganador para nosotros. Para hacer eso, vamos a decir si es ganador, vamos a darle un tablero, y en esta variable - board_copy - y una letra, y la letra será la letra actual que estamos comprobando, o en este caso "o" al principio, y luego "x". Si esto es verdadero, vamos a decir movimiento = i
y vamos a devolver eso. Entonces, permítanme volver a explicar esto una vez más, estamos revisando ohs y equis, primero echamos un vistazo a todos los movimientos posibles que podemos hacer, y eso son todos los espacios vacíos que hemos definido aquí arriba. Vamos a crear una copia de nuestro tablero y vamos simplemente a colocar una letra en esa posición vacía en nuestra copia del tablero. Vamos a comprobar si esa copia del tablero es un ganador o no, si lo es, vamos a decir que ese es nuestro movimiento y vamos a devolverlo y vamos a salir de la función de movimiento de la computadora, porque ese es el movimiento que queremos hacer, va a ganar para nosotros. Ahora lo mismo se aplica aquí, excepto que ahora estamos comprobando si el jugador puede ganar. Así que vamos a decir, "Bueno, si somos un jugador, ¿dónde tendríamos que movernos para ganar?" Si encontramos una posición donde podamos ganar en el tablero, bueno, no queremos que el jugador gane, así que vamos a movernos a esa posición para bloquearlo haciendo lo mismo aquí, y eso es prácticamente todo para el paso uno y el paso dos.