/* * Verrückte Turing-Maschinen — A turing complete game * Copyright (C) 2016 Christian Fraß * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ module mod_vtm_aufbau { /** * @author kcf */ export class klasse_partie { /** * @author kcf */ private welt : klasse_welt; /** * @author kcf */ private figur : schnittstelle_fehlermonade; /** * @author kcf */ private aufgabe : schnittstelle_aufgabe; /** * @author kcf */ private testindex : schnittstelle_fehlermonade; /** * @author kcf */ private modus : typ_modus; /** * @author kcf */ private lauscher : {[ereignis : string] : Array<(angaben ?: any)=>void>}; /** * @author kcf */ public constructor ( aufgabe : schnittstelle_aufgabe, welt : klasse_welt = klasse_welt.blanko() ) { this.aufgabe = aufgabe; this.welt = welt; this.figur = (new klasse_nichts()); this.testindex = (new klasse_nichts()); this.modus = modus_initial; this.lauscher = { "aenderung_aufgabe": [], "aenderung_welt": [], "aenderung_figur": [], "aenderung_modus": [], }; } /** * @author kcf */ public lauschen(ereignis : string, prozedur : (angaben ?: any)=>void) : void { if (ereignis in this.lauscher) { this.lauscher[ereignis].push(prozedur); } else { let meldung : string = "kein Ereignis mit diesem Name"; throw (new Error(meldung)); } } /** * @author kcf */ private benachrichtigen(ereignis : string, angaben : any = {}) : void { if (ereignis in this.lauscher) { this.lauscher[ereignis].forEach ( prozedur => { prozedur(angaben); } ) ; } else { let meldung : string = "kein Ereignis mit diesem Name"; throw (new Error(meldung)); } } /** * @author kcf */ public aufgabe_lesen() : schnittstelle_aufgabe { return this.aufgabe; } /** * @author kcf */ public welt_lesen() : klasse_welt { return this.welt; } /** * @author kcf */ public figur_lesen() : schnittstelle_fehlermonade { return this.figur; } /** * @author kcf */ public modus_lesen() : typ_modus { return this.modus; } /** * @author kcf */ public zuruecksetzen() : void { this.figur = (new klasse_nichts()); this.testindex = (new klasse_nichts()); this.modus = modus_initial; this.benachrichtigen("aenderung_figur", {}); this.benachrichtigen("aenderung_modus", {}); } /** * @author kcf */ public welt_feld_wechseln(stelle : typ_stelle, umgekehrt : boolean = false) : void { if (! (this.modus === mod_vtm_aufbau.modus_initial)) { let meldung : string = "gesperrt"; } else { this.welt.feld_wechseln(stelle, umgekehrt); this.benachrichtigen("aenderung_welt", {}); } } /** * @author kcf */ public welt_feld_drehen(stelle : typ_stelle, inkrement : int = +1) : void { if (! (this.modus === mod_vtm_aufbau.modus_initial)) { let meldung : string = "gesperrt"; } else { this.welt.feld_drehen(stelle, inkrement); this.benachrichtigen("aenderung_welt", {}); } } /** * @author kcf */ public fortfahren() : void { switch (this.modus) { case modus_initial: { this.modus = modus_ungewiss; this.testindex = (new klasse_schlicht(0)); this.benachrichtigen("aenderung_modus", {}); break; } case modus_ungewiss: { if (! this.figur.ist_schlicht()) { let tests : Array = this.aufgabe.tests(); let testindex : int = this.testindex.lesen(); let test : schnittstelle_test = tests[testindex]; let stelle : typ_stelle = this.welt.erzeuger_finden(); this.figur = ( new klasse_schlicht ( new klasse_figur ( mod_vtm_helfer.liste_kopieren(test.eingabe()), stelle ) ) ); this.benachrichtigen("aenderung_figur", {}); } else { let figur : klasse_figur = this.figur.lesen(); let stelle : typ_stelle = figur.stelle_lesen(); let aktor_ : schnittstelle_fehlermonade = this.welt.feld_holen(stelle); let aktor : schnittstelle_aktor = (aktor_.ist_schlicht() ? aktor_.lesen() : (new klasse_verwerfer())); aktor.verwenden(figur); let zustand : typ_zustand = figur.zustand_lesen(); if (zustand === zustand_laufend) { // nichts tun } else if ((zustand === zustand_angenommen) || (zustand === zustand_abgelehnt)) { let angenommen : boolean = (zustand === zustand_angenommen); let ausgabe : Array = figur.band_lesen(); this.figur = (new klasse_nichts()); let tests : Array = this.aufgabe.tests(); let testindex : int = this.testindex.lesen(); let test : schnittstelle_test = tests[testindex]; if (! test.pruefen(angenommen, ausgabe)) { this.modus = modus_fehlerhaft; this.benachrichtigen("aenderung_modus", {}); } else { testindex += 1; if (testindex >= tests.length) { // auf Modus "korrekt" wechseln this.testindex = (new klasse_nichts()); this.modus = modus_korrekt; this.benachrichtigen("aenderung_modus", {}); } else { // nächsten Test auswählen this.testindex = (new klasse_schlicht(testindex)); } } } else { let meldung : string = "unbehandelter Zustand"; throw (new Error(meldung)); } this.benachrichtigen("aenderung_figur", {}); } break; } case modus_fehlerhaft: { // nichts tun break; } case modus_korrekt: { // nichts tun break; } default: { let meldung : string = "unbehandelter Modus"; throw (new Error(meldung)); break; } } } } }