/* * 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 export function partie_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 export function partie_License for more details. * * You should have received a copy of the GNU General export function partie_License * along with this program. If not, see . */ module mod_vtm_aufbau { /** * @author kcf */ export type typ_partie = { welt : typ_welt; figur : schnittstelle_fehlermonade; aufgabe : typ_aufgabe; testindex : schnittstelle_fehlermonade; modus : typ_modus; lauscher : {[ereignis : string] : Array<(angaben ?: any)=>void>}; } ; /** * @author kcf */ export function partie_erstellen ( aufgabe : typ_aufgabe ) : typ_partie { let partie : typ_partie = { "welt": undefined, "figur": undefined, "aufgabe": aufgabe, "testindex": undefined, "modus": undefined, "lauscher": undefined, }; partie.lauscher = { "aenderung_aufgabe": [], "aenderung_welt": [], "aenderung_figur": [], "aenderung_modus": [], }; partie_welt_leeren(partie, false); partie_zuruecksetzen(partie, false); return partie; } /** * @author kcf */ export function partie_lauschen(partie : typ_partie, ereignis : string, prozedur : (angaben ?: any)=>void) : void { if (ereignis in partie.lauscher) { partie.lauscher[ereignis].push(prozedur); } else { let meldung : string = "kein Ereignis mit diesem Name"; throw (new Error(meldung)); } } /** * @author kcf */ function partie_benachrichtigen(partie : typ_partie, ereignis : string, angaben : any = {}) : void { if (ereignis in partie.lauscher) { partie.lauscher[ereignis].forEach ( prozedur => { prozedur(angaben); } ) ; } else { let meldung : string = "kein Ereignis mit diesem Name"; throw (new Error(meldung)); } } /** * @author kcf */ export function partie_zuruecksetzen(partie : typ_partie, bescheid_geben : boolean = true) : void { partie.figur = (new klasse_nichts()); partie.testindex = (new klasse_nichts()); partie.modus = modus_initial; if (bescheid_geben) { partie_benachrichtigen(partie, "aenderung_figur", {}); partie_benachrichtigen(partie, "aenderung_modus", {}); } else { // nichts tun } } /** * @author kcf */ export function partie_aufgabe_lesen(partie : typ_partie) : typ_aufgabe { return partie.aufgabe; } /** * @author kcf */ export function partie_aufgabe_setzen(partie : typ_partie, aufgabe : typ_aufgabe) : void { partie.aufgabe = aufgabe; // partie.welt_leeren(); partie_benachrichtigen(partie, "aenderung_aufgabe", {}); partie_zuruecksetzen(partie); } /** * @author kcf */ export function partie_welt_lesen(partie : typ_partie) : typ_welt { return partie.welt; } /** * @author kcf */ export function partie_welt_setzen(partie : typ_partie, welt : mod_vtm_aufbau.typ_welt, bescheid_geben : boolean = true) : void { partie.welt = welt; if (bescheid_geben) { partie_benachrichtigen(partie, "aenderung_welt", {}); } else { // nichts tun } } /** * @author kcf */ export function partie_welt_leeren(partie : typ_partie, bescheid_geben : boolean = true) : void { partie.welt = welt_blanko(); if (bescheid_geben) { partie_benachrichtigen(partie, "aenderung_welt", {}); } else { // nichts tun } } /** * @author kcf */ export function partie_figur_lesen(partie : typ_partie) : schnittstelle_fehlermonade { return partie.figur; } /** * @author kcf */ export function partie_modus_lesen(partie : typ_partie) : typ_modus { return partie.modus; } /** * @author kcf */ export function partie_welt_feld_wechseln(partie : typ_partie, stelle : typ_stelle, umgekehrt : boolean = false) : void { if (! (partie.modus === mod_vtm_aufbau.modus_initial)) { let meldung : string = "gesperrt"; } else { welt_feld_wechseln(partie.welt, stelle, umgekehrt); partie_benachrichtigen ( partie, "aenderung_welt", { "art": "feld_wechseln", "angaben": { "stelle": stelle, "umgekehrt": umgekehrt, "feld": welt_feld_holen(partie.welt, stelle), } } ) ; } } /** * @author kcf */ export function partie_welt_feld_drehen(partie : typ_partie, stelle : typ_stelle, inkrement : int = +1) : void { if (! (partie.modus === mod_vtm_aufbau.modus_initial)) { let meldung : string = "gesperrt"; } else { welt_feld_drehen(partie.welt, stelle, inkrement); partie_benachrichtigen(partie, "aenderung_welt", {}); } } /** * @author kcf */ export function partie_fortfahren(partie : typ_partie) : void { switch (partie.modus) { case modus_initial: { partie.modus = modus_ungewiss; partie.testindex = (new klasse_schlicht(0)); partie_benachrichtigen(partie, "aenderung_modus", {}); break; } case modus_ungewiss: { if (! partie.figur.ist_schlicht()) { let test : typ_test = aufgabe_tests(partie.aufgabe)[partie.testindex.lesen()]; let band : Array = mod_vtm_helfer.liste_kopieren(test_eingabe(test)); let stelle : typ_stelle = welt_erzeuger_finden(partie.welt); partie.figur = ( new klasse_schlicht ( figur_erstellen ( band, stelle ) ) ); } else { let figur : typ_figur = partie.figur.lesen(); let stelle : typ_stelle = figur_stelle_lesen(figur); let aktor_ : schnittstelle_fehlermonade = welt_feld_holen(partie.welt, stelle); let aktor : typ_aktor = (aktor_.ist_schlicht() ? aktor_.lesen() : verwerfer_erstellen_aktor()); aktor_verwenden(aktor, figur); let zustand : typ_zustand = figur_zustand_lesen(figur); 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(figur); partie.figur = (new klasse_nichts()); let testindex : int = partie.testindex.lesen(); let tests : Array = aufgabe_tests(partie.aufgabe); let test : typ_test = tests[testindex]; if (! test_pruefen(test, angenommen, ausgabe)) { partie.modus = modus_fehlerhaft; partie_benachrichtigen(partie, "aenderung_modus", {}); } else { testindex += 1; if (testindex < tests.length) { // nächsten Test auswählen partie.testindex = (new klasse_schlicht(testindex)); } else { // auf Modus "korrekt" wechseln partie.testindex = (new klasse_nichts()); partie.modus = modus_korrekt; partie_benachrichtigen(partie, "aenderung_modus", {}); } } } else { let meldung : string = "unbehandelter Zustand"; throw (new Error(meldung)); } } partie_benachrichtigen(partie, "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; } } } }