elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
29 Mayo 2012, 00:56  


Tema destacado: ¡Aprende hacking con práctica! - WarZone, el wargame de elhacker.net

+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse)
| | |-+  Ejemplo de Minimax: 3 en raya
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ejemplo de Minimax: 3 en raya  (Leído 559 veces)
ghastlyX
Colaborador
***
Desconectado Desconectado

Mensajes: 1.894



Ver Perfil
Ejemplo de Minimax: 3 en raya
« en: 15 Enero 2012, 23:32 »

Esta tarde con un amigo ha salido el tema por cosas de la conversación y le he desafiado a ganar al 3 en raya (Tic-tac-toe) a una IA que hiciera para el ordenador. Tras unos 15 minutos, os dejo el código que he hecho, puesto que considero que puede ser interesante la parte del minimax para aquellos que no hayan hecho nunca uno. Los gráficos son cutres y por consola, puesto que no era el objetivo del programa hacer una interfaz bonita.
Código
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
 
int M[3][3];
 
 
int fila[] = {0, 2, 2, 2, 1, 1, 1, 0, 0, 0};
int col[] = {0, 0, 1, 2, 0, 1, 2, 0, 1, 2};
 
int incf[] = {0, 1, 1, -1};
int incc[] = {1, 1, 0, 1};
 
int check() {
   for (int i = 0; i < 3; ++i) {
       for (int j = 0; j < 3; ++j) {
           for (int d = 0; d < 4; ++d) {
               string s;
               int f = i, c = j;
               for (int h = 0; h < 3; ++h) {
                   if (f < 0 or f >= 3 or c < 0 or c >= 3) break;
                   s += char(M[f][c] + '0');
                   f += incf[d];
                   c += incc[d];
               }
               if (s == "111") return 1;
               else if (s == "222") return 2;
           }
       }
   }
   return -1;
}
 
void draw() {
   for (int i = 0; i < 50; ++i) cout << endl;
   for (int i = 0; i < 3; ++i) {
       for (int j = 0; j < 3; ++j) {
           if (M[i][j] == 0) cout << "  ";
           else if (M[i][j] == 1) cout << " X";
           else cout << " O";
           if (j != 2) cout << " |";
       }
       cout << endl;
       if (i != 2) cout << "------------" << endl;
   }
}
 
int rec(int &x, int &y, int torn) {
   int best = -2;
   int z, t;
   for (int i = 0; i < 3; ++i) {
       for (int j = 0; j < 3; ++j) {
           if (M[i][j] != 0) continue;
           M[i][j] = torn;
           if (check() == torn) {
               x = i;
               y = j;
               M[i][j] = 0;
               return 1;
           }
           int aux = rec(z, t, (torn == 1)?2:1);
           if (aux == -2 or aux == 0) {
               if (best < 0) {
                   best = 0;
                   x = i;
                   y = j;
               }
           }
           else if (aux == -1) {
               if (best < 1) {
                   best = 1;
                   x = i;
                   y = j;
                   M[i][j] = 0;
                   return best;
               }
           }
           else if (aux == 1) {
               if (best < -1) {
                   best = -1;
                   x = i;
                   y = j;
               }
           }
           M[i][j] = 0;
       }
   }
   return best;
}
 
void tira_pc() {
   int x, y;
   int aux = rec(x, y, 1);
   M[x][y] = 1;
}
 
void tira_jug() {
   int pos = -1;
   while (pos < 1) {
       cin >> pos;
       if (pos < 1 or pos > 9) pos = -1;
       else if (M[fila[pos]][col[pos]] != 0) pos = -1;
   }
   M[fila[pos]][col[pos]] = 2;
}
 
int main() {
   memset(M, 0, sizeof(M));
   int win = -1, torn = 0;
   int qtt = 0;
   draw();
   while ((win = check()) < 0 and qtt < 9) {
       if (torn == 1) tira_pc();
       else tira_jug();
       torn = 1 - torn;
       draw();
       ++qtt;
   }
   if (win == 1) cout << "Gana el ordenador" << endl;
   else if (win == 2) cout << "Ganas tu" << endl;
   else cout << "Empate" << endl;
}

Se juega con los números:
7 8 9
4 5 6
1 2 3

El ordenador juega con X, el jugador humano con O. Empieza jugando el humano, aunque todo esto son detalles que se arreglan cambiando una o dos líneas.


En línea
m0rf


Desconectado Desconectado

Mensajes: 557


TBB


Ver Perfil
Re: Ejemplo de Minimax: 3 en raya
« Respuesta #1 en: 16 Enero 2012, 00:01 »

Interesante lo de la teoria de la decisión y el algoritmo de toma de decisiones minimax, conoces alguno más o este es el más utilizado o lo has elegido por algo en especial?

Saludos, realmente interesante nunca he tocado este tema.

PD: Empate siempre xD!!


En línea

Estilo ilícito ®
ghastlyX
Colaborador
***
Desconectado Desconectado

Mensajes: 1.894



Ver Perfil
Re: Ejemplo de Minimax: 3 en raya
« Respuesta #2 en: 16 Enero 2012, 17:57 »

Minimax lo que hace informalmente es considerar todos los casos que se pueden dar desde donde estás y en base a esto, elegir el movimiento que te lleve a un resultado mejor asumiendo que el contrario hará el movimiento que más te perjudique.

El problema de minimax es que el árbol de estados que crea es muy grande para juegos más complejos, pero con el 3 en raya hay pocos y lo puede calcular entero, de manera que el ordenador juega de forma perfecta, por eso he programado un minimax.

A la hora de programarlo no es complicado, es un pequeño backtracking. La idea es probar todos tus posibles movimientos y recursivamente hacer que haga lo mismo tu rival. En función de lo que retorne tu rival, elegirás la opción que mejor te vaya.

Si se deja acabar minimax, la jugada es perfecta. El problema es que no todos los juegos como ya he dicho lo permiten (puesto que necesitaría demasiado tiempo, por ejemplo con el ajedrez) y lo que se hace cuando se usa minimax en estos juegos es realizar diferentes tipos de podas para así conseguir un movimiento suficientemente bueno.
En línea
m0rf


Desconectado Desconectado

Mensajes: 557


TBB


Ver Perfil
Re: Ejemplo de Minimax: 3 en raya
« Respuesta #3 en: 16 Enero 2012, 23:27 »

A más es solo para juegos con dos jugadores por lo que vi en wikipedia.

A ver si me animo un dia de estos ha hacer un pequeño juego con este metodo para probarlo.

Gracias por aclarar sobre para que sirve minimax.

Saludos.
En línea

Estilo ilícito ®
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Minimax (canal infantil) en Wikipedia
Foro Libre
Swicher 0 356 Último mensaje 3 Diciembre 2007, 21:25
por Swicher
[C++] Tres en raya V1.00 (Act. V1.10)
Programación C/C++
JuaN-ThE-HaCKeR 9 1,440 Último mensaje 20 Febrero 2009, 12:30
por JuaN-ThE-HaCKeR
4 en raya
Programación C/C++
eipock 5 3,174 Último mensaje 18 Marzo 2011, 20:56
por Dr.Hacker++
3 en raya Help
Programación C/C++
safkevin 3 1,478 Último mensaje 11 Mayo 2010, 05:09
por Og.
Si un dvd se raya... « 1 2 »
Hardware
Nu|kEr32 18 3,483 Último mensaje 22 Agosto 2010, 03:59
por Nu|kEr32
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines