/* * 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 { export module mod_aufbau { export module mod_partie { /** * @author kcf */ export type typ_partie = { welt : mod_welt.typ_welt; figur : lib_fehlermonade.typ_fehlermonade; aufgabe : mod_aufgabe.typ_aufgabe; testindex : lib_fehlermonade.typ_fehlermonade; modus : mod_modus.typ_modus; lauscher : {[ereignis : string] : Array<(angaben ?: any)=>void>}; } ; /** * @author kcf */ export function erstellen ( aufgabe : mod_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": [], }; welt_leeren(partie, false); zuruecksetzen(partie, false); return partie; } /** * @author kcf */ export function 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 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 zuruecksetzen ( partie : typ_partie, bescheid_geben : boolean = true ) : void { partie.figur = (lib_fehlermonade.erstellen_nichts()); partie.testindex = (lib_fehlermonade.erstellen_nichts()); partie.modus = mod_modus.initial; if (bescheid_geben) { benachrichtigen(partie, "aenderung_figur", {}); benachrichtigen(partie, "aenderung_modus", {}); } else { // nichts tun } } /** * @author kcf */ export function aufgabe_lesen ( partie : typ_partie ) : mod_aufgabe.typ_aufgabe { return partie.aufgabe; } /** * @author kcf */ export function aufgabe_setzen ( partie : typ_partie, aufgabe : mod_aufgabe.typ_aufgabe ) : void { partie.aufgabe = aufgabe; // partie.welt_leeren(); benachrichtigen(partie, "aenderung_aufgabe", {}); zuruecksetzen(partie); } /** * @author kcf */ export function welt_lesen ( partie : typ_partie ) : mod_welt.typ_welt { return partie.welt; } /** * @author kcf */ export function welt_setzen ( partie : typ_partie, welt : mod_welt.typ_welt, bescheid_geben : boolean = true ) : void { partie.welt = welt; if (bescheid_geben) { benachrichtigen(partie, "aenderung_welt", {}); } else { // nichts tun } } /** * @author kcf */ export function welt_leeren ( partie : typ_partie, bescheid_geben : boolean = true ) : void { partie.welt = mod_welt.blanko(); if (bescheid_geben) { benachrichtigen(partie, "aenderung_welt", {}); } else { // nichts tun } } /** * @author kcf */ export function figur_lesen ( partie : typ_partie ) : lib_fehlermonade.typ_fehlermonade { return partie.figur; } /** * @author kcf */ export function modus_lesen ( partie : typ_partie ) : mod_modus.typ_modus { return partie.modus; } /** * @author kcf */ export function welt_feld_wechseln ( partie : typ_partie, stelle : mod_stelle.typ_stelle, umgekehrt : boolean = false ) : void { if (! (partie.modus === mod_modus.initial)) { let meldung : string = "gesperrt"; } else { mod_welt.feld_wechseln(partie.welt, stelle, umgekehrt); benachrichtigen ( partie, "aenderung_welt", { "art": "feld_wechseln", "angaben": { "stelle": stelle, "umgekehrt": umgekehrt, "feld": mod_welt.feld_holen(partie.welt, stelle), } } ) ; } } /** * @author kcf */ export function welt_feld_drehen ( partie : typ_partie, stelle : mod_stelle.typ_stelle, inkrement : int = +1 ) : void { if (! (partie.modus === mod_modus.initial)) { let meldung : string = "gesperrt"; } else { mod_welt.feld_drehen(partie.welt, stelle, inkrement); benachrichtigen(partie, "aenderung_welt", {}); } } /** * @author kcf */ export function fortfahren ( partie : typ_partie ) : void { switch (partie.modus) { case mod_modus.initial: { partie.modus = mod_modus.ungewiss; partie.testindex = (lib_fehlermonade.erstellen_schlicht(0)); benachrichtigen(partie, "aenderung_modus", {}); break; } case mod_modus.ungewiss: { if (! lib_fehlermonade.voll(partie.figur)) { let test : mod_test.typ_test = mod_aufgabe.tests(partie.aufgabe)[lib_fehlermonade.lesen(partie.testindex)]; let band : Array = mod_vtm.mod_helfer.liste_kopieren(mod_test.eingabe(test)); let stelle : mod_stelle.typ_stelle = mod_welt.erzeuger_finden(partie.welt); partie.figur = ( lib_fehlermonade.erstellen_schlicht ( mod_figur.erstellen ( band, stelle ) ) ); } else { let figur : mod_figur.typ_figur = lib_fehlermonade.lesen(partie.figur); let stelle : mod_stelle.typ_stelle = mod_figur.stelle_lesen(figur); let aktor_ : lib_fehlermonade.typ_fehlermonade = mod_welt.feld_holen(partie.welt, stelle); let aktor : mod_aktor.typ_aktor = ( lib_fehlermonade.voll(aktor_) ? lib_fehlermonade.lesen(aktor_) : mod_aktor.mod_verwerfer.erstellen_aktor() ); mod_aktor.verwenden(aktor, figur); let zustand : mod_zustand.typ_zustand = mod_figur.zustand_lesen(figur); if (zustand === mod_zustand.laufend) { // nichts tun } else if ((zustand === mod_zustand.angenommen) || (zustand === mod_zustand.abgelehnt)) { let angenommen : boolean = (zustand === mod_zustand.angenommen); let ausgabe : Array = mod_figur.band_lesen(figur); partie.figur = (lib_fehlermonade.erstellen_nichts()); let testindex : int = lib_fehlermonade.lesen(partie.testindex); let tests : Array = mod_aufgabe.tests(partie.aufgabe); let test : mod_test.typ_test = tests[testindex]; if (! mod_test.pruefen(test, angenommen, ausgabe)) { partie.modus = mod_modus.fehlerhaft; benachrichtigen(partie, "aenderung_modus", {}); } else { testindex += 1; if (testindex < tests.length) { // nächsten Test auswählen partie.testindex = (lib_fehlermonade.erstellen_schlicht(testindex)); } else { // auf Modus "korrekt" wechseln partie.testindex = (lib_fehlermonade.erstellen_nichts()); partie.modus = mod_modus.korrekt; benachrichtigen(partie, "aenderung_modus", {}); } } } else { let meldung : string = "unbehandelter Zustand"; throw (new Error(meldung)); } } benachrichtigen(partie, "aenderung_figur", {}); break; } case mod_modus.fehlerhaft: { // nichts tun break; } case mod_modus.korrekt: { // nichts tun break; } default: { let meldung : string = "unbehandelter Modus"; throw (new Error(meldung)); break; } } } } } }