/* * Verrückte Turing-Maschinen — A turing complete game * Copyright (C) 2016-2018 kcf * * 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_model { export module mod_world { /** * @author kcf */ export type type_world = { tiles : lib_hashmap.type_hashmap; } ; /** * @author kcf */ export function create ( tiles : lib_hashmap.type_hashmap = lib_hashmap.create(mod_spot.hash) ) : type_world { return { "tiles": tiles, }; } /** * @author kcf */ export function tiles_read ( world : type_world ) : Array<{spot : mod_spot.type_spot; actuator : mod_actuator.type_actuator;}> { let tiles : Array<{spot : mod_spot.type_spot; actuator : mod_actuator.type_actuator;}> = []; lib_hashmap.iterate ( world.tiles, (spot, actuator) => {tiles.push({"spot": spot, "actuator": actuator});} ) ; return tiles; } /** * @author kcf */ export function tile_get ( world : type_world, spot : mod_spot.type_spot ) : lib_errormonade.type_errormonade { return lib_hashmap.get(world.tiles, spot); } /** * @author kcf */ export function tile_set ( world : type_world, spot : mod_spot.type_spot, actuator : mod_actuator.type_actuator ) : void { lib_hashmap.set(world.tiles, spot, actuator); } /** * @author kcf */ export function tile_change ( world : type_world, spot : mod_spot.type_spot, inverted : boolean = false ) : void { const extended : boolean = true; const liste : Array<{pruefer : (actuator : mod_actuator.type_actuator)=>boolean; erspotr : ()=>mod_actuator.type_actuator;}> = ( [] .concat ( [ { "pruefer": (actuator) => (actuator.kind === "conveyer"), "erspotr": () => mod_actuator.mod_conveyer.create_extended(0), }, ] ) .concat ( lib_list.sequence(extended ? 4 : 2).map ( symbol => ( { "pruefer": (actuator) => { if (actuator.kind === "writer") { return (mod_actuator.mod_writer.symbol_read(actuator.data) === symbol); } else { return false; } } , "erspotr": () => mod_actuator.mod_writer.create_extended(0, symbol) } ) ) ) .concat ( lib_list.sequence(extended ? 2 : 1).map ( index => { let symbol_links : mod_symbol.type_symbol = (2*index+0); let symbol_rechts : mod_symbol.type_symbol = (2*index+1); return ( { "pruefer": (actuator) => { if (actuator.kind === "reader") { return ( (mod_actuator.mod_reader.symbol_links_read(actuator.data) === symbol_links) && (mod_actuator.mod_reader.symbol_rechts_read(actuator.data) === symbol_rechts) ); } else { return false; } } , "erspotr": () => mod_actuator.mod_reader.create_extended(0, symbol_links, symbol_rechts) } ); } ) ) .concat ( [ { "pruefer": (actuator) => (actuator.kind === "rejector"), "erspotr": () => mod_actuator.mod_rejector.create_extended(), }, ] ) ); let index_alt : lib_errormonade.type_errormonade; const actuator_alt_ : lib_errormonade.type_errormonade = lib_hashmap.get(world.tiles, spot); if (lib_errormonade.filled(actuator_alt_)) { const actuator_alt : mod_actuator.type_actuator = lib_errormonade.read(actuator_alt_); const gefunden : boolean = ( liste .some ( (entry, index) => { if (entry.pruefer(actuator_alt)) { index_alt = (lib_errormonade.create_just(index)); return true; } else { return false; } } ) ); if (! gefunden) { index_alt = (lib_errormonade.create_nothing()); } else { // nothing tun } } else { const message : string = "kein Aktor gesetzt"; // console.warn(message); index_alt = (lib_errormonade.create_just(0)); } if (lib_errormonade.filled(index_alt)) { const index_neu : int = lib_math.mod(lib_errormonade.read(index_alt) + (inverted ? -1 : +1), liste.length); const actuator_neu : mod_actuator.type_actuator = liste[index_neu].erspotr(); tile_set(world, spot, actuator_neu); } else { const message : string = ("Aktor nicht gefunden"); // throw (new Error(message)); console.warn(message); } } /** * @author kcf */ export function tile_rotate ( world : type_world, spot : mod_spot.type_spot, increment : int = +1 ) : void { let actuator_ : lib_errormonade.type_errormonade = lib_hashmap.get(world.tiles, spot); if (lib_errormonade.filled(actuator_)) { mod_actuator.rotate(lib_errormonade.read(actuator_), increment); } else { console.warn("kein Aktor gesetzt"); } } /** * @author kcf * @throws {Error} */ export function generator_finden ( world : type_world ) : mod_spot.type_spot { let spot : lib_errormonade.type_errormonade = (lib_errormonade.create_nothing()); lib_hashmap.iterate ( world.tiles, (spot_, actuator) => { if (actuator.kind === "generator") { if (lib_errormonade.filled(spot)) { const message : string = "mehrere Erzeuger gefunden"; throw (new Error(message)); } else { spot = (lib_errormonade.create_just(spot_)); } } } ) ; if (lib_errormonade.filled(spot)) { return lib_errormonade.read(spot); } else { const message : string = "kein Erzeuger gefunden"; throw (new Error(message)); } } /** * @author kcf */ export function blanko ( groesse : int = 3 ) : type_world { let world : type_world = create(); for (let u : int = -groesse; u <= +groesse; u += 1) { for (let v : int = -groesse; v <= +groesse; v += 1) { if (Math.abs(u-v) <= groesse) { const spot : mod_spot.type_spot = {"u": u, "v": v}; let actuator : mod_actuator.type_actuator; if ((u === -groesse) && (v === 0)) { actuator = mod_actuator.mod_generator.create_extended(0); } else if ((u === +groesse) && (v === 0)) { actuator = mod_actuator.mod_acceptor.create_extended(); } else { actuator = mod_actuator.mod_rejector.create_extended(); } lib_hashmap.set(world.tiles, spot, actuator); } } } return world; } /** * @author kcf */ export function export_ ( world : type_world ) : any { let raw : any = {}; raw["tiles"] = {}; lib_hashmap.iterate ( world.tiles, (spot, actuator) => { const spot_ : string = mod_spot.export_(spot); const actuator_ : any = mod_actuator.export_(actuator); raw["tiles"][spot_] = actuator_; } ) ; return raw; } /** * @author kcf */ export function import_ ( raw : any ) : type_world { let tiles : lib_hashmap.type_hashmap = (lib_hashmap.create(mod_spot.hash)); for (let spot_ in raw["tiles"]) { const spot : mod_spot.type_spot = mod_spot.import_(spot_); const actuator_ : mod_actuator.type_actuator = raw["tiles"][spot_]; const actuator : mod_actuator.type_actuator = mod_actuator.import_(actuator_); lib_hashmap.set(tiles, spot, actuator); } return ( create ( tiles ) ); } } } }