Flash, Inteligencia Artificial + 3 en raya

Posted on Thursday 12 July 2007

Hoy les presento a un juego que tiene mucha historia.
Esta vez, el juego lo he construido yo, de arriba a abajo. Lo juro

Tiene 2 tipos de juego: Dos Jugadores, para jugar 2 personas desde el mismo PC; y Un Jugador, contra la Inteligencia Artificial que programé. :o

Necesita tener Flash Player 7 o superior y JavaScript Activado. =)

Nota: La inteligencia Artificial buena, es la de nivel 3 U_U



Algunas referencias para entender el código:

Para trabajar mejor con el tablero, lo representé virtualmente como una matriz 3x3:

Actionscript:
  1. var t:Array = new Array();
  2. t = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];

Cuando una posición del tablero (matriz) esta vacía, (no ha sido ocupada) le asigno un valor de 0.
Cuando una posición del tablero (matriz) ha sido ocupada por una cruz, le doy valor -1.
Cuando una posición del tablero (matriz) ha sido ocupada por una circunferencia, le doy valor 1.

Como podrán ver en el código de la IA, al trabajar con estos valores para la matriz, nos facilita mucho mas las cosas que trabajando con, por ejemplo: undefined , true y false


Les pongo el código de la IA con las funciones que utiliza:

Actionscript:
  1. stop();
  2.  
  3. restart();
  4. //-->Game
  5. function evaluar(t) {
  6.     var res:Number = 0;
  7.     if (t[0][0] == t[1][1] && t[1][1] == t[2][2]) {
  8.         res = t[0][0];
  9.     }
  10.     if (t[0][2] == t[1][1] && t[1][1] == t[2][0]) {
  11.         res = t[0][2];
  12.     }
  13.     if (t[0][0] == t[0][1] && t[0][1] == t[0][2]) {
  14.         res = t[0][0];
  15.     }
  16.     if (t[1][0] == t[1][1] && t[1][1] == t[1][2]) {
  17.         res = t[1][0];
  18.     }
  19.     if (t[2][0] == t[2][1] && t[2][1] == t[2][2]) {
  20.         res = t[2][0];
  21.     }
  22.     if (t[0][0] == t[1][0] && t[1][0] == t[2][0]) {
  23.         res = t[0][0];
  24.     }
  25.     if (t[0][1] == t[1][1] && t[1][1] == t[2][1]) {
  26.         res = t[0][1];
  27.     }
  28.     if (t[0][2] == t[1][2] && t[1][2] == t[2][2]) {
  29.         res = t[0][2];
  30.     }
  31.     return res;
  32. }
  33.  
  34. function posicion_libre(t) {
  35.     var res:Boolean = false;
  36.     var i:Number = 0;
  37.     var j:Number = 0;
  38.     for (i=0; i<3; i++) {
  39.         for (j=0; j<3; j++) {
  40.             if (t[i][j] == 0) {
  41.                 res = true;
  42.             }
  43.         }
  44.     }
  45.     return res;
  46. }
  47.  
  48. function disable() {
  49.     for (i=0; i<3; i++) {
  50.         for (j=0; j<3; j++) {
  51.             _root["_"+i+"_"+j].enabled = false;
  52.         }
  53.     }
  54. }
  55.  
  56. function cruz(i, j) {
  57.     _root["_"+i+"_"+j].gotoAndStop("cruz");
  58.     t[i][j] = -1;
  59.     turno = 1;
  60.     turno_mc.gotoAndStop("p1");
  61.     trace(i+","+j);
  62. }
  63. function circulo(i, j) {
  64.     _root["_"+i+"_"+j].gotoAndStop("circulo");
  65.     t[i][j] = 1;
  66.     turno = 2;
  67.     turno_mc.gotoAndStop("p2");
  68. }
  69.  
  70. function pulsar(i, j) {
  71.     if (!fin) {
  72.         if (turno == 1) {
  73.             circulo(i,j);
  74.             if (evaluar(t) == 0) {
  75.                 IA();
  76.             }
  77.         }
  78.     }
  79.     switch (evaluar(t)) {
  80.         case 0 :
  81.             if (!posicion_libre(t)) {
  82.                 //trace("empate");
  83.                 turno_mc.gotoAndStop("empate");
  84.                 reiniciar.play();
  85.                 fin = true;
  86.                 disable();
  87.             }
  88.             break;
  89.         case -1 :
  90.  
  91.             //trace("ganan cruzes");
  92.             turno_mc.gotoAndStop("cruces");
  93.             reiniciar.play();
  94.             fin = true;
  95.             disable();
  96.             break;
  97.         case 1 :
  98.  
  99.             //trace("ganan criculos");
  100.             turno_mc.gotoAndStop("circulos");
  101.             reiniciar.play();
  102.             fin = true;
  103.             disable();
  104.             break;
  105.         default :
  106.  
  107.             trace("OMG! GRAN ERROR!");
  108.             break;
  109.     }
  110. }
  111.  
  112. function restart() {
  113.     turno = 1;
  114.     fin = false;
  115.     turno_mc.gotoAndStop("p1");
  116.     for (i=0; i<3; i++) {
  117.         for (j=0; j<3; j++) {
  118.             _root["_"+i+"_"+j].enabled = true;
  119.             _root["_"+i+"_"+j].gotoAndStop(1);
  120.             t[i][j] = 0;
  121.         }
  122.     }
  123. }
  124.  
  125. _0_0.onPress = function() {
  126.     pulsar(0,0);
  127. };
  128.  
  129. _0_1.onPress = function() {
  130.     pulsar(0,1);
  131. };
  132. _0_2.onPress = function() {
  133.     pulsar(0,2);
  134. };
  135. _1_0.onPress = function() {
  136.     pulsar(1,0);
  137. };
  138. _1_1.onPress = function() {
  139.     pulsar(1,1);
  140. };
  141. _1_2.onPress = function() {
  142.     pulsar(1,2);
  143. };
  144. _2_0.onPress = function() {
  145.     pulsar(2,0);
  146. };
  147. _2_1.onPress = function() {
  148.     pulsar(2,1);
  149. };
  150. _2_2.onPress = function() {
  151.     pulsar(2,2);
  152. };
  153. reiniciar.onPress = function() {
  154.     restart();
  155.     if (cont) {
  156.         reiniciar.play();
  157.     }
  158. };
  159.  
  160. menu.onPress = function() {
  161.     gotoAndStop("tablero");
  162. };
  163.  
  164. /*----------I A ------------*/
  165. function IA() {
  166.     var fet:Boolean = false;
  167.     var a:Number = 0;
  168.     var b:Number = 0;
  169.  
  170.     if (d != 1 && d != 2) {//si no es facil ni normal
  171.         if (t[1][1] == 0 && !fet) {//coloca el medio
  172.             cruz(1,1);
  173.             fet = true;
  174.         }
  175.         if (!fet) {
  176.             a = 0;
  177.             for (i=0; i<3; i++) {
  178.                 for (j=0; j<3; j++) {
  179.                     if (t[i][j] == 0) {
  180.                         a++;
  181.                     }
  182.                 }
  183.             }
  184.             if (a == 8 && (t[0][0] == 0 || t[2][0] == 0 || t[0][2] == 0 || t[2][2] == 0)) {
  185.                 b = Math.floor(Math.random()*3);
  186.                 switch (b) {
  187.                     case 0 :
  188.                         if (t[0][0] == 0 && !fet) {
  189.                             cruz(0,0);
  190.                             fet = true;
  191.                         }
  192.                         break;
  193.                     case 1 :
  194.                         if (t[0][2] == 0 && !fet) {
  195.                             cruz(0,2);
  196.                             fet = true;
  197.                         }
  198.                         break;
  199.                     case 2 :
  200.                         if (t[2][0] == 0 && !fet) {
  201.                             cruz(2,0);
  202.                             fet = true;
  203.                         }
  204.                         break;
  205.                     case 3 :
  206.                         if (t[2][2] == 0 && !fet) {
  207.                             cruz(2,2);
  208.                             fet = true;
  209.                         }
  210.                         break;
  211.                     default :
  212.                         trace("Error Switch");
  213.                         break;
  214.                 }
  215.             }
  216.         }
  217.         //a partir de aquí ataca->>>>>>
  218.         if (d != 1) {// si no es fácil (normal)
  219.         if (((t[0][0])+(t[1][1])+(t[2][2])) == -2 && !fet) {// diagonal 1 (\)
  220.             for (a=0; a<3; a++) {
  221.                 b = a;//equación (condición de los puntos para que pertenezcan) a la recta de la diagonal 1 (y=x)
  222.                 if (t[a][b] == 0 && !fet) {
  223.                     cruz(a,b);
  224.                     fet = true;
  225.                 }
  226.             }
  227.         }
  228.         if (((t[0][2])+(t[1][1])+(t[2][0])) == -2 && !fet) {//diagonal 2 (/)
  229.             for (a=0; a<3; a++) {
  230.                 b = 2-a;
  231.                 if (t[a][b] == 0 && !fet) {
  232.                     cruz(a,b);
  233.                     fet = true;
  234.                 }
  235.             }
  236.         }
  237.         b = 0;
  238.         while (b<3 && !fet) {
  239.             if (((t[0][b])+(t[1][b])+(t[2][b])) == -2 && !fet) {//horitzontals
  240.                 for (a=0; a<3; a++) {
  241.                     if (t[a][b] == 0 && !fet) {
  242.                         cruz(a,b);
  243.                         fet = true;
  244.                     }
  245.                     //endif
  246.                 }//endfor
  247.             }
  248.             //endifyelse
  249.             b++;
  250.         }//endwhile
  251.         a = 0;
  252.         while (a<3 && !fet) {
  253.             if (((t[a][0])+(t[a][1])+(t[a][2])) == -2 && !fet) {
  254.                 for (b=0; b<3; b++) {
  255.                     if (t[a][b] == 0 && !fet) {
  256.                         cruz(a,b);
  257.                         fet = true;
  258.                     }
  259.                 }
  260.             }
  261.             a++;
  262.         }//endwhile
  263.         //a partir de aquí se defiende->>>>>>
  264.             if (Math.abs((t[0][0])+(t[1][1])+(t[2][2])) == 2 && !fet) {// diagonal 1 (\)
  265.                 for (a=0; a<3; a++) {
  266.                     b = a;//equación (condición de los puntos para que pertenezcan) a la recta de la diagonal 1 (y=2-x)
  267.                     if (t[a][b] == 0 && !fet) {
  268.                         cruz(a,b);
  269.                         fet = true;
  270.                     }
  271.                 }
  272.             }
  273.             if (Math.abs((t[0][2])+(t[1][1])+(t[2][0])) == 2 && !fet) {//diagonal 2 (/)
  274.                 for (a=0; a<3; a++) {
  275.                     b = 2-a;
  276.                     if (t[a][b] == 0 && !fet) {
  277.                         cruz(a,b);
  278.                         fet = true;
  279.                     }
  280.                 }
  281.             }
  282.             b = 0;