// Juego simple para aprender a programar mejor:
// Aportar o no, 1 o 0, 2 jugadores se turnan aportando o...
// no, hasta que haya 3 aportes o 2 fallos. No son rivales,
// ganan ambos o pierden ambos.
// Este programa tiene básicamente 2 etapas,
// que se pueden resumir así:
// Nota: La situación inicial, en que no se realizaron acciones,
// estará guardada en la lista nro 0 (0 acciones).
// 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 derrota). Repetir con cada nueva lista...
// hasta que no se genere una nueva situación.
// 2:
// Desde las últimas listas, probar las acciones.
// Guardar cuántas acciones causan victoria y cuántas derrota.
// Averiguar la mejor acción en cada situación, basado en el...
// mejor resultado seguro que causa (asumiendo que el compañero...
// juega bien), y en 2nda instancia el más probable (asumiendo...
// que juegue al azar). Repetir hasta resolver la lista 0.
AportesRequeridos = 3;
FallosParaDerrota = 2;
// En las listas L_SaE se irán poniendo las situaciones a...
// experimentar en que hayan transcurrido _ turnos.
// En la lista 0 se agrega una situación, la inicial:
L0SaE1 = "";
// 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";
// Datos de la situación:
// Usada para fácilmente saber de qué signo es turno:
set (S_+"Turno", "X");
NroDeListaRevisandose = -1;
// /////////////////////////////////////////////
// ///////////////// Etapa 1 /////////////////
// /////////////////////////////////////////////
// Consiste en llegar a nuevas situaciones y guardarlas,
// si no son victoria ni derrota.
//
// 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();
// El if no está bien, pero funcionará creo:
// Si la lista tiene alguna situación:
if (NroDeListaRevisandose < 5) {
// 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( "No se hallaron situaciones en la nueva lista; inicia la etapa 2.");
// Iniciar Etapa 3:
gotoAndStop(4);
}
}
BuscarOtraListaEt1();
// Usada cuando se cambia de lista, en BuscarOtraListaEt1,
// y al comenzar Et2:
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+"1";
// trace("L_SaE_: "+L_SaE_);
trace("La lista preparada es la "+NroDeListaRevisandose);
}
// Usada cuando se elige una SaE, en BuscarOtraListaEt1,
// BuscarOtraSituacionEt1 y PrepararSaEEt3:
function PrepararSaE () {
trace("Ejecutando PrepararSaE");
SituacionBase = eval(L_SaE_);
trace("Se inician experimentos en otra situación de la lista, la nro "+NroDeSExperimentandose+", que es "+SituacionBase);
S_ = "S"+SituacionBase;
Turno = eval(S_+"Turno");
Action = 0;
}
// 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;
// trace("La situación experimentándose es "+Situacion);
EvaluarAplicabilidadEt1();
}
// Inútil aquí, queda para no complicar la simplificación:
function EvaluarAplicabilidadEt1 () {
AplicarAccionEt1();
}
// Usada luego de EvaluarAplicabilidadEt1,
// si una acción es realizable:
function AplicarAccionEt1 () {
trace("Ejecutando AplicarAccionEt1");
Situacion = Situacion+Action;
trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
// ¿Se debe continuar? ¿hay 2 0s o 3 1s?
EvaluarContinuabilidad();
if (Continuabilidad == "Sí") {
EvaluarConocimientoSobreSEt1();
}
// ¿Queda alguna acción sin probar en la situación?
BuscarOtraAccionEt1();
}
// Usada en AplicarAccionEt1:
function EvaluarContinuabilidad () {
trace("Ejecutando EvaluarContinuabilidad");
Continuabilidad = "Sí";
CantidadDe0s = 0;
CantidadDe1s = 0;
CaracteraContar = 0;
do {
if (Situacion.charat(CaracteraContar) == "0") {
CantidadDe0s++;
} else {
CantidadDe1s++;
}
CaracteraContar++;
} while (CaracteraContar < Situacion.length);
if (CantidadDe0s == 2) {
trace ("Se hallaron 2 0s");
Continuabilidad = 0;
} else if (CantidadDe1s == 3) {
trace ("Se hallaron 3 1s");
Continuabilidad = 1;
}
}
// Usada en EvaluarAplicabilidadEt1 cuando una acción no es...
// realizable:
function SinResetBuscarOtraAccionEt1 () {
trace("Ejecutando SinResetBuscarOtraAccionEt1");
if (Action < 1) {
// 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 < 1) {
// 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 2 variables son para evitar reconcatenar:
NewS_ = "S"+Situacion;
NewS_BestAction = NewS_+"BestAction";
// ¿Se ha llegado antes a la situación?
if (eval(NewS_BestAction) == undefined) {
// No, anotar que debe investigarse:
SituacionesNuevas++;
trace("Situación a anotar a "+NextL_SaE+SituacionesNuevas+" es "+Situacion);
set (NextL_SaE+SituacionesNuevas, Situacion);
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");
}
}
}
// 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 /////////////////
// /////////////////////////////////////////////
// Innecesaria aquí.
// /////////////////////////////////////////////
// ///////////////// 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 = "";
Victorias = 0;
Derrotas = 0;
// Establecer que hasta ahora los resultados hallados...
// son peores que lo posible, para que se sustituyan por...
// cualquier acción:
// EL VALOR DEBERÍA SER PEOR?
BestResultadoEObtenido = "Derrota";
// Si 2 acciones causan victoria segura,
// esto sirve para elegir la mejor de ellas:
BestDistanciaaGanar = 10;
// No HAY DERROTA SEGURA, esto está por probar...
// Si 2 acciones causan derrota segura,
// esto sirve para elegir la mejor de ellas:
BestChanceDeGanarEnD = -1;
BestDistanciaaGanarEnD = 10;
}
// 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;
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 () {
AplicarAccionEt3();
}
// 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 = Situacion+Action;
trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
// ¿Se debe continuar? ¿hay 2 0s o 3 1s?
EvaluarContinuabilidad();
if (Continuabilidad == "Sí") {
trace("No hubo victoria, agregando datos...");
// Agregar los posibles resultados de la...
// situación obtenida:
// Estas 5 variables son para evitar reconcatenar:
NewS_ = "S"+Situacion;
NewVictorias = eval(NewS_+"Victorias");
NewDerrotas = eval(NewS_+"Derrotas");
Victorias = Victorias+NewVictorias;
Derrotas = Derrotas+NewDerrotas;
trace(Victorias+", "+Derrotas);
// Si en la SaE ya se halló una acción que...
// causa victoria segura:
if (BestResultadoEObtenido == "Victoria") {
trace("El mejor resultado logrado es victoria");
// Si la acción recién usada también causa eso:
if (eval(NewS_+"ResultadoEsperado") == "Victoria") {
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 el mejor resultado esperado hallado es derrota:
} else {
// Si la acción recién usada causa que...
// el resultado esperado sea victoria:
if (eval(NewS_+"ResultadoEsperado") == "Victoria") {
// Sustituir datos:
BestResultadoEObtenido = "Victoria";
BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar");
BestAction = Action;
// sino es derrota:
} else {
// Averiguar chance de ganar:
Posibilidades = NewVictorias+NewDerrotas;
ChanceDeGanar = NewVictorias*100/Posibilidades;
// Si es más alta que la hallada antes:
if (ChanceDeGanar > BestChanceDeGanarEnD) {
// Sustituir datos:
BestChanceDeGanarEnD = ChanceDePerder;
BestAction = Action;
// sino si la chance es igual:
// ACÁ HABRÍA QUE VER LA DISTANCIA A GANAR EN D
// sino es peorm, no prestarle atención.
}
}
}
} else {
// Incrementar victorias:
// Esta es para evitar reconcatenar:
VariableaIncrementar = "Victorias";
set (VariableaIncrementar, eval(VariableaIncrementar)+1);
if (BestDistanciaaGanar > 0) {
// Sustituir datos:
BestResultadoEObtenido = "Victorias";
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();
}
}