Código
// Signos en línea en tableros cuadrados: // Este programa tiene básicamente 3 etapas, // que se pueden resumir así: // Nota: La situación inicial, en que hay 0 signos colocados, // estará guardada en la lista nro 0. // 1: // Probar acciones en cada situación de la lista nro 0, // guardando en una nueva lista las nuevas situaciones (que no... // sean victoria ni empate). Repetir con cada nueva lista hasta... // la que tenga situaciones en que sólo 1 acción es posible // (por ejemplo en el 3 en línea es la 8). // 2: // Probar acciones en cada situación de la última lista, // guardando datos sobre las consecuencias (victoria o empate) // de realizar la única acción posible. // 3: // En las situaciones no resueltas, empezando por las... // penúltimas listas, probar las acciones. // Guardar cuántas acciones causan victoria de uno, de otro y... // de empate. Averiguar la mejor acción en cada situación, // basado en el mejor resultado seguro que causa (asumiendo... // que el rival juega bien), y en 2nda instancia el más probable // (asumiendo que el rival juegue al azar). // Repetir hasta resolver la lista 0. JuntosRequeridos = 2; CasillerosPorFila = 2; // Contando desde 0: MaxColumna = CasillerosPorFila-1; Casilleros = CasillerosPorFila*CasillerosPorFila; // Están numerados así: // 0 1 // 2 3 MaxCasillero = Casilleros-1; // En las listas L_SaE se irán poniendo las situaciones a... // experimentar que tengan _ signos colocados. // En la lista 0 se agregará una situación: L0SaE1 = []; // A continuación se especifica cual, agregando v // (que significa vacío) en lo que serían los casilleros, // los elementos del array: ValoraAgregar = -1; do { ValoraAgregar++; L0SaE1.push("v"); } while (ValoraAgregar < MaxCasillero); delete ValoraAgregar; // Los datos de las situaciones no están en las listas, // se crean aparte. Con esta variable se evita repetidamente... // convertir en texto y concatenar: S_ = "S"+(L0SaE1.join("")); // Datos de la situación: // Usada para fácilmente saber de qué signo es turno: set (S_+"Turno", "X"); // En otros casos usada para evitar probar acciones... // innecesarias y con LastAPosible para saber si sólo queda 1: set (S_+"FirstAPosible", 0); set (S_+"LastAPosible", MaxCasillero); NroDeListaRevisandose = -1; // Última lista que se revisará en la etapa 1: // LastListaDeEt1 = Casilleros; // ///////////////////////////////////////////// // ///////////////// Etapa 1 ///////////////// // ///////////////////////////////////////////// // Consiste en llegar a nuevas situaciones y guardarlas, // si no son victoria. Termina antes de que pueda haber empates. // // Usada a continuación y durante la etapa 1 (Et1)... // cuando no hay más situaciones en la lista revisándose: function BuscarOtraListaEt1 () { trace("Ejecutando BuscarOtraListaEt1"); NroDeListaRevisandose++; PrepararUsoDeLista(); PrepararSaE(); // Si las situaciones de la lista tienen más de 1 opción: if (NroDeListaRevisandose < MaxCasillero) { // Para evitar concatenar cosas al guardar datos de situaciones nuevas: NextL_SaE = "L"+(NroDeListaRevisandose+1)+"SaE"; // trace("NextL_SaE: "+NextL_SaE); // Usado en EvaluarConocimientoSobreSEt1 para... // nombrar las situaciones nuevas que se logren: SituacionesNuevas = 0; } else { trace( "La lista actual tiene situaciones de sólo 1 opción; inicia la etapa 2."); // Iniciar Etapa 2: gotoAndStop(3); } } BuscarOtraListaEt1(); // Usada cuando se cambia de lista, en BuscarOtraListaEt1, // al comenzar Et2 y en Et3: function PrepararUsoDeLista () { trace("Ejecutando PrepararUsoDeLista"); // Para evitar concatenar repetidamente: L_SaE = "L"+NroDeListaRevisandose+"SaE"; // trace("L_SaE: "+L_SaE); NroDeSExperimentandose = 1; // También para evitar concatenar repetidamente: // L_SaE_ = L_SaE+NroDeSExperimentandose; L_SaE_ = L_SaE+"1"; // trace("L_SaE_: "+L_SaE_); trace("La lista preparada es la "+NroDeListaRevisandose); } // Usada cuando se elige una SaE, en BuscarOtraListaEt1, // BuscarOtraSituacionEt1, BuscarOtraSituacionEt2 y PrepararSaEEt3: function PrepararSaE () { trace("Ejecutando PrepararSaE"); SituacionBase = eval(L_SaE_).slice(); trace("Se inician experimentos en otra situación de la lista, la nro "+NroDeSExperimentandose+", que es "+SituacionBase); S_ = "S"+(SituacionBase.join("")); Turno = eval(S_+"Turno"); FirstActionPosible = eval(S_+"FirstAPosible"); LastActionPosible = eval(S_+"LastAPosible"); Action = FirstActionPosible; } // Usada en frame 2 (o etapa 1) repetidamente: function ResetearSituacionEt1 () { trace("Ejecutando ResetearSituacionEt1"); // Plantear situación porque puede modificarse pero... // podría requerirse su estado original luego: Situacion = SituacionBase.slice(); // trace("La situación experimentándose es "+Situacion); EvaluarAplicabilidadEt1(); } // Usada luego de que cambia la SaE y/o la acción, en Et1: function EvaluarAplicabilidadEt1 () { trace("Ejecutando EvaluarAplicabilidadEt1"); if (Situacion[Action] == "v") { trace("La acción "+Action+" es realizable."); AplicarAccionEt1(); } else { trace("La acción "+Action+" no es realizable."); SinResetBuscarOtraAccionEt1(); } } // Usada luego de EvaluarAplicabilidadEt1, // si una acción es realizable: function AplicarAccionEt1 () { trace("Ejecutando AplicarAccionEt1"); Situacion[Action] = Turno; trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion); // ¿Ganó? // Si no se detecta victoria vertical, // revisa de otros modos (ver las funciones Chequear): ChequearVertical(); if (Win == "No") { EvaluarConocimientoSobreSEt1(); } // ¿Queda alguna acción sin probar en la situación? BuscarOtraAccionEt1(); } // Usada en EvaluarAplicabilidadEt1 cuando una acción no es... // realizable: function SinResetBuscarOtraAccionEt1 () { trace("Ejecutando SinResetBuscarOtraAccionEt1"); if (Action < LastActionPosible) { // Si queda alguna acción sin probar... // en la situación, probarla: Action++; EvaluarAplicabilidadEt1(); } else { trace("No hay más acciones realizables."); BuscarOtraSituacionEt1(); } } // Usada luego de AplicarAccionEt1: function BuscarOtraAccionEt1 () { trace("Ejecutando BuscarOtraAccionEt1"); if (Action < LastActionPosible) { // Si queda alguna acción sin probar... // en la situación, probarla: Action++; trace("La nueva acción a probar es "+Action); // Se ejecutará ResetearSituacionEt1. } else { trace("No hay más acciones realizables."); BuscarOtraSituacionEt1(); } } // Usada en AplicarAccionEt1 cuando no hay victoria (ni empate, // aunque por ahora no ocurren): function EvaluarConocimientoSobreSEt1 () { trace("Ejecutando EvaluarConocimientoSobreSEt1"); // Estas 3 variables son para evitar reconcatenar: SituacionJoined = Situacion.join(""); NewS_ = "S"+SituacionJoined; NewS_BestAction = NewS_+"BestAction"; // ¿Se ha llegado antes a la situación? if (eval(NewS_BestAction) == undefined) { // No, anotar que debe investigarse: SituacionesNuevas++; // Copiar array (porque no se puede normalmente): trace("Situación a copiar a "+NextL_SaE+SituacionesNuevas+" es "+Situacion); set (NextL_SaE+SituacionesNuevas, Situacion.slice()); trace("Esa situación no está anotada; se anota como nro "+SituacionesNuevas); // trace(" NewS_: "+NewS_); // trace(" NewS_BestAction: "+NewS_BestAction); set(NewS_BestAction, "Desconocida"); if (Turno == "X") { set (NewS_+"Turno", "0"); } else { set (NewS_+"Turno", "X"); } // Averiguar cual es su 1er acción posible: AccionRevisandose = -1; do { AccionRevisandose++; if (Situacion[AccionRevisandose] == "v") { set (NewS_+"FirstAPosible", AccionRevisandose); break; } } while (true); // Averiguar cual es su última acción posible: AccionRevisandose = Casilleros; do { AccionRevisandose--; if (Situacion[AccionRevisandose] == "v") { set (NewS_+"LastAPosible", AccionRevisandose); break; } } while (true); } } // Usada en BuscarOtraAccionEt1 cuando no hay más acciones posibles, // y en SinResetBuscarOtraAccionEt1: function BuscarOtraSituacionEt1 () { trace("Ejecutando BuscarOtraSituacionEt1"); NroDeSExperimentandose++; if (eval(L_SaE+NroDeSExperimentandose) != undefined) { // Hay otra situación en la lista, // prepararse a usarla: L_SaE_ = L_SaE+NroDeSExperimentandose; PrepararSaE(); } else { trace("No hay más situaciones a experimentar en la lista actual, se mirará otra."); BuscarOtraListaEt1(); } } // ///////////////////////////////////////////// // ///////////////// Etapa 2 ///////////////// // ///////////////////////////////////////////// // Consiste en guardar el resultado de las situaciones en que... // sólo 1 acción es posible. Puede ser victoria o empate. // // Usada en frame 3 (o etapa 2) repetidamente: function ResetearSituacionEt2 () { trace("Ejecutando ResetearSituacionEt2"); // Plantear situación porque puede modificarse pero... // podría requerirse su estado original luego: Situacion = SituacionBase.slice(); trace("La situación experimentándose es "+Situacion); AplicarAccionEt2(); } // Usada luego de ResetearSituacionEt2, parece innecesario que sea función: function AplicarAccionEt2 () { trace("Ejecutando AplicarAccionEt2"); Situacion[Action] = Turno; trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion); // ¿Ganó? // Si no se detecta victoria vertical, // revisa de otros modos (ver las funciones Chequear): ChequearVertical(); set(S_+"BestAction", Action); if (Win == "Sí") { trace("Victoria conseguida, guardando datos."); if (Turno == "X") { // Estas son las chances de que gane... // X, 0 o que haya empate: set(S_+"VictoriasDeX", 1); set(S_+"VictoriasDe0", 0); set(S_+"ResultadoEsperado", "X"); } else { set(S_+"VictoriasDeX", 0); set(S_+"VictoriasDe0", 1); set(S_+"ResultadoEsperado", "0"); } set(S_+"DistanciaaGanar", 1); set(S_+"Empates", 0); } else { trace("Empate conseguido, guardando datos."); set(S_+"VictoriasDeX", 0); set(S_+"VictoriasDe0", 0); set(S_+"Empates", 1); set(S_+"ResultadoEsperado", "E"); } // ¿Queda alguna situación en la lista experimentándose? BuscarOtraSituacionEt2(); } // Usada luego de AplicarAccionEt2, parece innecesario que sea función: function BuscarOtraSituacionEt2 () { trace("Ejecutando BuscarOtraSituacionEt2"); NroDeSExperimentandose++; if (eval(L_SaE+NroDeSExperimentandose) != undefined) { // Hay otra situación en la lista, // prepararse a usarla: L_SaE_ = L_SaE+NroDeSExperimentandose; PrepararSaE(); } else { trace("No hay más situaciones a experimentar en la lista actual, inicia la etapa 3."); BuscarOtraListaEt3(); gotoAndStop(4); } } // ///////////////////////////////////////////// // ///////////////// Etapa 3 ///////////////// // ///////////////////////////////////////////// // Consiste en guardar los resultados de las acciones en... // situaciones en que más de 1 acción es posible. // Particularmente se guarda la mejor acción. // El resultado de las acciones puede ser victoria, // una situación con posibles resultados, // y en la penúltima lista una situación con un único posible... // resultado. // // Usada antes y durante esta etapa... // cuando no hay más situaciones en la lista revisándose: function BuscarOtraListaEt3 () { trace("Ejecutando BuscarOtraListaEt3"); NroDeListaRevisandose--; if (NroDeListaRevisandose > -1) { // Si se halla una lista: PrepararUsoDeLista(); PrepararSaEEt3(); } else { trace("No hay más listas a revisar; programa terminado."); // En este frame nada hay, es sólo para mostrar el mensaje: gotoAndStop(5); } } // Casi como PrepararSaE. Usada cuando se elige una SaE, // en BuscarOtraListaEt3 y BuscarOtraSituacionEt3: function PrepararSaEEt3 () { trace("Ejecutando PrepararSaEEt3"); PrepararSaE(); // Para evitar evals y concatenaciones repetidamente: BestAction = ""; VictoriasDeX = 0; VictoriasDe0 = 0; Empates = 0; // Establecer que hasta ahora los resultados hallados... // son peores que lo posible, para que se sustituyan por... // cualquier acción: if (Turno == "X") { // La E antes de Obtenido es Esperado: BestResultadoEObtenido = "0"; } else { BestResultadoEObtenido = "X"; } // Si 2 acciones causan victoria segura, // esto sirve para elegir la mejor de ellas: BestDistanciaaGanar = Casilleros; // Si 2 acciones causan empate seguro, // esto sirve para elegir la mejor de ellas: BestChanceDeGanarEnE = -1; BestChanceDeEmpatarEnE = -1; // Si 2 acciones causan derrota segura, // esto sirve para elegir la mejor de ellas: LowestChanceDePerderEnD = -1; BestChanceDeGanarEnD = -1; } // Usada en frame 4 (o etapa 3) repetidamente: function ResetearSituacionEt3 () { // Plantear situación porque puede modificarse pero... // podría requerirse su estado original luego: Situacion = SituacionBase.slice(); trace("La situación experimentándose es "+Situacion); EvaluarAplicabilidadEt3(); } // Usada luego de que cambia la SaE y/o la acción, en Et3: function EvaluarAplicabilidadEt3 () { trace("Ejecutando EvaluarAplicabilidadEt3"); if (Situacion[Action] == "v") { trace("La acción "+Action+" es realizable."); AplicarAccionEt3(); } else { trace("La acción "+Action+" no es realizable."); SinResetBuscarOtraAccionEt3(); } } // Usada luego de EvaluarAplicabilidadEt3, // si una acción es realizable: function AplicarAccionEt3 () { // Los datos se guardarán bien en GuardarDatosEt3. // Por ahora varios se están guardando en variables más simples de nombrar. // Además algunos no se pueden guardar aún (VictoriasDeX, NewVictoriasDe0...). // Y DistanciaaGanar se está guardando como -1 de lo que debe, para no tener que estar sumando. trace("Ejecutando AplicarAccionEt3"); Situacion[Action] = Turno; trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion); // ¿Ganó? // Si no se detecta victoria vertical, // revisa de otros modos (ver las funciones Chequear): ChequearVertical(); if (Win == "No") { trace("No hubo victoria, agregando datos..."); // Agregar los posibles resultados de la... // situación obtenida: // Estas 5 variables son para evitar reconcatenar: SituacionJoined = Situacion.join(""); NewS_ = "S"+SituacionJoined; NewVictoriasDeX = eval(NewS_+"VictoriasDeX"); NewVictoriasDe0 = eval(NewS_+"VictoriasDe0"); NewEmpates = eval(NewS_+"Empates"); VictoriasDeX = VictoriasDeX+NewVictoriasDeX; VictoriasDe0 = VictoriasDe0+NewVictoriasDe0; Empates = Empates+NewEmpates; trace(VictoriasDeX+", "+VictoriasDe0+", "+Empates); // Si en la SaE ya se halló una acción que... // causa victoria segura: if (BestResultadoEObtenido == Turn) { trace("El mejor resultado logrado es victoria"); // Si la acción recién usada también causa eso: if (eval(NewS_+"ResultadoEsperado") == Turn) { trace("La acción causa victoria segura (no inmediata)"); trace("Pero ya se halló otra, se verá cual causa más rápido"); // Si dicha acción la causa faster: if (eval(NewS_+"DistanciaaGanar") < BestDistanciaaGanar) { // Sustituir datos: trace("La nueva fue mejor, sustituyendo datos..."); BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar"); BestAction = Action; } // SINO SI LA CAUSA IGUAL DE RÁPIDO HABRÍA QUE AVERIGUAR CHANCES, pero se gana igual... // sino dicha acción es peor, no prestarle más atención. } // idem. // sino si el mejor resultado esperado hallado... // en esta SaE es empate: } else if (BestResultadoEObtenido == "E") { trace("Por ahora el mejor resultado logrado es empate"); // Si la acción recién usada causa que... // el resultado esperado sea victoria: if (eval(NewS_+"ResultadoEsperado") == Turn) { // Sustituir datos: trace("La acción causa victoria segura (no inmediata)"); trace("Sustituyendo datos..."); BestResultadoEObtenido = Turn; BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar"); BestAction = Action; // sino si es empate: } else if (eval(NewS_+"ResultadoEsperado") == "E") { trace("La acción causa empate seguro (no inmediato)"); // Averiguar chance de victoria: Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates; ChanceDeGanar = eval("NewVictoriasDe"+Turno)*100/Posibilidades; // Si es mejor que la hallada antes: if (ChanceDeGanar > BestChanceDeGanarEnE) { // Sustituir datos: BestChanceDeGanarEnE = ChanceDeGanar; BestChanceDeEmpatarEnE = NewEmpates*100/Posibilidades; BestAction = Action; // sino si la chance es igual: } else if (ChanceDeGanar == BestChanceDeGanarEnE) { // Averiguar chance de empate: ChanceDeEmpatar = NewEmpates*100/Posibilidades; // Si es mejor que la hallada antes: if (ChanceDeEmpatar > BestChanceDeEmpatarEnE) { // Sustituir datos: // BestChanceDeGanarEnE = ChanceDeGanar; BestChanceDeEmpatarEnE = ChanceDeEmpatar; BestAction = Action; } } // SINO SI LAS CHANCES SON LAS MISMAS HABRÍA QUE DECIDIR SI SE PREFIERE LA QUE LO CAUSA MÁS RÁPIDO O NO. // sino dicha acción no es mejor, no prestarle más atención. // idem. } // El resultado esperado es derrota: } else { // Si la acción recién usada causa que... // el resultado esperado sea victoria: if (eval(NewS_+"ResultadoEsperado") == Turn) { // Sustituir datos: BestResultadoEObtenido = Turn; BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar"); BestAction = Action; // sino si es empate: } else if (eval(NewS_+"ResultadoEsperado") == "E") { // Averiguar chances y sustituir datos: Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates; BestChanceDeGanarEnE = eval("NewVictoriasDe"+Turno)*100/Posibilidades; BestChanceDeEmpatarEnE = NewEmpates*100/Posibilidades; BestResultadoEObtenido = "E"; BestAction = Action; // sino es derrota: } else { // Averiguar chance de perder: Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates; ChanceDePerder = 100-(eval("NewVictoriasDe"+Turno)+NewEmpates)*100/Posibilidades; // Si es más baja (mejor) que la hallada antes: if (ChanceDePerder < LowestChanceDePerderEnD) { // Sustituir datos: LowestChanceDePerderEnD = ChanceDePerder; BestChanceDeGanarEnD = eval("NewVictoriasDe"+Turno)*100/Posibilidades; BestAction = Action; // sino si la chance es igual: } else if (ChanceDePerder == LowestChanceDePerderEnD) { // Averiguar chance de victoria: ChanceDeGanar = eval("NewVictoriasDe"+Turno)*100/Posibilidades; // Si es mejor que la hallada antes: if (ChanceDeGanar > BestChanceDeGanarEnD) { // Sustituir datos: LowestChanceDePerderEnD = ChanceDePerder; BestChanceDeGanarEnD = ChanceDeGanar; BestAction = Action; } } } } // sino la acción causa una victoria inmediata: } else { // Incrementar victorias: // Esta es para evitar reconcatenar: VariableaIncrementar = "VictoriasDe"+Turno; set (VariableaIncrementar, eval(VariableaIncrementar)+1); if (BestDistanciaaGanar > 0) { // Sustituir datos: BestResultadoEObtenido = Turn; BestDistanciaaGanar = 0; BestAction = Action; } } // ¿Queda alguna acción sin probar en la situación? BuscarOtraAccionEt3(); } // Usada en EvaluarAplicabilidadEt3 cuando una acción no es... // realizable: function SinResetBuscarOtraAccionEt3 () { trace("Ejecutando SinResetBuscarOtraAccionEt3"); if (Action < LastActionPosible) { // Si queda alguna acción sin probar... // en la situación, probarla: Action++; EvaluarAplicabilidadEt3(); } else { trace("No hay más acciones realizables."); BuscarOtraSituacionEt3(); } } // Usada luego de AplicarAccionEt3: function BuscarOtraAccionEt3 () { trace("Ejecutando BuscarOtraAccionEt3"); if (Action < LastActionPosible) { // Si queda alguna acción sin probar... // en la situación, probarla: Action++; // Se ejecutará ResetearSituacionEt3. } else { trace("No hay más acciones realizables."); BuscarOtraSituacionEt3(); } } // Usada cuando no hay más acciones posibles: function GuardarDatosEt3 () { trace("Ejecutando GuardarDatosEt3"); set(S_+"VictoriasDeX", VictoriasDeX); set(S_+"VictoriasDe0", VictoriasDe0); set(S_+"Empates", Empates); set(S_+"BestAction", BestAction); set(S_+"DistanciaaGanar", BestDistanciaaGanar+1); set(S_+"ResultadoEsperado", BestResultadoEObtenido); } // Usada en BuscarOtraAccionEt3 cuando no hay más acciones posibles, // y en SinResetBuscarOtraAccionEt3: function BuscarOtraSituacionEt3 () { trace("Ejecutando BuscarOtraSituacionEt3"); NroDeSExperimentandose++; if (eval(L_SaE+NroDeSExperimentandose) != undefined) { // Hay otra situación en la lista, // prepararse a usarla: L_SaE_ = L_SaE+NroDeSExperimentandose; PrepararSaEEt3(); } else { trace("No hay más situaciones a experimentar en la lista actual, se mirará otra."); BuscarOtraListaEt3(); } } // ///////////////////////////////////////////// // ///////////////// Chequeos //////////////// // ///////////////////////////////////////////// // Usada en ChequeoHorizontal y requerida en otros casos: function ObtenerColumnayFilaDelMarcado () { FilaDelMarcado = Math.floor(Action/CasillerosPorFila); ColumnaDelMarcado = Action%CasillerosPorFila; } function ChequearVertical () { // trace ("Ejecutando ChequearVertical"); // // SOLO FUNCIONA SI CasillerosPorFila >= JuntosRequeridos. // // Se revisará la vertical. Desde el casillero más arriba... // que pueda estar incluído en la línea, // hasta el casillero marcado. Si se halla alguno que no... // tenga la marca requerida, se repite el proceso mirando... // desde uno más abajo del fallado, y mirando ahora hasta... // más abajo, según corresponda: Desde = Action-CasillerosPorFila*(JuntosRequeridos-1); // Mientras el casillero no exista: while (Desde<0) { // trace ("Desde es "+Desde+", se aumentará"); // Indicar que se empiece a mirar desde más abajo: Desde = Desde+CasillerosPorFila; } do { Hasta = Desde+CasillerosPorFila*(JuntosRequeridos-1); if (Hasta>MaxCasillero) { // Para ganar se necesitaría más casilleros hacia... // abajo de los que hay, terminar análisis: // trace ("No hay suficientes cuadraditos abajo"); break; } Puntero = Desde; // trace ("Comenzando chequeo desde "+Desde+" hasta "+Hasta); // Puede cambiar: Win = "Sí"; do { // trace ("Chequando el casillero "+Puntero); if (Situacion[Action] != Situacion[Puntero]) { Win = "No"; Desde = Puntero+CasillerosPorFila; break; } Puntero = Puntero+CasillerosPorFila; } while (Puntero<=Hasta); } while (Desde<=Action && Win == "No"); if (Win == "No") { // ChequearHorizontal(); } } function ChequearHorizontal () { // trace ("Ejecutando ChequearHorizontal"); // Es similar al chequeo vertical, pero aquí no sirve... // sumar o restar a un puntero que marque el casillero... // porque puede existir ese casillero pero no estar en... // un costado. En vez de eso, se obtiene su columna y... // fila, se modifica la columna si es posible, // y se calcula cual es el casillero a mirar: ObtenerColumnayFilaDelMarcado(); DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1; // Para que no mire cuadraditos inexistentes en la izq: if (DesdeColumna<0) { DesdeColumna = 0; } do { HastaColumna = DesdeColumna+JuntosRequeridos-1; if (HastaColumna>MaxColumna) { // Para ganar se necesitaría más casilleros hacia... // la derecha de los que hay, terminar análisis: // trace ("No hay suficientes cuadraditos a la derecha"); break; } Puntero = DesdeColumna; // trace ("Comenzando chequeo desde "+DesdeColumna+" hasta "+HastaColumna); // Puede cambiar: Win = "Sí"; do { CasilleroaMirar = FilaDelMarcado*CasillerosPorFila+Puntero; // trace ("Chequando el casillero "+CasilleroaMirar); if (Situacion[Action] != Situacion[CasilleroaMirar]) { Win = "No"; DesdeColumna = Puntero+1; break; } Puntero++; } while (Puntero<=HastaColumna); } while (DesdeColumna<=ColumnaDelMarcado && Win == "No"); if (Win == "No") { ChequearDesdeUpIzq(); } } // La diagonal así \ function ChequearDesdeUpIzq () { // trace ("Ejecutando ChequearDesdeUpIzq"); DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1; // trace("DesdeColumna: "+DesdeColumna); DesdeFila = FilaDelMarcado-JuntosRequeridos+1; // trace("DesdeFila: "+DesdeFila); // Para que no mire cuadraditos inexistentes: if (DesdeColumna<DesdeFila) { Sumar = DesdeColumna; } else { Sumar = DesdeFila; } // trace("Sumar: "+Sumar); if (Sumar<0) { // trace("Sumando."); DesdeColumna = DesdeColumna-Sumar; // trace("DesdeColumna: "+DesdeColumna); DesdeFila = DesdeFila-Sumar; // trace("DesdeFila: "+DesdeFila); } do { HastaColumna = DesdeColumna+JuntosRequeridos-1; if (HastaColumna>MaxColumna) { // Para ganar se necesitaría más casilleros hacia... // la derecha de los que hay, terminar análisis: // trace ("No hay suficientes cuadraditos a la derecha"); break; } HastaFila = DesdeFila+JuntosRequeridos-1; // Sirve usar MaxColumna en vez de crear MaxFila... // porque como el tablero es cuadrado serían iguales: if (HastaFila>MaxColumna) { // Para ganar se necesitaría más casilleros hacia... // abajo de los que hay, terminar análisis: // trace ("No hay suficientes cuadraditos abajo"); break; } PunteroDeColumna = DesdeColumna; PunteroDeFila = DesdeFila; // trace ("Comenzando chequeo desde columna "+DesdeColumna+" y fila "+DesdeFila); // trace ("hasta columna "+HastaColumna+" y fila "+HastaFila); // Puede cambiar: Win = "Sí"; do { CasilleroaMirar = PunteroDeFila*CasillerosPorFila+PunteroDeColumna; // trace ("Chequando el casillero "+CasilleroaMirar); if (Situacion[Action] != Situacion[CasilleroaMirar]) { Win = "No"; DesdeColumna = PunteroDeColumna+1; DesdeFila = PunteroDeFila+1; break; } PunteroDeColumna++; PunteroDeFila++; } while (PunteroDeColumna<=HastaColumna); } while (DesdeColumna<=ColumnaDelMarcado && Win == "No"); if (Win == "No") { ChequearDesdeDownIzq(); } } // La diagonal así / function ChequearDesdeDownIzq () { // trace ("Ejecutando ChequearDesdeDownIzq"); DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1; // trace("DesdeColumna: "+DesdeColumna); DesdeFila = FilaDelMarcado+JuntosRequeridos-1; // trace("DesdeFila: "+DesdeFila); // Para que no mire cuadraditos inexistentes: ColumnasInexistentes = 0; if (DesdeColumna<0) { ColumnasInexistentes = DesdeColumna*-1; } FilasInexistentes = 0; // Está bien usar MaxColumna porque MaxFila sería igual: if (DesdeFila>MaxColumna) { FilasInexistentes = DesdeFila-MaxColumna; } if (ColumnasInexistentes>=FilasInexistentes) { Ajuste = ColumnasInexistentes; } else { Ajuste = FilasInexistentes; } // trace("Ajuste: "+Ajuste); if (Ajuste>0) { // trace("Ajustando."); DesdeColumna = DesdeColumna+Ajuste; // trace("DesdeColumna: "+DesdeColumna); DesdeFila = DesdeFila-Ajuste; // trace("DesdeFila: "+DesdeFila); } do { HastaColumna = DesdeColumna+JuntosRequeridos-1; if (HastaColumna>MaxColumna) { // Para ganar se necesitaría más casilleros hacia... // la derecha de los que hay, terminar análisis: // trace ("No hay suficientes cuadraditos a la derecha"); break; } HastaFila = DesdeFila-JuntosRequeridos+1; if (HastaFila<0) { // Para ganar se necesitaría más casilleros hacia... // arriba de los que hay, terminar análisis: // trace ("No hay suficientes cuadraditos arriba"); break; } PunteroDeColumna = DesdeColumna; PunteroDeFila = DesdeFila; // trace ("Comenzando chequeo desde columna "+DesdeColumna+" y fila "+DesdeFila); // trace ("hasta columna "+HastaColumna+" y fila "+HastaFila); // Puede cambiar: Win = "Sí"; do { CasilleroaMirar = PunteroDeFila*CasillerosPorFila+PunteroDeColumna; // trace ("Chequando el casillero "+CasilleroaMirar); if (Situacion[Action] != Situacion[CasilleroaMirar]) { Win = "No"; DesdeColumna = PunteroDeColumna+1; DesdeFila = PunteroDeFila-1; break; } PunteroDeColumna++; PunteroDeFila--; } while (PunteroDeColumna<=HastaColumna); } while (DesdeColumna<=ColumnaDelMarcado && Win == "No"); // trace("Win: "+Win); }
Necesito practicar con un juego más sencillo :/