diff --git a/package-lock.json b/package-lock.json index 336bb4b..f136b47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "pilas-bloques-exercises", - "version": "1.4.11", + "version": "1.4.12", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 295ab15..dd92631 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pilas-bloques-exercises", - "version": "1.4.11", + "version": "1.4.12", "description": "Exercises for Pilas Bloques", "homepage": "http://pilasbloques.program.ar", "author": { diff --git a/src/actores/Casilla.ts b/src/actores/Casilla.ts index 9108402..3d00874 100644 --- a/src/actores/Casilla.ts +++ b/src/actores/Casilla.ts @@ -145,6 +145,10 @@ class Casilla extends ActorAnimado { return this.actores.some( actor => actor.tiene_etiqueta(unaEtq)) } + tieneMasDeUnActor(){ + return this.actores.length > 1 + } + actoresConEtiqueta(unaEtq) { return this.actores.filter(actor => actor.tiene_etiqueta(unaEtq)); } diff --git a/src/actores/segundoCiclo/Chuy/Chuy.ts b/src/actores/segundoCiclo/Chuy/Chuy.ts index 8364f85..98c23d3 100644 --- a/src/actores/segundoCiclo/Chuy/Chuy.ts +++ b/src/actores/segundoCiclo/Chuy/Chuy.ts @@ -19,10 +19,12 @@ class Chuy extends ActorAnimado { this.definirAnimacion("correr", [68, 69, 70, 71, 72, 73, 74, 75, 76], 12); this.definirAnimacion("correrChocando", [68, 69, 70, 71, 72, 73, 74, 75, 76], 12) this.definirAnimacion("obstaculo", [0, 1, 1, 2, 2, 3, 3, 4, 4, 4], 12) - this.definirAnimacion("error", [101, 101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105] - , 12) + this.definirAnimacion("error", [101, 101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105], 12) this.definirAnimacion("recoger", [97, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 100, 97], 12); + this.definirAnimacion("revolearPulpito", [ 97, 97, 97, 109, 109, 109, 108, 108, 108, 107, 107, 107, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, + 109, 109, 109, 108, 108, 108, 107, 107, 107, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 97, 97, 97], 12); this.definirAnimacion("usarPaleta", [51, 52, 53, 54, 55, 56, 57, 58, 57, 56, 55, 56, 57, 58, 57, 56, 55, 56, 57, 58, 57, 56, 55, 56, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67], 12); + this.definirAnimacion("usarPaletaUnaVez", [51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67], 6); this.definirAnimacion("rebotarPelota", [87, 88, 89, 90, 91, 92, 93, 92, 91, 90, 94, 95, 90, 91, 92, 93, 91, 94, 91, 93, 90, 94, 96, 87, 87, 87, 87], 12); this.definirAnimacion("patear", [87, 88, 89, 90, 91, 92, 93, 92, 91, 90, 94, 95, 90, 91, 92, 93, 91, 94, 91, 93, 90, 94, 96, 87, 87, 87, 87], 12) this.definirAnimacion("rebotarPulpito", [77, 78, 79, 80, 81, 82, 83, 82, 81, 80, 84, 85, 80, 81, 82, 83, 81, 84, 81, 83, 80, 84, 86, 77, 77, 77, 77], 12); diff --git a/src/actores/segundoCiclo/Manic/Manic.ts b/src/actores/segundoCiclo/Manic/Manic.ts index 9768606..552c0ca 100644 --- a/src/actores/segundoCiclo/Manic/Manic.ts +++ b/src/actores/segundoCiclo/Manic/Manic.ts @@ -7,15 +7,12 @@ class Manic extends ActorAnimado { constructor() { super(0,0,{cantColumnas: 10, cantFilas: 9}); this.definirAnimacion("parado", - new Cuadros(0).repetirVeces(16) + new Cuadros(32).repetirVeces(18) + .concat([33, 34, 34, 32, 32, 32, 32, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32]) + .concat(new Cuadros(32).repetirVeces(18)) + .concat([33, 34, 34, 32, 32, 32, 32, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32]) .concat([32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 32, 32, 32, 32, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32]) - .concat(new Cuadros(0).repetirVeces(30)) - .concat([32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 32, 32, 32, 32, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32]) - .concat(new Cuadros(0).repetirVeces(30)) - .concat([32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 32, 32, 32, 32, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32]) - .concat(new Cuadros(0).repetirVeces(16)) - .concat([32]) - .concat(new Cuadros(0).repetirVeces(5)), + .concat([32]), 20, true); this.definirAnimacion("correr", [0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 6, 7, 6, 5, 6, 7, 7], 20); this.definirAnimacion("correrChocando", [0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 6, 7, 6, 5, 6, 7, 7], 12) diff --git a/src/actores/segundoCiclo/MetaFinal.ts b/src/actores/segundoCiclo/MetaFinal.ts new file mode 100644 index 0000000..e9c0e0a --- /dev/null +++ b/src/actores/segundoCiclo/MetaFinal.ts @@ -0,0 +1,20 @@ +/// + +class MetaFinal extends ActorAnimado { + + static imagenesPara(actor) : string[] { + return [`marcador-${actor}.png`]; + } + + constructor(actor: string) { + super(0, 0, { grilla: `marcador-${actor}.png`, cantColumnas: 1, cantFilas: 1 }); + } + + enviarAtras() { + this.setZ(Math.min(this.getZ() + 1)) + } + + ajustarSegunCuadricula(alto){ + this.setY(this.getY() + alto / 2) + } +} \ No newline at end of file diff --git a/src/assets/actor.chuy.png b/src/assets/actor.chuy.png index c2f0fe6..6a65bb8 100644 Binary files a/src/assets/actor.chuy.png and b/src/assets/actor.chuy.png differ diff --git a/src/assets/fondo.superMaraton.png b/src/assets/fondo.superMaraton.png new file mode 100644 index 0000000..753073b Binary files /dev/null and b/src/assets/fondo.superMaraton.png differ diff --git a/src/assets/marcador-capy.png b/src/assets/marcador-capy.png new file mode 100644 index 0000000..4a893b3 Binary files /dev/null and b/src/assets/marcador-capy.png differ diff --git a/src/assets/marcador-chuy.png b/src/assets/marcador-chuy.png new file mode 100644 index 0000000..b470dcc Binary files /dev/null and b/src/assets/marcador-chuy.png differ diff --git a/src/assets/marcador-duba.png b/src/assets/marcador-duba.png new file mode 100644 index 0000000..caf533e Binary files /dev/null and b/src/assets/marcador-duba.png differ diff --git a/src/assets/marcador-lita.png b/src/assets/marcador-lita.png new file mode 100644 index 0000000..06b3a7e Binary files /dev/null and b/src/assets/marcador-lita.png differ diff --git a/src/assets/marcador-manic.png b/src/assets/marcador-manic.png new file mode 100644 index 0000000..ab38ec3 Binary files /dev/null and b/src/assets/marcador-manic.png differ diff --git a/src/assets/marcador-yvoty.png b/src/assets/marcador-yvoty.png new file mode 100644 index 0000000..81c3edd Binary files /dev/null and b/src/assets/marcador-yvoty.png differ diff --git a/src/assets/pelotaAnimada.png b/src/assets/pelotaAnimada.png index 6ce8c54..17ecd21 100644 Binary files a/src/assets/pelotaAnimada.png and b/src/assets/pelotaAnimada.png differ diff --git a/src/comportamientos/CorrerHeroicamente.ts b/src/comportamientos/CorrerHeroicamente.ts new file mode 100644 index 0000000..bc124a2 --- /dev/null +++ b/src/comportamientos/CorrerHeroicamente.ts @@ -0,0 +1,20 @@ +/// +/// + +class CorrerHeroicamente extends ComportamientoConVelocidad { + nombreAnimacion(){ + return 'correr'; + } + + preAnimacion(){ + this.argumentos.velocidad = 100; + this.argumentos.cantPasos = 1; + super.preAnimacion(); + this.receptor.escena.fondo.hacer_luego(GirarMarquesina,{}); + } + + postAnimacion(){ + super.postAnimacion(); + if(this.receptor.fraseAlCorrer) this.receptor.decir(this.receptor.fraseAlCorrer()); + } +} diff --git a/src/comportamientos/PingPongAnimado.ts b/src/comportamientos/PingPongAnimado.ts new file mode 100644 index 0000000..080c44f --- /dev/null +++ b/src/comportamientos/PingPongAnimado.ts @@ -0,0 +1,20 @@ +/// +/// + +/* +Comportamiento que hace decir una +frase definida por la escena +*/ + +class PingPongAnimado extends Decir { + preAnimacion(): void { + this.receptor.escena.antesDeRebotar(); + this.argumentos.mensaje = this.receptor.escena.getFraseAlRebotar() + super.preAnimacion(); + } + + postAnimacion(){ + super.postAnimacion(); + this.receptor.decir(this.receptor.escena.fraseAlRebotar()); + } +} diff --git a/src/escenas/ChuyHaciendoJueguito.ts b/src/escenas/ChuyHaciendoJueguito.ts new file mode 100644 index 0000000..25acda5 --- /dev/null +++ b/src/escenas/ChuyHaciendoJueguito.ts @@ -0,0 +1,89 @@ +/// +/// +/// + +class ChuyHaciendoJueguito extends EscenaActividad { + automata; + pulpito; + fondo; + cuadricula; + + iniciar() { + this.fondo = new Fondo('fondo.chuy.png',0,0); + this.colocarCuadricula() + this.construirObjeto(); + this.construirAutomata(); + this.construirFSM(); + } + + colocarCuadricula(){ + this.cuadricula = new Cuadricula(0, 0, 1, 1, + { alto: 100, ancho: 400 }, + { grilla: 'invisible.png', cantColumnas: 1 }); + } + + construirAutomata() { + this.automata = new Chuy(); + this.automata.escala *= 1.2; + this.cuadricula.agregarActor(this.automata, 0, 0, false); + this.automata.x -= 50; + } + + construirObjeto() { + this.pulpito = new Pulpito(); + this.pulpito.y = -120; + this.pulpito.escala *= 0.2; + this.pulpito.aprender(Flotar, {Desvio: 4}); + this.cuadricula.agregarActor(this.pulpito, 0, 0, false); + } + + private construirFSM(){ + var builder= new BuilderStatePattern(this, 'inicial',false); + builder.agregarEstado('posCorrecta',false); + builder.agregarEstado('calentar1',false); + builder.agregarEstado('calentar2',false); + builder.agregarEstado('enCalor',false); + builder.agregarEstado('levantarPelota',false); + builder.agregarEstado('tirarAlAire',false); + builder.agregarEstado('jugarConElPie',false); + builder.agregarEstado('resuelto',false); + builder.agregarEstado('noResuelve',false); + builder.agregarEstadoAceptacion('fin'); + + builder.agregarTransicion('inicial', 'posCorrecta', 'avanzar'); + builder.agregarTransicion('posCorrecta','calentar1','retroceder'); + builder.agregarTransicion('posCorrecta','calentar2','avanzar'); + builder.agregarTransicion('calentar1','enCalor','avanzar'); + builder.agregarTransicion('calentar2','enCalor','retroceder'); + builder.agregarTransicion('enCalor','levantarPelota','recoger'); + builder.agregarTransicion('levantarPelota','tirarAlAire','revolearPulpito'); + builder.agregarTransicion('levantarPelota','jugarConElPie','rebotarPiePulpito'); + builder.agregarTransicion('tirarAlAire','resuelto','rebotarPiePulpito'); + builder.agregarTransicion('jugarConElPie','resuelto','revolearPulpito'); + builder.agregarTransicion('resuelto','fin','retroceder'); + + builder.agregarError('inicial', 'recoger', 'Primero hay que entrar en calor'); + builder.agregarError('inicial', 'revolearPulpito', 'Primero hay que entrar en calor y agarrar la pelota'); + builder.agregarError('inicial', 'rebotarPiePulpito', 'Primero hay que entrar en calor y agarrar la pelota'); + builder.agregarError('inicial', 'retroceder', 'Primero hay que avanzar y entrar en calor'); + + builder.agregarError('posCorrecta', 'recoger', 'Primero hay que entrar en calor'); + builder.agregarError('posCorrecta', 'revolearPulpito', 'Primero hay que entrar en calor y agarrar la pelota'); + builder.agregarError('posCorrecta', 'rebotarPiePulpito', 'Primero hay que entrar en calor y agarrar la pelota'); + + builder.agregarError('calentar1', 'revolearPulpito', 'Primero hay que entrar en calor y agarrar la pelota'); + builder.agregarError('calentar1', 'rebotarPiePulpito', 'Primero hay que entrar en calor y agarrar la pelota'); + builder.agregarError('calentar1', 'retroceder', 'Primero hay que avanzar, entrar en calor y agarrar la pelota'); + + builder.agregarError('calentar2', 'revolearPulpito', 'Primero hay que entrar en calor y agarrar la pelota'); + builder.agregarError('calentar2', 'rebotarPiePulpito', 'Primero hay que entrar en calor y agarrar la pelota'); + + builder.agregarError('enCalor', 'revolearPulpito', 'Primero hay que agarrar la pelota'); + builder.agregarError('enCalor', 'rebotarPiePulpito', 'Primero hay que agarrar la pelota'); + builder.agregarError('enCalor', 'retroceder', 'Primero hay que agarrar la pelota'); + + builder.agregarError('levantarPelota', 'retroceder', 'Primero hay que jugar con la pelota'); + + this.estado = builder.estadoInicial(); + } +} diff --git a/src/escenas/EscenaActividad.ts b/src/escenas/EscenaActividad.ts index fd9c9a5..cf48f84 100644 --- a/src/escenas/EscenaActividad.ts +++ b/src/escenas/EscenaActividad.ts @@ -13,6 +13,8 @@ class EscenaActividad extends Base { automata : ActorAnimado; cuadricula : Cuadricula; fondo; + xFinal: number; + yFinal: number; /** * Devuelve todos los nombres de archivo de imagen necesarios para @@ -99,6 +101,18 @@ class EscenaActividad extends Base { return this.obtenerActoresConEtiqueta(actor).every(o => o.nombreAnimacionActual() == estado); } + estaEnPosicionFinalSiLaTiene(): boolean { + return !this.tienePosicionFinal() || this.automataEnPosicionFinal() + } + + tienePosicionFinal(): boolean { + return this.xFinal !== undefined + } + + automataEnPosicionFinal(): boolean { + return this.automata.casillaActual().sos(this.yFinal, this.xFinal); + } + /** * Computa un multiplicador que crece según la cantidad de filas y columnas de la cuadrícula. * El multiplicador es 1 si la cuadrícula es de 1x1, y crece acotado por maxRatio. diff --git a/src/escenas/NoMeCansoDeRebotar.ts b/src/escenas/NoMeCansoDeRebotar.ts new file mode 100644 index 0000000..eefff90 --- /dev/null +++ b/src/escenas/NoMeCansoDeRebotar.ts @@ -0,0 +1,78 @@ +/// +/// +/// +/// +/// + + +/** + * @class NoMeCansoDeRebotar + * + * Objetivos: Introducir Repetición + * Enunciado: Repetir reboteso. + */ + class NoMeCansoDeRebotar extends EscenaActividad { + automata + paleta + pingpong + fondo + rebotesFaltantes + cuadricula; + + iniciar() { + this.fondo = new Fondo('fondo.chuy.png',0,0); + this.colocarCuadricula() + this.construirObjetos(); + this.construirAutomata(); + this.rebotesFaltantes=30; + this.automata.decir(" Tengo que hacer " + this.rebotesFaltantes + " rebotes!"); + } + + colocarCuadricula(){ + this.cuadricula = new Cuadricula(70, 0, 1, 1, + { alto: 100, ancho: 300 }, + { grilla: 'invisible.png', cantColumnas: 1 }); + } + + construirAutomata() { + this.automata = new Chuy(); + this.automata.escala *= 1.2; + this.cuadricula.agregarActor(this.automata, 0, 0, false); + this.automata.x -= 20; + } + + construirObjetos() { + this.paleta = new Paleta(); + this.paleta.y = -120; + this.paleta.escala *= 0.2; + this.paleta.aprender(Flotar, {Desvio: 4}); + this.cuadricula.agregarActor(this.paleta, 0, 0, false); + this.pingpong = new PingPong(); + this.pingpong.y = -160; + this.pingpong.escala *= 0.2; + this.pingpong.aprender(Flotar, {Desvio: 4}); + this.cuadricula.agregarActor(this.pingpong, 0, 0, false); + } + + antesDeRebotar(){ + //oculto los objetos + this.pingpong.escala = 0; + this.paleta.escala = 0; + } + + getFraseAlRebotar(): string { + if (this.rebotesFaltantes > 0) return " Faltan " + this.rebotesFaltantes + " rebotes"; + if (this.rebotesFaltantes == 0) return " ¡Ya hice los rebotes necesarios!"; + throw new ActividadError(" ¡Uy! Hice muchos rebotes... ¡Me pasé!"); + } + + fraseAlRebotar(){ + this.rebotesFaltantes--; + return this.getFraseAlRebotar(); + } + + estaResueltoElProblema() { + return this.rebotesFaltantes == 0; + } + +} diff --git a/src/escenas/SuperMaraton.ts b/src/escenas/SuperMaraton.ts new file mode 100644 index 0000000..90b59bb --- /dev/null +++ b/src/escenas/SuperMaraton.ts @@ -0,0 +1,49 @@ +/// +/// +/// +/// + + +/** + * @class SuperMaraton + * + */ +class SuperMaraton extends EscenaActividad { + fondo; + automata; + + iniciar() { + this.fondo = new FondoAnimado('fondo.superMaraton.png', pilas.derecha(), 0); + this.automata = new Chuy(); + this.automata.y = -70; + + this.automata.totalKM = 15 + Math.round(Math.random() * 30); + this.automata.restantesKM = this.automata.totalKM; + + this.automata.kmsTotales = function(){ + return this.totalKM + }; + + this.crearTablero(); + + this.automata.fraseAlCorrer = function() { + this.restantesKM--; + if (this.restantesKM == 0) return "¡Llegué!"; + if (this.restantesKM == 1) return "¡Falta 1 kilometro!"; + if (this.restantesKM < 0) throw new ActividadError("Ya llegué, ¡no debo seguir corriendo!"); + + return "¡Faltan " + this.restantesKM + " kilometros!"; + } + } + + crearTablero(){ + Trait.toObject(Observado, this.automata); + var tablero = new Tablero(0, 210, { texto: "Kilómetros a recorrer" , atributoObservado: 'kmsTotales'}); + this.automata.registrarObservador(tablero); + } + + estaResueltoElProblema(){ + return this.automata.restantesKM === 0; + } + +} diff --git a/src/escenas/libroPrimaria/CustomScene.ts b/src/escenas/libroPrimaria/CustomScene.ts index 2dd3113..97b78f8 100644 --- a/src/escenas/libroPrimaria/CustomScene.ts +++ b/src/escenas/libroPrimaria/CustomScene.ts @@ -49,6 +49,10 @@ class CustomScene extends EscenaDesdeMapa { this.initDesdeUnaOVariasDescripciones(options.grid.spec, options.grid.specOptions); } + static nombreAutomata(): string { + return 'custom' + } + obtenerAutomata(): ActorAnimado { return this.automata } diff --git a/src/escenas/libroPrimaria/EscenaCapy.ts b/src/escenas/libroPrimaria/EscenaCapy.ts index 10b4e54..34c063e 100644 --- a/src/escenas/libroPrimaria/EscenaCapy.ts +++ b/src/escenas/libroPrimaria/EscenaCapy.ts @@ -12,13 +12,13 @@ class EscenaCapy extends EscenaDesdeMapa { return 'fondo.capy.png'; } - static imagenesAdicionales(): string[] { - return Casilla.imagenesPara('capy').concat(Obstaculo.imagenesPara('capy')); + static nombreAutomata(): string { + return 'capy' } - constructor(especificacion: Spec, opciones?: opcionesMapaAleatorio) { + constructor(especificacion: Spec, opciones?: opcionesMapaAleatorio, posFinal?: [number, number]) { super(); - this.initDesdeUnaOVariasDescripciones(especificacion, opciones); + this.initDesdeUnaOVariasDescripciones(especificacion, opciones, posFinal); } ajustarGraficos() { @@ -57,10 +57,6 @@ class EscenaCapy extends EscenaDesdeMapa { return new Obstaculo(archivosObstaculos, (fila + 1) + (fila + 1) * (columna + 1)); } - todosLosActoresCumplen(actor, estado) { - return this.obtenerActoresConEtiqueta(actor).every(o => o.nombreAnimacionActual() == estado); - } - tachosLlenos(): boolean { return this.todosLosActoresCumplen("Tacho", "lleno") } @@ -77,13 +73,8 @@ class EscenaCapy extends EscenaDesdeMapa { return this.recogidos(actor) || this.noHay(actor) } - - noHay(actor): boolean { - return this.contarActoresConEtiqueta(actor) == 0 - } - estaResueltoElProblema(): boolean { - return this.tachoResuelto() && this.recoleccionResuelta("Lata") && this.recoleccionResuelta("Papel") + return super.estaResueltoElProblema() && this.tachoResuelto() && this.recoleccionResuelta("Lata") && this.recoleccionResuelta("Papel") } archivoFondo() { diff --git a/src/escenas/libroPrimaria/EscenaChuy.ts b/src/escenas/libroPrimaria/EscenaChuy.ts index 7b956f9..75c4425 100644 --- a/src/escenas/libroPrimaria/EscenaChuy.ts +++ b/src/escenas/libroPrimaria/EscenaChuy.ts @@ -13,18 +13,13 @@ class EscenaChuy extends EscenaDesdeMapa { return 'fondo.chuy.png'; } - static imagenesAdicionales(): string[] { - return Casilla.imagenesPara('chuy').concat(Obstaculo.imagenesPara('chuy')); + static nombreAutomata(): string { + return 'chuy' } constructor(especificacion: Spec, opciones?: opcionesMapaAleatorio, posFinal?: [number, number]) { super(); - this.initDesdeUnaOVariasDescripciones(especificacion, opciones); - - if (posFinal) { - this.xFinal = posFinal[0]; - this.yFinal = posFinal[1]; - } + this.initDesdeUnaOVariasDescripciones(especificacion, opciones, posFinal); } ajustarGraficos() { @@ -44,7 +39,7 @@ class EscenaChuy extends EscenaDesdeMapa { this.obtenerActoresConEtiqueta("PelotaAnimada").forEach(actor => { actor.aprender(Flotar, { Desvio: 4 }); - actor.escala *= this.escalaSegunCuadricula(0.5); + actor.escala *= this.escalaSegunCuadricula(0.1); }); this.obtenerActoresConEtiqueta("PingPong").forEach(actor => { @@ -83,7 +78,7 @@ class EscenaChuy extends EscenaDesdeMapa { } estaEnPosicionFinalSiLaTiene(): boolean { - return this.xFinal === undefined || this.automata.casillaActual().sos(this.yFinal, this.xFinal) || this.automata.alFinalDelCamino(); + return super.estaEnPosicionFinalSiLaTiene() || this.automata.alFinalDelCamino(); } noHayPelotas(): boolean { diff --git a/src/escenas/libroPrimaria/EscenaDesdeMapa.ts b/src/escenas/libroPrimaria/EscenaDesdeMapa.ts index ae58749..4cfaf36 100644 --- a/src/escenas/libroPrimaria/EscenaDesdeMapa.ts +++ b/src/escenas/libroPrimaria/EscenaDesdeMapa.ts @@ -6,13 +6,13 @@ /// type MapaEscena = Array>; -declare var grammar : nearley.CompiledRules; // Header para la gramática, que se toma desde ../../../parserAleatorio/gramticaAleatoria.js +declare var grammar: nearley.CompiledRules; // Header para la gramática, que se toma desde ../../../parserAleatorio/gramticaAleatoria.js -type GridSpec = { +type GridSpec = { spec: Spec, specOptions?: opcionesMapaAleatorio - } - +} + type Spec = string | string[] /** @@ -29,47 +29,71 @@ type Spec = string | string[] */ abstract class EscenaDesdeMapa extends EscenaActividad { - mapaEscena : MapaEscena; - generadorDeMapas : GeneradorDeMapas; + mapaEscena: MapaEscena; + generadorDeMapas: GeneradorDeMapas; /** * @param generadorDeMapas El generador que se utilizará para obtener mapas para la actividad. */ - constructor(generadorDeMapas? : GeneradorDeMapas) { + constructor(generadorDeMapas?: GeneradorDeMapas) { super(); this.generadorDeMapas = generadorDeMapas; } - initDesdeMapa(mapa : MapaEscena) { + static imagenesAdicionales(): string[] { + return [Casilla, Obstaculo, MetaFinal].map(clase => clase.imagenesPara(this.nombreAutomata())).reduce((acc, list) => list.concat(acc), []); + } + + /** + * Devuelve el nombre del automata, usado para la precarga de metas finales, obstaculos y casillas + * Pensado para redefinirse por escena. + */ + static nombreAutomata() { + return '' + } + + initDesdeMapa(mapa: MapaEscena) { this.generadorDeMapas = new GeneradorDeMapasSimple(mapa); } - initDesdeArrayDeMapas(mapas : Array) { - var generadores : Array + initDesdeArrayDeMapas(mapas: Array) { + var generadores: Array = mapas.map(m => new GeneradorDeMapasSimple(m)); this.generadorDeMapas = new GeneradorDeMapasArray(generadores); } - initDesdeDescripcion(descripcion : string, opciones?: opcionesMapaAleatorio) { + initDesdeDescripcion(descripcion: string, opciones?: opcionesMapaAleatorio) { this.generadorDeMapas = new GeneradorDeMapasAleatorios(descripcion, opciones); } - initDesdeArrayDeDescripciones(descripciones : Array, opciones?: opcionesMapaAleatorio) { + initDesdeArrayDeDescripciones(descripciones: Array, opciones?: opcionesMapaAleatorio) { var generadores: Array = descripciones.map(d => new GeneradorDeMapasAleatorios(d, opciones)); this.generadorDeMapas = new GeneradorDeMapasArray(generadores); } - initDesdeUnaOVariasDescripciones(especificacion: Spec, opciones?: opcionesMapaAleatorio) { //Podria recibir un GridSpec directamente + initDesdeUnaOVariasDescripciones(especificacion: Spec, opciones?: opcionesMapaAleatorio, posFinal?: [number, number]) { //Podria recibir un GridSpec directamente + this.guardarPosicionFinal(posFinal) if (Array.isArray(especificacion)) this.initDesdeArrayDeDescripciones(especificacion, opciones); else this.initDesdeDescripcion(especificacion, opciones); } - iniciar() : void { + guardarPosicionFinal(posFinal?: [number, number]){ + if (posFinal && this.posicionValida(posFinal)) { + this.xFinal = posFinal[0]; + this.yFinal = posFinal[1]; + } + } + + posicionValida(posFinal: [number, number]){ + return posFinal[0] >= 0 && posFinal[1] >= 0 + } + + iniciar(): void { this.fondo = new Fondo(this.archivoFondo(), 0, 0); - + this.automata = this.obtenerAutomata(); if (this.generadorDeMapas) { @@ -80,21 +104,40 @@ abstract class EscenaDesdeMapa extends EscenaActividad { this.cuadricula = this.construirCuadricula(this.mapaEscena); + this.agregarCasillaFinalSiLaTiene(); this.automata.enviarAlFrente(); this.ajustarGraficos(); } - protected construirCuadricula(mapa : MapaEscena) : Cuadricula { + protected construirCuadricula(mapa: MapaEscena): Cuadricula { const matrizBooleana = mapa.map(fila => fila.map(casilla => casilla === '_' ? 'F' : 'T')) const cuadricula: CuadriculaEsparsa = new CuadriculaEsparsa(this.cuadriculaX(), this.cuadriculaY(), this.opsCuadricula(), this.opsCasilla(), matrizBooleana); cuadricula.forEachCasilla(casilla => this.llenarCasilla(cuadricula, casilla, mapa)); return cuadricula; } - llenarCasilla(cuadricula : Cuadricula, casilla : Casilla, mapa : MapaEscena) : void { - let nroFila : number = casilla.nroFila; - let nroColumna : number = casilla.nroColumna; - let ids : string[] = mapa[nroFila][nroColumna].split("&"); + casillaFinal(): Casilla { + return this.cuadricula.casilla(this.yFinal, this.xFinal) + } + + agregarCasillaFinalSiLaTiene(): void { + if (this.tienePosicionFinal()) { + const actor = new MetaFinal((this.constructor as typeof EscenaDesdeMapa).nombreAutomata()) + this.cuadricula.agregarActorEnCasilla(actor, this.casillaFinal(), true) + this.ajustarMeta(actor) + } + } + + ajustarMeta(meta){ + meta.escala *= this.escalaSegunCuadricula(0.7); + meta.ajustarSegunCuadricula(this.cuadricula.getOpcionesCasilla().alto) + if(this.casillaFinal().tieneMasDeUnActor()) meta.enviarAtras() //en el caso de que haya un premio, debe ir atrás de este + } + + llenarCasilla(cuadricula: Cuadricula, casilla: Casilla, mapa: MapaEscena): void { + let nroFila: number = casilla.nroFila; + let nroColumna: number = casilla.nroColumna; + let ids: string[] = mapa[nroFila][nroColumna].split("&"); ids.forEach(id => { if (id != '' && id != ' ' && id != '-' && id != '_') { // si no es casilla libre let actor = this.mapearIdentificadorAActor(id, nroFila, nroColumna); @@ -103,17 +146,21 @@ abstract class EscenaDesdeMapa extends EscenaActividad { }) } + estaResueltoElProblema(): Boolean { + return this.estaEnPosicionFinalSiLaTiene() + } + /** * Indica si el mapa es distinto cada vez que se ejecuta la escena. */ - tieneAleatoriedad() : boolean { + tieneAleatoriedad(): boolean { return this.generadorDeMapas.tieneAleatoriedad(); } /** * Crea y devuelve el autómata de la actividad. */ - abstract obtenerAutomata() : ActorAnimado; + abstract obtenerAutomata(): ActorAnimado; /** * Recibe un identificador y crea y devuelve el actor que le corresponde. @@ -122,29 +169,29 @@ abstract class EscenaDesdeMapa extends EscenaActividad { * de la casilla donde se colocará el actor. */ abstract mapearIdentificadorAActor( - id : string, - nroFila : number, + id: string, + nroFila: number, nroColumna: number - ) : ActorAnimado; + ): ActorAnimado; /** * Se puede sobreescribir esta función para definir acciones que se realizarán * justo después de iniciar la escena para mejorar su aspecto visual. Por ejemplo, * ajustar la escala o la posición de los actores. Por defecto, no hace nada. */ - ajustarGraficos() : void {}; - + ajustarGraficos(): void { }; + /** Devuelve el path del archivo que se usará como fondo de la escena. */ - abstract archivoFondo() : string; + abstract archivoFondo(): string; /** Devuelve la posición en el eje X de la cuadrícula. Se puede sobreescribir. */ cuadriculaX(): number { return 0; } /** Devuelve la posición en el eje X de la cuadrícula. Se puede sobreescribir. */ - cuadriculaY() : number { return 0; } + cuadriculaY(): number { return 0; } /** Devuelve las opciones que se usarán para crear la cuadrícula. Se puede sobreescribir. */ - opsCuadricula() : any { return {}; } + opsCuadricula(): any { return {}; } /** Devuelve las opciones que se usarán para crear la casilla. Se puede sobreescribir. */ opsCasilla(): any { return { grilla: 'invisible.png' }; } @@ -155,16 +202,16 @@ abstract class EscenaDesdeMapa extends EscenaActividad { */ interface GeneradorDeMapas { /** Genera un mapa de escena. */ - obtenerMapa() : MapaEscena; + obtenerMapa(): MapaEscena; /** Indica si los mapas generados varían con cada ejecución. */ - tieneAleatoriedad() : boolean; + tieneAleatoriedad(): boolean; } /** * Este generador se inicializa con un mapa y devuelve siempre dicho mapa. */ class GeneradorDeMapasSimple implements GeneradorDeMapas { - constructor(private mapa : MapaEscena) {} + constructor(private mapa: MapaEscena) { } obtenerMapa() { return this.mapa; } tieneAleatoriedad() { return false; } } @@ -174,7 +221,7 @@ class GeneradorDeMapasSimple implements GeneradorDeMapas { * Cada vez que se le pide un mapa, elige uno de ellos al azar. */ class GeneradorDeMapasArray implements GeneradorDeMapas { - constructor(private generadores : Array) {} + constructor(private generadores: Array) { } obtenerMapa() { return Math.randomFrom(this.generadores).obtenerMapa(); } tieneAleatoriedad() { return this.generadores.length > 1 || this.generadores[0].tieneAleatoriedad(); } } @@ -210,18 +257,18 @@ class GeneradorDeMapasArray implements GeneradorDeMapas { * string indicada en la opción `macros`. */ class GeneradorDeMapasAleatorios implements GeneradorDeMapas { - generadoresDeSemillas : Array>; - _probaPorDefecto : number; - bolsa : Array; - bolsas: { [id : string] : Array }; - coleccion : Array; - colecciones: { [id : string] : Array }; - macros : { [id : string] : string }; + generadoresDeSemillas: Array>; + _probaPorDefecto: number; + bolsa: Array; + bolsas: { [id: string]: Array }; + coleccion: Array; + colecciones: { [id: string]: Array }; + macros: { [id: string]: string }; // Se usan durante la generación de un mapa - _anotadosParaColeccion : Array; + _anotadosParaColeccion: Array; _anotadosParaColecciones: { [id: string]: Array }; - _semillasEncoladas: Array<{ pos: [number, number], semilla : SemillaDeCasilla }> = []; + _semillasEncoladas: Array<{ pos: [number, number], semilla: SemillaDeCasilla }> = []; _posActual: [number, number] = [0, 0]; /** @@ -233,12 +280,12 @@ class GeneradorDeMapasAleatorios implements GeneradorDeMapas { * - `coleccion`: La colección de elementos para las casillas señaladas con `*`. * - `colecciones`: Diccionario de colecciones para utilizar `$` con identificadores. */ - constructor(descripcionDeMapa : string, opciones : opcionesMapaAleatorio = {}) { + constructor(descripcionDeMapa: string, opciones: opcionesMapaAleatorio = {}) { this.configurar(opciones); this.generadoresDeSemillas = GeneradorDeMapasAleatorios.parsear(descripcionDeMapa); } - private configurar(opciones : opcionesMapaAleatorio) { + private configurar(opciones: opcionesMapaAleatorio) { this._probaPorDefecto = opciones.probaPorDefecto || 0.5; this.bolsa = opciones.bolsa || []; this.bolsas = opciones.bolsas || {}; @@ -254,13 +301,13 @@ class GeneradorDeMapasAleatorios implements GeneradorDeMapas { obtenerMapa() { // Primera pasada - var semillas : Array> = + var semillas: Array> = this.generadoresDeSemillas.map(fila => fila.map( semilla => semilla.generarSemillaDeCasilla(this) )); this.repartirElementosDeColecciones(); // Segunda pasada - var mapa : MapaEscena = semillas.map((fila, i) => fila.map( + var mapa: MapaEscena = semillas.map((fila, i) => fila.map( (semilla, j) => semilla.germinar(this, [i, j]) )); // Pasadas adicionales @@ -279,45 +326,45 @@ class GeneradorDeMapasAleatorios implements GeneradorDeMapas { } /** Se utiliza durante la obtención del mapa, para realizar pasadas extra */ - encolarSemilla(pos: [number, number], semilla : SemillaDeCasilla) { + encolarSemilla(pos: [number, number], semilla: SemillaDeCasilla) { this._semillasEncoladas.push({ pos: pos, semilla: semilla }); } - tieneAleatoriedad() : boolean { + tieneAleatoriedad(): boolean { return this.generadoresDeSemillas.some(fila => fila.some( semilla => semilla.esAleatorioPara(this) )); } - probaPorDefecto() : number { + probaPorDefecto(): number { return this._probaPorDefecto; } - - dameUnoDeLaBolsa(idBolsa? : string) : string { - var bolsa : Array = idBolsa ? this.bolsas[idBolsa] : this.bolsa; + + dameUnoDeLaBolsa(idBolsa?: string): string { + var bolsa: Array = idBolsa ? this.bolsas[idBolsa] : this.bolsa; return Math.randomFrom(bolsa); } - anotarParaLaColeccion(semilla : SemillaDeCasilla, idColeccion? : string) : void { - var dondeAnotar : Array = idColeccion ? + anotarParaLaColeccion(semilla: SemillaDeCasilla, idColeccion?: string): void { + var dondeAnotar: Array = idColeccion ? this._anotadosParaColecciones[idColeccion] : this._anotadosParaColeccion; dondeAnotar.push(semilla); } - private repartirElementosDeColecciones() : void { + private repartirElementosDeColecciones(): void { this.repartirElementos(this.coleccion, this._anotadosParaColeccion); for (const id in this.colecciones) { this.repartirElementos(this.colecciones[id], this._anotadosParaColecciones[id]); } } - private repartirElementos(coleccion : Array, semillas : Array) { + private repartirElementos(coleccion: Array, semillas: Array) { coleccion.forEach(elemento => { if (semillas.length > 0) Math.takeRandomFrom(semillas).definir(elemento); }); } - + private vaciarAnotadosParaColecciones() { this._anotadosParaColeccion.splice(0); for (const id in this._anotadosParaColecciones) { @@ -325,7 +372,7 @@ class GeneradorDeMapasAleatorios implements GeneradorDeMapas { } } - obtenerGeneradorParaMacro(idMacro : string) { + obtenerGeneradorParaMacro(idMacro: string) { return GeneradorDeMapasAleatorios.parsear(this.macros[idMacro]); } @@ -343,7 +390,7 @@ type opcionesMapaAleatorio = { bolsas?: { [id: string]: Array }, coleccion?: Array, colecciones?: { [id: string]: Array }, - macros?: { [id : string] : string }, + macros?: { [id: string]: string }, } /** @@ -357,12 +404,12 @@ interface GeneradorDeCasilla { * Las semillas son necesarias como paso intermedio porque a veces el contenido definitivo * de una casilla no puede determinarse hasta que se haya construido todo el mapa. */ - generarSemillaDeCasilla(generador : GeneradorDeMapasAleatorios) : SemillaDeCasilla; + generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla; /** * Indica si este generador produce resultados aleatorios al ser utilizado * con un generador de mapas en particular. */ - esAleatorioPara(generador : GeneradorDeMapasAleatorios) : boolean; + esAleatorioPara(generador: GeneradorDeMapasAleatorios): boolean; } /** @@ -370,18 +417,18 @@ interface GeneradorDeCasilla { * de un mapa. Se utiliza durante el proceso de generación de un mapa aleatorio. */ class SemillaDeCasilla { - contenido : string; - generadoresExtra : Array = []; - constructor(contenido? : string) { this.definir(contenido); } - definir(contenido? : string) { this.contenido = contenido || "-"; } - encolarGeneradoresExtra(generadores : Array) { + contenido: string; + generadoresExtra: Array = []; + constructor(contenido?: string) { this.definir(contenido); } + definir(contenido?: string) { this.contenido = contenido || "-"; } + encolarGeneradoresExtra(generadores: Array) { this.generadoresExtra = this.generadoresExtra.concat(generadores); return this; } - seraVacia() : boolean { return this.contenido == "-"; } - germinar(generador : GeneradorDeMapasAleatorios, pos : [number, number]) : string { + seraVacia(): boolean { return this.contenido == "-"; } + germinar(generador: GeneradorDeMapasAleatorios, pos: [number, number]): string { if (this.seraVacia() && this.generadoresExtra.length > 0) { - var semillaSiguiente : SemillaDeCasilla + var semillaSiguiente: SemillaDeCasilla = (this.generadoresExtra.splice(0, 1)[0].generarSemillaDeCasilla(generador)); semillaSiguiente.encolarGeneradoresExtra(this.generadoresExtra); generador.encolarSemilla(pos, semillaSiguiente); @@ -403,22 +450,21 @@ class SemillaCompuesta extends SemillaDeCasilla { } public germinar(generador: GeneradorDeMapasAleatorios, pos: [number, number]): string { - return this.semillas.map(semilla => semilla.germinar(generador,pos)).join("&") + return this.semillas.map(semilla => semilla.germinar(generador, pos)).join("&") } } /** Corresponde a identificadores de la forma `[a-zA-Z0-9]+`. */ class GeneradorDeCasillaSimple implements GeneradorDeCasilla { - constructor(private id : string) {} - generarSemillaDeCasilla(generador : GeneradorDeMapasAleatorios) : SemillaDeCasilla - { return new SemillaDeCasilla(this.id); } - esAleatorioPara(generador : GeneradorDeMapasAleatorios) : boolean { return false; } + constructor(private id: string) { } + generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { return new SemillaDeCasilla(this.id); } + esAleatorioPara(generador: GeneradorDeMapasAleatorios): boolean { return false; } } /** Corresponde a las casillas indicadas con `$` y `$(id)`. */ class GeneradorDeCasillaBolsa implements GeneradorDeCasilla { - constructor(private idBolsa? : string) {} - generarSemillaDeCasilla(generador : GeneradorDeMapasAleatorios) : SemillaDeCasilla { + constructor(private idBolsa?: string) { } + generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { return new SemillaDeCasilla(generador.dameUnoDeLaBolsa(this.idBolsa)); } // Por simplicidad se devuelve siempre true, aunque en rigor puede no ser correcto. @@ -429,35 +475,33 @@ class GeneradorDeCasillaBolsa implements GeneradorDeCasilla { /** Corresponde a las casillas indicadas con `*` y `*(id)`. */ class GeneradorDeCasillaColeccion implements GeneradorDeCasilla { - constructor(private idColeccion?: string) {} - generarSemillaDeCasilla(generador : GeneradorDeMapasAleatorios) : SemillaDeCasilla { - var semilla : SemillaDeCasilla = new SemillaDeCasilla(); + constructor(private idColeccion?: string) { } + generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { + var semilla: SemillaDeCasilla = new SemillaDeCasilla(); generador.anotarParaLaColeccion(semilla, this.idColeccion); return semilla; } // Por simplicidad. Ver GeneradorDeCasillaBolsa.esAleatorioPara. - esAleatorioPara(generador : GeneradorDeMapasAleatorios) { return true; } + esAleatorioPara(generador: GeneradorDeMapasAleatorios) { return true; } } /** Corresponde a las casillas indicadas con `-`. */ class GeneradorDeCasillaVacia implements GeneradorDeCasilla { - generarSemillaDeCasilla(generador : GeneradorDeMapasAleatorios) : SemillaDeCasilla - { return new SemillaDeCasilla('-'); } - esAleatorioPara(generador : GeneradorDeMapasAleatorios): boolean { return false; } + generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { return new SemillaDeCasilla('-'); } + esAleatorioPara(generador: GeneradorDeMapasAleatorios): boolean { return false; } } /** Corresponde a las casillas indicadas con `_`. */ class GeneradorDeCasillaNula implements GeneradorDeCasilla { - generarSemillaDeCasilla(generador : GeneradorDeMapasAleatorios) : SemillaDeCasilla - { return new SemillaDeCasilla('_'); } - esAleatorioPara(generador : GeneradorDeMapasAleatorios): boolean { return false; } + generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { return new SemillaDeCasilla('_'); } + esAleatorioPara(generador: GeneradorDeMapasAleatorios): boolean { return false; } } /** Corresponde al modificador `?` (recursivo). */ class GeneradorDeCasillaMaybe implements GeneradorDeCasilla { - constructor(private generadorInterno : GeneradorDeCasilla, private proba? : number) {} - generarSemillaDeCasilla(generador : GeneradorDeMapasAleatorios) : SemillaDeCasilla { - var proba : number = this.proba || generador.probaPorDefecto(); + constructor(private generadorInterno: GeneradorDeCasilla, private proba?: number) { } + generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { + var proba: number = this.proba || generador.probaPorDefecto(); if (Math.random() < proba) return this.generadorInterno.generarSemillaDeCasilla(generador); else @@ -465,13 +509,13 @@ class GeneradorDeCasillaMaybe implements GeneradorDeCasilla { } esAleatorioPara(generador): boolean { var proba: number = this.proba || generador.probaPorDefecto(); - return 0 < proba && proba < 1; + return 0 < proba && proba < 1; } } class GeneradorDeCasillaAnd implements GeneradorDeCasilla { - constructor(private generador1 : GeneradorDeCasilla, private generador2: GeneradorDeCasilla) {} + constructor(private generador1: GeneradorDeCasilla, private generador2: GeneradorDeCasilla) { } - generarSemillaDeCasilla(generador : GeneradorDeMapasAleatorios) : SemillaDeCasilla { + generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { const semilla1: SemillaDeCasilla = this.generador1.generarSemillaDeCasilla(generador) const semilla2: SemillaDeCasilla = this.generador2.generarSemillaDeCasilla(generador) return new SemillaCompuesta([semilla1, semilla2]) @@ -484,19 +528,19 @@ class GeneradorDeCasillaAnd implements GeneradorDeCasilla { /** Corresponde al modificador `|` (recursivo). */ class GeneradorDeCasillaOpcion implements GeneradorDeCasilla { - constructor(private opciones : Array) {} - generarSemillaDeCasilla(generador : GeneradorDeMapasAleatorios) : SemillaDeCasilla { + constructor(private opciones: Array) { } + generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { return Math.randomFrom(this.opciones) .generarSemillaDeCasilla(generador); } - esAleatorioPara(generador : GeneradorDeMapasAleatorios) { + esAleatorioPara(generador: GeneradorDeMapasAleatorios) { return this.opciones.length > 1; } } /** Corresponde al modificador `>` (recursivo). */ class GeneradorDeCasillaSucesion implements GeneradorDeCasilla { - constructor(private opciones: Array) {} + constructor(private opciones: Array) { } generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { return this.opciones[0].generarSemillaDeCasilla(generador) .encolarGeneradoresExtra(this.opciones.splice(1)); @@ -507,11 +551,11 @@ class GeneradorDeCasillaSucesion implements GeneradorDeCasilla { } class GeneradorDeCasillaMacro implements GeneradorDeCasilla { - constructor(private id : string) {} + constructor(private id: string) { } generarSemillaDeCasilla(generador: GeneradorDeMapasAleatorios): SemillaDeCasilla { return generador.obtenerGeneradorParaMacro(this.id).generarSemillaDeCasilla(generador); } - esAleatorioPara(generador : GeneradorDeMapasAleatorios) { + esAleatorioPara(generador: GeneradorDeMapasAleatorios) { return generador.obtenerGeneradorParaMacro(this.id).esAleatorioPara(generador); } } diff --git a/src/escenas/libroPrimaria/EscenaDuba.ts b/src/escenas/libroPrimaria/EscenaDuba.ts index 9472c4e..cb12b73 100644 --- a/src/escenas/libroPrimaria/EscenaDuba.ts +++ b/src/escenas/libroPrimaria/EscenaDuba.ts @@ -17,18 +17,13 @@ class EscenaDuba extends EscenaDesdeMapa { return 'fondo.duba.png'; } - static imagenesAdicionales(): string[] { - return Casilla.imagenesPara('duba').concat(Obstaculo.imagenesPara('duba')); - } //TODO: Usar flatMap (lodash) + static nombreAutomata(): string { + return 'duba' + } constructor(especificacion: Spec, opciones?: opcionesMapaAleatorio, posFinal?: [number, number]) { super(); - this.initDesdeUnaOVariasDescripciones(especificacion, opciones); - - if (posFinal) { - this.xFinal = posFinal[0]; - this.yFinal = posFinal[1]; - } + this.initDesdeUnaOVariasDescripciones(especificacion, opciones, posFinal); } ajustarGraficos() { @@ -65,8 +60,7 @@ class EscenaDuba extends EscenaDesdeMapa { } estaResueltoElProblema(): boolean { - return (this.contarActoresConEtiqueta("Churrasco")) === 0 && - (this.xFinal === undefined || this.automata.casillaActual().sos(this.xFinal, this.yFinal)); + return super.estaResueltoElProblema() && this.noHay('Churrasco') } archivoFondo() { diff --git a/src/escenas/libroPrimaria/EscenaLita.ts b/src/escenas/libroPrimaria/EscenaLita.ts index a0ffa14..356a38f 100644 --- a/src/escenas/libroPrimaria/EscenaLita.ts +++ b/src/escenas/libroPrimaria/EscenaLita.ts @@ -17,18 +17,13 @@ class EscenaLita extends EscenaDesdeMapa { return 'fondo.lita.png'; } - static imagenesAdicionales(): string[] { - return Casilla.imagenesPara('lita').concat(Obstaculo.imagenesPara('lita')); - } //TODO: Usar flatMap (lodash) + static nombreAutomata(): string { + return 'lita' + } constructor(especificacion: Spec, opciones?: opcionesMapaAleatorio, posFinal?: [number, number]) { super(); - this.initDesdeUnaOVariasDescripciones(especificacion, opciones); - - if (posFinal) { - this.xFinal = posFinal[0]; - this.yFinal = posFinal[1]; - } + this.initDesdeUnaOVariasDescripciones(especificacion, opciones, posFinal); } iniciar() { @@ -62,11 +57,7 @@ class EscenaLita extends EscenaDesdeMapa { } estaResueltoElProblema(): boolean { - // Además de verificar que Lita haya cumplido el objetivo de la escena, - // en el caso de que se haya proporcionado una posición final, - // queremos verificar que Lita esté ahí. - return super.estaResueltoElProblema() && - (this.xFinal === undefined || this.automata.casillaActual().sos(this.xFinal, this.yFinal)); + return super.estaResueltoElProblema() && this.estado.soyAceptacion() } ajustarGraficos() { diff --git a/src/escenas/libroPrimaria/EscenaManic.ts b/src/escenas/libroPrimaria/EscenaManic.ts index a70e61a..3344ff6 100644 --- a/src/escenas/libroPrimaria/EscenaManic.ts +++ b/src/escenas/libroPrimaria/EscenaManic.ts @@ -14,17 +14,13 @@ class EscenaManic extends EscenaDesdeMapa { return 'fondo.manic.png'; } - static imagenesAdicionales(): string[] { - return Casilla.imagenesPara('manic').concat(Obstaculo.imagenesPara('manic')); + static nombreAutomata(): string { + return 'manic' } constructor(especificacion: Spec, opciones?: opcionesMapaAleatorio, posFinal?: [number, number]) { super(); - this.initDesdeUnaOVariasDescripciones(especificacion, opciones); - if (posFinal) { - this.xFinal = posFinal[0]; - this.yFinal = posFinal[1]; - } + this.initDesdeUnaOVariasDescripciones(especificacion, opciones, posFinal); } ajustarGraficos() { @@ -68,10 +64,6 @@ class EscenaManic extends EscenaDesdeMapa { return new Obstaculo(archivosObstaculos, (fila + 1) + (fila + 1) * (columna + 1)); } - todosLosActoresCumplen(actor, estado) { - return this.obtenerActoresConEtiqueta(actor).every(o => o.nombreAnimacionActual() == estado); - } - telescopiosArreglados(): boolean { return this.todosLosActoresCumplen("Telescopio", "arreglado") } @@ -88,17 +80,8 @@ class EscenaManic extends EscenaDesdeMapa { return this.observados(actor) || this.noHay(actor) } - - noHay(actor): boolean { - return this.contarActoresConEtiqueta(actor) == 0 - } - - estaEnPosicionFinalSiLaTiene(): boolean { - return this.xFinal === undefined || this.automata.casillaActual().sos(this.yFinal, this.xFinal); - } - estaResueltoElProblema(): boolean { - return this.estaEnPosicionFinalSiLaTiene() && this.telescopioResuelto() && this.observacionResuelta("Estrella") && this.observacionResuelta("Planeta"); + return super.estaResueltoElProblema() && this.telescopioResuelto() && this.observacionResuelta("Estrella") && this.observacionResuelta("Planeta"); } archivoFondo() { diff --git a/src/escenas/libroPrimaria/EscenaToto.ts b/src/escenas/libroPrimaria/EscenaToto.ts index ff20a4c..7cadc74 100644 --- a/src/escenas/libroPrimaria/EscenaToto.ts +++ b/src/escenas/libroPrimaria/EscenaToto.ts @@ -33,6 +33,10 @@ abstract class EscenaToto extends EscenaDesdeMapa { return [] } + static nombreAutomata(): string { + return 'toto' + } + /** * @param mapaEscena Matriz bidimensional de strings a partir de la cual se crea la escena. * Toto se representa con una 'A' mayúscula. Las letras a leer van en minúscula diff --git a/src/escenas/libroPrimaria/EscenaYvoty.ts b/src/escenas/libroPrimaria/EscenaYvoty.ts index 9bacb12..adb7050 100644 --- a/src/escenas/libroPrimaria/EscenaYvoty.ts +++ b/src/escenas/libroPrimaria/EscenaYvoty.ts @@ -12,13 +12,13 @@ class EscenaYvoty extends EscenaDesdeMapa { return 'fondo.yvoty.png'; } - static imagenesAdicionales(): string[] { - return Casilla.imagenesPara('yvoty').concat(Obstaculo.imagenesPara('yvoty')); + static nombreAutomata(): string { + return 'yvoty' } - constructor(especificacion: Spec, opciones?: opcionesMapaAleatorio) { + constructor(especificacion: Spec, opciones?: opcionesMapaAleatorio, posFinal?: [number, number]) { super(); - this.initDesdeUnaOVariasDescripciones(especificacion, opciones); + this.initDesdeUnaOVariasDescripciones(especificacion, opciones, posFinal); } ajustarGraficos() { @@ -86,7 +86,7 @@ class EscenaYvoty extends EscenaDesdeMapa { } estaResueltoElProblema(): boolean { - return this.luciernagasDespiertas() && this.celularResuelto() && this.noHay("Mariposa") && this.computadorasPrendidas() + return super.estaResueltoElProblema() && this.luciernagasDespiertas() && this.celularResuelto() && this.noHay("Mariposa") && this.computadorasPrendidas() } archivoFondo() {