/* * 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_welt { /** * @author kcf */ private felder : mod_vtm_helfer.klasse_hashmap; /** * @author kcf */ public constructor ( felder : mod_vtm_helfer.klasse_hashmap = (new mod_vtm_helfer.klasse_hashmap(stelle_hash)) ) { this.felder = felder; } /** * @author kcf */ public felder_lesen() : Array<{stelle : typ_stelle; aktor : schnittstelle_aktor;}> { let felder : Array<{stelle : typ_stelle; aktor : schnittstelle_aktor;}> = []; this.felder.iterieren ( (stelle, aktor) => felder.push({"stelle": stelle, "aktor": aktor}) ) ; return felder; } /** * @author kcf */ public feld_holen(stelle : typ_stelle) : schnittstelle_fehlermonade { return this.felder.holen(stelle); } /** * @author kcf */ public feld_setzen(stelle : typ_stelle, aktor : schnittstelle_aktor) : void { this.felder.setzen(stelle, aktor); } /** * @author kcf */ public feld_wechseln(stelle : typ_stelle, umgekehrt : boolean = false) : void { let erweitert : boolean = true; let liste : Array<{pruefer : (aktor : schnittstelle_aktor)=>boolean; ersteller : ()=>schnittstelle_aktor;}> = ( [] .concat ( [ { "pruefer": (aktor) => (aktor instanceof klasse_befoerderer), "ersteller": () => new klasse_befoerderer(), }, ] ) .concat ( mod_vtm_helfer.sequenz(erweitert ? 4 : 2).map ( symbol => ( { "pruefer": (aktor) => { if (aktor instanceof klasse_schreiber) { let schreiber : klasse_schreiber = (aktor); return (schreiber.symbol_lesen() === symbol); } else { return false; } } , "ersteller": () => new klasse_schreiber(0, symbol), } ) ) ) .concat ( mod_vtm_helfer.sequenz(erweitert ? 2 : 1).map ( index => { let symbol_links : typ_symbol = (2*index+0); let symbol_rechts : typ_symbol = (2*index+1); return ( { "pruefer": (aktor) => { if (aktor instanceof klasse_leser) { let leser : klasse_leser = (aktor); return ( (leser.symbol_links_lesen() === symbol_links) && (leser.symbol_rechts_lesen() === symbol_rechts) ); } else { return false; } } , "ersteller": () => new klasse_leser(0, symbol_links, 2*index+1), } ); } ) ) .concat ( [ { "pruefer": (aktor) => (aktor instanceof klasse_verwerfer), "ersteller": () => new klasse_verwerfer(), }, ] ) ); let index_alt : schnittstelle_fehlermonade; let aktor_alt_ : schnittstelle_fehlermonade = this.felder.holen(stelle); if (aktor_alt_.ist_schlicht) { let aktor_alt : schnittstelle_aktor = aktor_alt_.lesen(); let gefunden : boolean = liste.some ( (eintrag, index) => { if (eintrag.pruefer(aktor_alt)) { index_alt = (new klasse_schlicht(index)); return true; } else { return false; } } ) ; if (! gefunden) { index_alt = (new klasse_nichts()); } else { // nichts tun } } else { let meldung : string = "kein Aktor gesetzt"; // console.warn(meldung); index_alt = (new klasse_schlicht(0)); } if (index_alt.ist_schlicht()) { let index_neu : int = mod_vtm_helfer.mod(index_alt.lesen() + (umgekehrt ? -1 : +1), liste.length); let aktor_neu : schnittstelle_aktor = liste[index_neu].ersteller(); this.feld_setzen(stelle, aktor_neu); } else { let meldung : string = ("Aktor nicht gefunden"); // throw (new Error(meldung)); console.warn(meldung); } } /** * @author kcf */ public feld_drehen(stelle : typ_stelle, inkrement : int = +1) : void { let aktor_ : schnittstelle_fehlermonade = this.felder.holen(stelle); if (aktor_.ist_schlicht) { aktor_.lesen().drehen(inkrement); } else { console.warn("kein Aktor gesetzt"); } } /** * @author kcf * @throws {Error} */ public erzeuger_finden() : typ_stelle { let stelle : schnittstelle_fehlermonade = (new klasse_nichts()); this.felder.iterieren ( (stelle_, aktor) => { if (aktor instanceof klasse_erzeuger) { if (stelle.ist_schlicht()) { let meldung : string = "mehrere Erzeuger gefunden"; throw (new Error(meldung)); } else { stelle = (new klasse_schlicht(stelle_)); } } } ) ; if (stelle.ist_schlicht()) { return stelle.lesen(); } else { let meldung : string = "kein Erzeuger gefunden"; throw (new Error(meldung)); } } /** * @author kcf */ public static blanko(groesse : int = 3) : klasse_welt { let welt : klasse_welt = new klasse_welt(); for (let u : int = -groesse; u <= +groesse; u += 1) { for (let v : int = -groesse; v <= +groesse; v += 1) { if (Math.abs(u-v) <= groesse) { let stelle : typ_stelle = {"u": u, "v": v}; let aktor : schnittstelle_aktor; if ((u === -groesse) && (v === 0)) { aktor = (new klasse_erzeuger(0)); } else if ((u === +groesse) && (v === 0)) { aktor = (new klasse_annehmer()); } else { aktor = (new klasse_verwerfer()); } welt.felder.setzen(stelle, aktor); } } } return welt; } /** * @author kcf */ public exportieren() : any { let roh : any = {}; roh["felder"] = {}; this.felder.iterieren ( (stelle, aktor) => { let stelle_ : string = stelle_exportieren(stelle); let aktor_ : any = aktor_exportieren(aktor); roh["felder"][stelle_] = aktor_; } ) ; return roh; } /** * @author kcf */ public static importieren(roh : any) : klasse_welt { let felder : mod_vtm_helfer.klasse_hashmap = (new mod_vtm_helfer.klasse_hashmap(stelle_hash)); for (let stelle_ in roh["felder"]) { let stelle : typ_stelle = stelle_importieren(stelle_); let aktor_ : schnittstelle_aktor = roh["felder"][stelle_]; let aktor : schnittstelle_aktor = aktor_importieren(aktor_); felder.setzen(stelle, aktor); } return ( new klasse_welt ( felder ) ); } } }