/* * 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_welt { /** * @author kcf */ export type typ_welt = { felder : lib_hashmap.typ_hashmap; } ; /** * @author kcf */ export function erstellen ( felder : lib_hashmap.typ_hashmap = lib_hashmap.erstellen(mod_stelle.hash) ) : typ_welt { return { "felder": felder, }; } /** * @author kcf */ export function felder_lesen ( welt : typ_welt ) : Array<{stelle : mod_stelle.typ_stelle; aktor : mod_aktor.typ_aktor;}> { let felder : Array<{stelle : mod_stelle.typ_stelle; aktor : mod_aktor.typ_aktor;}> = []; lib_hashmap.iterieren ( welt.felder, (stelle, aktor) => felder.push({"stelle": stelle, "aktor": aktor}) ) ; return felder; } /** * @author kcf */ export function feld_holen ( welt : typ_welt, stelle : mod_stelle.typ_stelle ) : lib_fehlermonade.typ_fehlermonade { return lib_hashmap.holen(welt.felder, stelle); } /** * @author kcf */ export function feld_setzen ( welt : typ_welt, stelle : mod_stelle.typ_stelle, aktor : mod_aktor.typ_aktor ) : void { lib_hashmap.setzen(welt.felder, stelle, aktor); } /** * @author kcf */ export function feld_wechseln ( welt : typ_welt, stelle : mod_stelle.typ_stelle, umgekehrt : boolean = false ) : void { let erweitert : boolean = true; let liste : Array<{pruefer : (aktor : mod_aktor.typ_aktor)=>boolean; ersteller : ()=>mod_aktor.typ_aktor;}> = ( [] .concat ( [ { "pruefer": (aktor) => (aktor.art === "befoerderer"), "ersteller": () => mod_aktor.mod_befoerderer.erstellen_aktor(0), }, ] ) .concat ( mod_vtm.mod_helfer.sequenz(erweitert ? 4 : 2).map ( symbol => ( { "pruefer": (aktor) => { if (aktor.art === "schreiber") { return (mod_aktor.mod_schreiber.symbol_lesen(aktor.angaben) === symbol); } else { return false; } } , "ersteller": () => mod_aktor.mod_schreiber.erstellen_aktor(0, symbol) } ) ) ) .concat ( mod_vtm.mod_helfer.sequenz(erweitert ? 2 : 1).map ( index => { let symbol_links : mod_symbol.typ_symbol = (2*index+0); let symbol_rechts : mod_symbol.typ_symbol = (2*index+1); return ( { "pruefer": (aktor) => { if (aktor.art === "leser") { return ( (mod_aktor.mod_leser.symbol_links_lesen(aktor.angaben) === symbol_links) && (mod_aktor.mod_leser.symbol_rechts_lesen(aktor.angaben) === symbol_rechts) ); } else { return false; } } , "ersteller": () => mod_aktor.mod_leser.erstellen_aktor(0, symbol_links, symbol_rechts) } ); } ) ) .concat ( [ { "pruefer": (aktor) => (aktor.art === "verwerfer"), "ersteller": () => mod_aktor.mod_verwerfer.erstellen_aktor(), }, ] ) ); let index_alt : lib_fehlermonade.typ_fehlermonade; let aktor_alt_ : lib_fehlermonade.typ_fehlermonade = lib_hashmap.holen(welt.felder, stelle); if (lib_fehlermonade.voll(aktor_alt_)) { let aktor_alt : mod_aktor.typ_aktor = lib_fehlermonade.lesen(aktor_alt_); let gefunden : boolean = ( liste.some ( (eintrag, index) => { if (eintrag.pruefer(aktor_alt)) { index_alt = (lib_fehlermonade.erstellen_schlicht(index)); return true; } else { return false; } } ) ); if (! gefunden) { index_alt = (lib_fehlermonade.erstellen_nichts()); } else { // nichts tun } } else { let meldung : string = "kein Aktor gesetzt"; // console.warn(meldung); index_alt = (lib_fehlermonade.erstellen_schlicht(0)); } if (lib_fehlermonade.voll(index_alt)) { let index_neu : int = lib_mathematik.mod(lib_fehlermonade.lesen(index_alt) + (umgekehrt ? -1 : +1), liste.length); let aktor_neu : mod_aktor.typ_aktor = liste[index_neu].ersteller(); feld_setzen(welt, stelle, aktor_neu); } else { let meldung : string = ("Aktor nicht gefunden"); // throw (new Error(meldung)); console.warn(meldung); } } /** * @author kcf */ export function feld_drehen ( welt : typ_welt, stelle : mod_stelle.typ_stelle, inkrement : int = +1 ) : void { let aktor_ : lib_fehlermonade.typ_fehlermonade = lib_hashmap.holen(welt.felder, stelle); if (lib_fehlermonade.voll(aktor_)) { mod_aktor.drehen(lib_fehlermonade.lesen(aktor_), inkrement); } else { console.warn("kein Aktor gesetzt"); } } /** * @author kcf * @throws {Error} */ export function erzeuger_finden ( welt : typ_welt ) : mod_stelle.typ_stelle { let stelle : lib_fehlermonade.typ_fehlermonade = (lib_fehlermonade.erstellen_nichts()); lib_hashmap.iterieren ( welt.felder, (stelle_, aktor) => { if (aktor.art === "erzeuger") { if (lib_fehlermonade.voll(stelle)) { let meldung : string = "mehrere Erzeuger gefunden"; throw (new Error(meldung)); } else { stelle = (lib_fehlermonade.erstellen_schlicht(stelle_)); } } } ) ; if (lib_fehlermonade.voll(stelle)) { return lib_fehlermonade.lesen(stelle); } else { let meldung : string = "kein Erzeuger gefunden"; throw (new Error(meldung)); } } /** * @author kcf */ export function blanko ( groesse : int = 3 ) : typ_welt { let welt : typ_welt = erstellen(); 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 : mod_stelle.typ_stelle = {"u": u, "v": v}; let aktor : mod_aktor.typ_aktor; if ((u === -groesse) && (v === 0)) { aktor = mod_aktor.mod_erzeuger.erstellen_aktor(0); } else if ((u === +groesse) && (v === 0)) { aktor = mod_aktor.mod_annehmer.erstellen_aktor(); } else { aktor = mod_aktor.mod_verwerfer.erstellen_aktor(); } lib_hashmap.setzen(welt.felder, stelle, aktor); } } } return welt; } /** * @author kcf */ export function exportieren ( welt : typ_welt ) : any { let roh : any = {}; roh["felder"] = {}; lib_hashmap.iterieren ( welt.felder, (stelle, aktor) => { let stelle_ : string = mod_stelle.exportieren(stelle); let aktor_ : any = mod_aktor.exportieren(aktor); roh["felder"][stelle_] = aktor_; } ) ; return roh; } /** * @author kcf */ export function importieren ( roh : any ) : typ_welt { let felder : lib_hashmap.typ_hashmap = (lib_hashmap.erstellen(mod_stelle.hash)); for (let stelle_ in roh["felder"]) { let stelle : mod_stelle.typ_stelle = mod_stelle.importieren(stelle_); let aktor_ : mod_aktor.typ_aktor = roh["felder"][stelle_]; let aktor : mod_aktor.typ_aktor = mod_aktor.importieren(aktor_); lib_hashmap.setzen(felder, stelle, aktor); } return ( erstellen ( felder ) ); } } } }