// 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("Comienzan experimentos en una nueva lista, la "+NroDeListaRevisandose);
}
// Usada cuando se elige una SaE, en BuscarOtraListaEt1,
// BuscarOtraSituacionEt1, BuscarOtraSituacionEt2 y PrepararSaEEt3:
function PrepararSaE () {
trace("Ejecutando PrepararSaE");
trace("Se inician experimentos en otra situación de la lista, la nro "+NroDeSExperimentandose);
SituacionBase = eval(L_SaE_).slice();
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 () {
// 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++;
// 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);
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 () {
// 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") {
// 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;
// Si en la SaE ya se halló una acción que...
// causa victoria segura:
if (BestResultadoEObtenido == Turn) {
// Si la acción recién usada también causa eso:
if (eval(NewS_+"ResultadoEsperado") == Turn) {
// Si dicha acción la causa faster:
if (eval(NewS_+"DistanciaaGanar") < BestDistanciaaGanar) {
// Sustituir 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") {
// 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 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 = NewEmpatesDeX*100/Posibilidades;
BestResultadoEObtenido = "E";
BestAction = Action;
// sino es derrota:
} else {
// Averiguar chance de perder:
Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates;
ChanceDePerder = (Posibilidades-eval("NewVictoriasDe"+Turno)*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);
}