diff --git a/makefile b/makefile index 7c7bd64..320a194 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,10 @@ -alles: erzeugnis/vtm.html erzeugnis/vtm.css erzeugnis/aufgaben.dat.js erzeugnis/vtm.js -.PHONY: alles +all: erzeugnis/vtm.html erzeugnis/vtm.css erzeugnis/aufgaben.dat.js erzeugnis/vtm.js +.PHONY: all + +clear: + @ echo "-- zurücksetzen …" + @ rm -f erzeugnis +.PHONY: clear erzeugnis/vtm.html: quelldatein/manifestation/web/vtm.html @ echo "-- Struktur …" @@ -11,10 +16,17 @@ erzeugnis/vtm.css: quelldatein/manifestation/web/vtm.css quelldatein/manifestati @ mkdir -p erzeugnis @ cat quelldatein/manifestation/web/vtm.css quelldatein/manifestation/web/partie.css > erzeugnis/vtm.css -erzeugnis/aufgaben.dat.js: quelldatein/daten/aufgaben.dat.js +erzeugnis/aufgaben.dat.js: \ + quelldatein/daten/aufgaben.dat.js \ + quelldatein/daten/zeichenketten/de.dat.js \ + quelldatein/daten/zeichenketten/en.dat.js @ echo "-- Daten …" @ mkdir -p erzeugnis - @ cat quelldatein/daten/aufgaben.dat.js > erzeugnis/daten.js + @ cat \ + quelldatein/daten/aufgaben.dat.js \ + quelldatein/daten/zeichenketten/de.dat.js \ + quelldatein/daten/zeichenketten/en.dat.js \ + > erzeugnis/daten.js erzeugnis/vtm.js: \ quelldatein/basis/typen.ts \ @@ -24,6 +36,7 @@ erzeugnis/vtm.js: \ quelldatein/helfer/vektor.ts \ quelldatein/helfer/hashmap.ts \ quelldatein/helfer/xmlknoten.ts \ + quelldatein/helfer/uebersetzung.ts \ quelldatein/daten.ts \ quelldatein/aufbau/richtung.ts \ quelldatein/aufbau/symbol.ts \ @@ -66,6 +79,7 @@ erzeugnis/vtm.js: \ quelldatein/helfer/vektor.ts \ quelldatein/helfer/hashmap.ts \ quelldatein/helfer/xmlknoten.ts \ + quelldatein/helfer/uebersetzung.ts \ quelldatein/daten.ts \ quelldatein/aufbau/richtung.ts \ quelldatein/aufbau/symbol.ts \ diff --git a/quelldatein/aufbau/partie.ts b/quelldatein/aufbau/partie.ts index e05e7e4..7660910 100644 --- a/quelldatein/aufbau/partie.ts +++ b/quelldatein/aufbau/partie.ts @@ -66,15 +66,12 @@ module mod_vtm_aufbau */ public constructor ( - aufgabe : schnittstelle_aufgabe, - welt : klasse_welt = klasse_welt.blanko() + aufgabe : schnittstelle_aufgabe ) { this.aufgabe = aufgabe; - this.welt = welt; - this.figur = (new klasse_nichts()); - this.testindex = (new klasse_nichts()); - this.modus = modus_initial; + this.welt_leeren(false); + this.zuruecksetzen(false); this.lauscher = { "aenderung_aufgabe": [], "aenderung_welt": [], @@ -125,6 +122,42 @@ module mod_vtm_aufbau } + /** + * @author kcf + */ + public welt_leeren(bescheid_geben : boolean = true) : void + { + this.welt = klasse_welt.blanko(); + if (bescheid_geben) + { + this.benachrichtigen("aenderung_welt", {}); + } + else + { + // nichts tun + } + } + + /** + * @author kcf + */ + public zuruecksetzen(bescheid_geben : boolean = true) : void + { + this.figur = (new klasse_nichts()); + this.testindex = (new klasse_nichts()); + this.modus = modus_initial; + if (bescheid_geben) + { + this.benachrichtigen("aenderung_figur", {}); + this.benachrichtigen("aenderung_modus", {}); + } + else + { + // nichts tun + } + } + + /** * @author kcf */ @@ -140,9 +173,8 @@ module mod_vtm_aufbau public aufgabe_setzen(aufgabe : schnittstelle_aufgabe) : void { this.aufgabe = aufgabe; - this.welt = klasse_welt.blanko(); + this.welt_leeren(); this.benachrichtigen("aenderung_aufgabe", {}); - this.benachrichtigen("aenderung_welt", {}); this.zuruecksetzen(); } @@ -174,19 +206,6 @@ module mod_vtm_aufbau } - /** - * @author kcf - */ - public zuruecksetzen() : void - { - this.figur = (new klasse_nichts()); - this.testindex = (new klasse_nichts()); - this.modus = modus_initial; - this.benachrichtigen("aenderung_figur", {}); - this.benachrichtigen("aenderung_modus", {}); - } - - /** * @author kcf */ diff --git a/quelldatein/aufbau/welt.ts b/quelldatein/aufbau/welt.ts index f3b3aab..424fd34 100644 --- a/quelldatein/aufbau/welt.ts +++ b/quelldatein/aufbau/welt.ts @@ -160,18 +160,18 @@ module mod_vtm_aufbau ] ) ); - let index : int; + 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_) => + (eintrag, index) => { if (eintrag.pruefer(aktor_alt)) { - index = index_; + index_alt = (new klasse_schlicht(index)); return true; } else @@ -183,9 +183,7 @@ module mod_vtm_aufbau ; if (! gefunden) { - let meldung : string = ("Aktor nicht gefunden"); - // throw (new Error(meldung)); - console.warn(meldung); + index_alt = (new klasse_nichts()); } else { @@ -196,10 +194,20 @@ module mod_vtm_aufbau { let meldung : string = "kein Aktor gesetzt"; // console.warn(meldung); - index = 0; + 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); } - let aktor_neu : schnittstelle_aktor = liste[mod_vtm_helfer.mod(index + (umgekehrt ? -1 : +1), liste.length)].ersteller(); - this.feld_setzen(stelle, aktor_neu); } diff --git a/quelldatein/daten/aufgaben.dat.js b/quelldatein/daten/aufgaben.dat.js index 6ab4747..0af2668 100644 --- a/quelldatein/daten/aufgaben.dat.js +++ b/quelldatein/daten/aufgaben.dat.js @@ -69,7 +69,7 @@ jsonp_behandlung( "art": "akzeptor", "parameter": { "titel": "Abwechslung erfreuet", - "text": "Annehmen genau dann wenn: Die Farben der Eingabe (${s0} und ${s1}) sich immer abwechseln", + "text": "annehmen genau dann wenn: Die Farben der Eingabe (${s0} / ${s1}) sich immer abwechseln", "tests": [ { "eingabe": [], @@ -98,7 +98,7 @@ jsonp_behandlung( "art": "transduktor", "parameter": { "titel": "Ans Ende", - "text": "die Eingabe, aber mit dem ersten Symbol am Ende", + "text": "die Eingabe (${s0} / ${s1}), aber mit dem ersten Symbol am Ende", "tests": [ { "eingabe": [0,0,1,1,1,0,1,0,1,1,1,0,1], @@ -110,12 +110,16 @@ jsonp_behandlung( { "art": "transduktor", "parameter": { - "titel": "An den Anfang", - "text": "die Eingabe, aber mit dem letzten Symbol am Anfang", + "titel": "Tauschen", + "text": "aus der Eingabe (${s0} / ${s1}) alle ${s0} durch ${s2} ersetzen und alle ${s1} durch ${s3}", "tests": [ { - "eingabe": [0,0,1,1,1,0,1,0,1,1,1,0,1], - "ausgabe": [1,0,0,1,1,1,0,1,0,1,1,1,0] + "eingabe": [0,1,1,0], + "ausgabe": [2,3,3,2] + }, + { + "eingabe": [0,1,0,1,0,1,1,0,0,0,0,1,0,1,1,0], + "ausgabe": [2,3,2,3,2,3,3,2,2,2,2,3,2,3,3,2] } ] } @@ -124,7 +128,7 @@ jsonp_behandlung( "art": "transduktor", "parameter": { "titel": "Wählerisch", - "text": "aus der Eingabe alle ${s0} entfernen und alle ${s1} beibehalten", + "text": "aus der Eingabe (${s0} / ${s1}) alle ${s0} entfernen und alle ${s1} beibehalten", "tests": [ { "eingabe": [0,0,0,1,0], @@ -166,7 +170,7 @@ jsonp_behandlung( "art": "akzeptor", "parameter": { "titel": "Alpha und Omega", - "text": "Eingaben, die mit den gleichen Symbolen anfangen und enden", + "text": "Eingaben(${s0} / ${s1}), die mit den gleichen Symbolen anfangen und enden", "tests": [ { "eingabe": [], @@ -198,16 +202,12 @@ jsonp_behandlung( { "art": "transduktor", "parameter": { - "titel": "Tauschen", - "text": "alle ${s0} durch ${s2} ersetzen und alle ${s1} durch ${s3}", + "titel": "An den Anfang", + "text": "die Eingabe (${s0} / ${s1}), aber mit dem letzten Symbol am Anfang", "tests": [ { - "eingabe": [0,1,1,0], - "ausgabe": [2,3,3,2] - }, - { - "eingabe": [0,1,0,1,0,1,1,0,0,0,0,1,0,1,1,0], - "ausgabe": [2,3,2,3,2,3,3,2,2,2,2,3,2,3,3,2] + "eingabe": [0,0,1,1,1,0,1,0,1,1,1,0,1], + "ausgabe": [1,0,0,1,1,1,0,1,0,1,1,1,0] } ] } diff --git a/quelldatein/daten/zeichenketten/de.dat.js b/quelldatein/daten/zeichenketten/de.dat.js new file mode 100644 index 0000000..3e53a9d --- /dev/null +++ b/quelldatein/daten/zeichenketten/de.dat.js @@ -0,0 +1,51 @@ +jsonp_behandlung( + { + "schluessel": "zeichenketten-de", + "wert": { + "allgemein.titel": "Verrückte Turing-Maschinen", + "allgemein.hilfe": "Hilfe", + "allgemein.spiel": "Spiel", + "aufbau.figur.worter.singular": "Figur", + "aufbau.figur.worter.plural": "Figuren", + "aufbau.aktoren.woerter.singular": "Aktor", + "aufbau.aktoren.woerter.plural": "Aktoren", + "aufbau.aktoren.arten.erzeuger.name": "Eingang", + "aufbau.aktoren.arten.annehmer.name": "Ausgang", + "aufbau.aktoren.arten.verwerfer.name": "Abweiser", + "aufbau.aktoren.arten.befoerderer.name": "Schieber", + "aufbau.aktoren.arten.schreiber.name": "Schreiber", + "aufbau.aktoren.arten.leser.name": "Weiche", + "aufbau.aufgaben.woerter.singular": "Aufgabe", + "aufbau.aufgaben.woerter.plural": "Aufgaben", + "aufbau.aufgaben.arten.akzeptor.name": "Akzeptor", + "aufbau.aufgaben.arten.akzeptor.kuerzel": "AKZ", + "aufbau.aufgaben.arten.transduktor.name": "Transduktor", + "aufbau.aufgaben.arten.transduktor.kuerzel": "TRA", + "steuerung.auswaehlen": "Aufgabe auswählen", + "steuerung.schritt": "Nächster Schritt", + "steuerung.test": "Ablaufen", + "steuerung.anhalten": "Anhalten", + "steuerung.bearbeiten": "Bearbeiten", + "steuerung.leeren": "Leeren", + "hilfe.einleitung": "Dieses Spiel ist inspiriert von !var:manufacturia, !var:crazy_machines, !var:world_of_goo … und auch von unvergessenen Stunden Hardware-Praktikum im Informatik-Studium :P", + "hilfe.steuerung.titel": "Steuerung", + "hilfe.steuerung.eintrag1": "Links-Klick/Rechts-Klick: Feldtyp wechseln", + "hilfe.steuerung.eintrag2": "Mausrad-Drehen: Feld drehen", + "hilfe.figur.satz1": "Die Figur kann durch Aktoren auf dem Spielplan umher bewegt werden und wird als schwarzer Kreis dargestellt.", + "hilfe.figur.satz2": "Zudem verfügt die Figur über ein Liste von gesetzen Symbolen (Band), dargestellt durch farbige Punkte neben der Figur. Gelesen wird das Band immer an der vordersten Stelle und geschrieben wird an die hinterste Stelle (FIFO-Prinzip).", + "hilfe.aktoren.einleitung": "Jedes Feld des Spielplans kann mit einem Aktor bestückt werden, der je nach Typ unterschiedliche Einflüsse auf die Figur ausübt. Folgende Typen stehen zur Verfügung:", + "hilfe.aktoren.erzeuger": "Der Eingang ist fest platziert auf dem ganz linken Feld des Spielplans und wird durch ein weißes Dreieck dargestellt. An ihm wird die Spielfigur auf den Plan gesetzt und bewegt sich anschließend in die angezeigte Richtung.", + "hilfe.aktoren.annehmer": "Auf dem ganz rechten Feld des Spielplans fest platziert befindet sich der Ausgang, der durch einen weißen Kreis dargestellt wird. Steuert man die Figur zu diesem Feld, so wird der aktuelle Band-Inhalt ausgelesen und akzeptiert.", + "hilfe.aktoren.verwerfer": "Jedes leere Feld beendet den Lauf der Figur mit einer Abweisung des aktuellen Band-Inhalts.", + "hilfe.aktoren.befoerderer": "Dieser Aktor dient dazu die Figur von einem Feld zu einem benachbarten zu befördern ohne dabei den Band-Inhalt zu ändern.", + "hilfe.aktoren.schreiber": "Um ein Symbol auf das Band zu schreiben, wird dieser Aktor benötigt. Die jeweilige Farbe gibt an, welches Symbol geschrieben wird und die Richtung zeigt, wohin die Figur anschließend befördert wird.", + "hilfe.aktoren.leser": "An einer Weiche wird das erste Symbol auf dem Band der Figur gelesen und die übereinstimmende Richtung gewählt, zu welcher die Figur im Anschluss bewegt wird. Gibt es einen passenden Ausgang, so wird das gelesene Symbol vom Band entfernt. Falls kein Ausgang gefunden wird oder das Band leer ist, wird der Ersatz-Ausgang (grau) gewählt.", + "hilfe.aufgaben.einleitung": "Ziel ist das Lösen von bestimmten Aufgaben. Dabei wird zwischen zwei Arten von Aufgaben unterschieden:", + "hilfe.aufgaben.akzeptor.erklaerung": "Hierbei geht es darum den Band-Inhalt der Figur zu untersuchen und zu entscheiden, ob er eine bestimmte Bedingung erfüllt oder nicht. Fall ja, so steuert man die Figur in den Ausgang; andernfalls auf ein beliebiges leeres Feld.", + "hilfe.aufgaben.akzeptor.beispiel": "Beispiel: Genau dann akzeptieren, wenn das Band mindestens zwei mal rot enthält.", + "hilfe.aufgaben.transduktor.erklaerung": "Bei einer Transduktor-Aufgabe soll eine Ausgabe erzeugt werden, die in einer bestimmten Beziehung zur vorgefundenen Eingabe steht, also sozusagen eine Funktion angewendet werden.", + "hilfe.aufgaben.transduktor.beispiel": "Beispiel: Die Eingabe zwei mal wiederholt." + } + } +); + diff --git a/quelldatein/daten/zeichenketten/en.dat.js b/quelldatein/daten/zeichenketten/en.dat.js new file mode 100644 index 0000000..68ea6b2 --- /dev/null +++ b/quelldatein/daten/zeichenketten/en.dat.js @@ -0,0 +1,51 @@ +jsonp_behandlung( + { + "schluessel": "zeichenketten-en", + "wert": { + "allgemein.titel": "Crazy Turing Machines", + "allgemein.hilfe": "Help", + "allgemein.spiel": "Game", + "aufbau.figur.worter.singular": "token", + "aufbau.figur.worter.plural": "tokens", + "aufbau.aktoren.woerter.singular": "actor", + "aufbau.aktoren.woerter.plural": "actors", + "aufbau.aktoren.arten.erzeuger.name": "entrance", + "aufbau.aktoren.arten.annehmer.name": "exit", + "aufbau.aktoren.arten.verwerfer.name": "dropper", + "aufbau.aktoren.arten.befoerderer.name": "conveyer", + "aufbau.aktoren.arten.schreiber.name": "writer", + "aufbau.aktoren.arten.leser.name": "switch", + "aufbau.aufgaben.woerter.singular": "task", + "aufbau.aufgaben.woerter.plural": "tasks", + "aufbau.aufgaben.arten.akzeptor.name": "acceptor", + "aufbau.aufgaben.arten.akzeptor.kuerzel": "ACC", + "aufbau.aufgaben.arten.transduktor.name": "transductor", + "aufbau.aufgaben.arten.transduktor.kuerzel": "TRA", + "steuerung.auswaehlen": "choose task", + "steuerung.schritt": "next step", + "steuerung.test": "run", + "steuerung.anhalten": "stop", + "steuerung.bearbeiten": "edit", + "steuerung.leeren": "clear", + "hilfe.einleitung": "This game is inspired by !var:manufacturia, !var:crazy_machines, !var:world_of_goo … and also by memorable hours of the practical hardware course during computer science study :P", + "hilfe.steuerung.titel": "controls", + "hilfe.steuerung.eintrag1": "left click/right click: change tile type", + "hilfe.steuerung.eintrag2": "rotate mousewheel: rotate tile", + "hilfe.figur.satz1": "The token can be moved around the board by actors and it is displayed as a black circle.", + "hilfe.figur.satz2": "Additionally the token has a list of set symbols (its tape), which is shown as coloured points next to the token. The tape is always read at the front and written at its back (FIFO principle).", + "hilfe.aktoren.einleitung": "Every tile on the board can be equipped with an actor, which will cause a certain effect on the token depending on the type. The following types are available:", + "hilfe.aktoren.erzeuger": "The entrance is statically placed on the most left tile of the board and is displayed as a white triangle. It is the spot at which the token is inserted into the board and moved to the indicated direction afterwards.", + "hilfe.aktoren.annehmer": "On the most right tile of the board the exit is statically placed; it is displayed as a white circle. If the token is moved to this tile, its tape content will be read and accepted.", + "hilfe.aktoren.verwerfer": "Every empty tile will cancel the tokens run with a rejection of the current tape content.", + "hilfe.aktoren.befoerderer": "This actor is used for moving the token to neighbour tile without changing the tape content.", + "hilfe.aktoren.schreiber": "In order to write a symbol to the tape, this actor is utilized. The colour indicates which symbol will be written and the direction shows to which tile the token will be moved afterwards.", + "hilfe.aktoren.leser": "At a switch the first symbol of the tape will be read and the the token will be moved the the corresponding direction. If a matching way out exists, the symbol will be removed from the tape. If no way out matches or if the tape is empty the fallback exit (grey) will be chosen.", + "hilfe.aufgaben.einleitung": "The goal is to solve certain tasks. Two kind of tasks are distinguished:", + "hilfe.aufgaben.akzeptor.erklaerung": "Here the goal is to investigate the content of the tokens tape and to decide whether it fulfils a certain condition or not. IF so, the token shall be moved to the exit; otherwise to an arbitrary empty tile.", + "hilfe.aufgaben.akzeptor.beispiel": "Example: Accept then and only then, if the tape contains at least two red symbols.", + "hilfe.aufgaben.transduktor.erklaerung": "In a transductor task an output shall be generated, which has a certain relationship to to the input; in other words: to apply a function.", + "hilfe.aufgaben.transduktor.beispiel": "Example: The input repeated two times." + } + } +); + diff --git a/quelldatein/haupt.ts b/quelldatein/haupt.ts index f01a0f7..0a580f1 100644 --- a/quelldatein/haupt.ts +++ b/quelldatein/haupt.ts @@ -78,11 +78,91 @@ function aufgaben_eintragen(behandler : (aufgabe : mod_vtm_aufbau.schnittstelle_ */ function haupt() : void { - let aufbau : mod_vtm_aufbau.klasse_partie; - let aufgabe_laden = function (aufgabe : mod_vtm_aufbau.schnittstelle_aufgabe) : void {aufbau.aufgabe_setzen(aufgabe);}; - aufgaben_eintragen(aufgabe_laden); - aufbau = (new mod_vtm_aufbau.klasse_partie(mod_vtm_aufbau.aufgabe_holen(0))); - (new mod_vtm_manifestation.klasse_web_partie(aufbau, document.querySelector("#bereich_mitte"))).einrichten(); + // uebersetzungen + { + let sprachen : Array = navigator.languages.map(sprache => sprache); + let sprache_nativ : string = "de"; + if (! sprachen[""+"includes"](sprache_nativ)) + sprachen.push(sprache_nativ); + mod_vtm_helfer.uebersetzung_einrichten(sprachen); + mod_vtm_helfer.uebersetzung_anwenden(document); + } + // hilfe + { + // einleitung + { + document.querySelector("#hilfe_einleitung").innerHTML = ( + mod_vtm_helfer.uebersetzung_holen + ( + "hilfe.einleitung", + { + "manufacturia": "Manufacturia", + "crazy_machines": "Crazy Machines", + "world_of_goo": "World of Goo", + } + ) + ); + } + // aktoren + { + // arten + { + let von_x : float = -0.5; + let von_y : float = -0.5; + let bis_x : float = +0.5; + let bis_y : float = +0.5; + let breite : float = 80; + let hoehe : float = 80; + [ + { + "aufbau": (new mod_vtm_aufbau.klasse_erzeuger()), + "kontext": document.querySelector("#hilfe_aktoren_aktor_erzeuger"), + }, + { + "aufbau": (new mod_vtm_aufbau.klasse_annehmer()), + "kontext": document.querySelector("#hilfe_aktoren_aktor_annehmer"), + }, + { + "aufbau": (new mod_vtm_aufbau.klasse_verwerfer()), + "kontext": document.querySelector("#hilfe_aktoren_aktor_verwerfer"), + }, + { + "aufbau": (new mod_vtm_aufbau.klasse_befoerderer()), + "kontext": document.querySelector("#hilfe_aktoren_aktor_befoerderer"), + }, + { + "aufbau": (new mod_vtm_aufbau.klasse_schreiber()), + "kontext": document.querySelector("#hilfe_aktoren_aktor_schreiber"), + }, + { + "aufbau": (new mod_vtm_aufbau.klasse_leser()), + "kontext": document.querySelector("#hilfe_aktoren_aktor_leser"), + }, + ] + .forEach + ( + eintrag => + { + let manifestor = (new mod_vtm_manifestation.klasse_svg_aktor(eintrag.aufbau, mod_vtm_aufbau.stelle_null())); + let xmlknoten : mod_vtm_helfer.schnittstelle_xmlknoten = mod_vtm_manifestation.svg_wurzel(von_x, von_y, bis_x, bis_y, breite, hoehe, [manifestor.darstellen()]); + eintrag.kontext.querySelector(".hilfe_aktoren_aktor_bild").innerHTML = xmlknoten.darstellen(); + } + ) + ; + } + } + } + // spiel + { + let aufbau : mod_vtm_aufbau.klasse_partie; + aufgaben_eintragen + ( + function (aufgabe : mod_vtm_aufbau.schnittstelle_aufgabe) : void {aufbau.aufgabe_setzen(aufgabe);} + ) + ; + aufbau = (new mod_vtm_aufbau.klasse_partie(mod_vtm_aufbau.aufgabe_holen(0))); + (new mod_vtm_manifestation.klasse_web_partie(aufbau, document.querySelector("#bereich_mitte"))).einrichten(); + } } diff --git a/quelldatein/helfer/uebersetzung.ts b/quelldatein/helfer/uebersetzung.ts new file mode 100644 index 0000000..04ba40b --- /dev/null +++ b/quelldatein/helfer/uebersetzung.ts @@ -0,0 +1,172 @@ +/* + * 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_helfer + { + + /** + * @author kcf + */ + var _uebersetzung_sprachstapel : Array; + + + /** + * @author kcf + */ + export var _uebersetzung_daten : {[sprache : string] : {[schluessel : string] : string}} = {}; + + + /** + * @author kcf + */ + export function uebersetzung_einrichten(sprachen : Array) : void + { + _uebersetzung_sprachstapel = []; + sprachen.forEach + ( + sprache => + { + let zeichenketten_roh_ : schnittstelle_fehlermonade = mod_vtm_daten.lesen("zeichenketten-" + sprache); + if (zeichenketten_roh_.ist_schlicht()) + { + let zeichenketten_roh : {[schluessel : string] : string} = (<{[schluessel : string] : string}>(zeichenketten_roh_.lesen())); + _uebersetzung_daten[sprache] = {}; + for (let schluessel in zeichenketten_roh) + { + _uebersetzung_daten[sprache][schluessel] = ((zeichenketten_roh[schluessel])); + } + _uebersetzung_sprachstapel.push(sprache); + } + else + { + let meldung : string = ("Zeichenketten für Sprache '" + sprache + "' konnten nicht geladen werden"); + console.warn(meldung); + } + } + ) + ; + } + + + /** + * @author kcf + */ + function uebersetzung_lesen(sprache : string, schluessel : string) : schnittstelle_fehlermonade + { + if (sprache in _uebersetzung_daten) + { + let satz : {[schluessel : string] : string} = _uebersetzung_daten[sprache]; + if (schluessel in satz) + { + return (new klasse_schlicht(satz[schluessel])); + } + else + { + let meldung : string = ("keine Zeichenketten für Schlüssel '" + schluessel + "' in Sprache '" + sprache + "'"); + console.warn(meldung); + return (new klasse_nichts()); + } + } + else + { + let meldung : string = ("keine Zeichenketten für Sprache '" + sprache + "'"); + console.warn(meldung); + return (new klasse_nichts()); + } + } + + + /** + * @author kcf + */ + export function uebersetzung_holen(schluessel : string, vars : {[name : string] : string} = {}) : string + { + let ergebnis : schnittstelle_fehlermonade = (new klasse_nichts()); + let gefunden : boolean = ( + _uebersetzung_sprachstapel + .some + ( + sprache => + { + let ergebnis_ : schnittstelle_fehlermonade = uebersetzung_lesen(sprache, schluessel); + if (ergebnis_.ist_schlicht()) + { + ergebnis = ergebnis_; + return true; + } + else + { + return false; + } + } + ) + ); + if (gefunden) + { + let str : string = ergebnis.lesen(); + for (let name in vars) + { + let muster : RegExp = (new RegExp("!var:" + name)); + let wert : string = vars[name]; + str = str.replace(muster, wert); + } + return str; + } + else + { + return ("{" + schluessel + "}"); + } + } + + + /** + * @author kcf + */ + export function uebersetzung_anwenden(kontext : DocumentFragment) : void + { + let muster : RegExp = (new RegExp("^!translate:([a-z0-9\.]*)$")); + document.querySelectorAll("*")[""+"forEach"] + ( + element => + { + if (element.childElementCount === 0) + { + let inhalt : string = element.textContent; + let fund : any = muster.exec(inhalt); + if (fund != null) + { + let schluessel : string = fund[1]; + let inhalt_ : string = uebersetzung_holen(schluessel); + element.textContent = inhalt_; + } + else + { + // nichts tun + } + } + else + { + // nichts tun + } + } + ) + ; + } + + } + diff --git a/quelldatein/manifestation/web/partie.ts b/quelldatein/manifestation/web/partie.ts index a2fe737..348a2f0 100644 --- a/quelldatein/manifestation/web/partie.ts +++ b/quelldatein/manifestation/web/partie.ts @@ -107,6 +107,7 @@ module mod_vtm_manifestation (angaben) => { this.erneuern_modus(); + this.erneuern_knoepfe(); } ) ; @@ -302,7 +303,16 @@ module mod_vtm_manifestation { this.anhalten(); this.aufbau.zuruecksetzen(); - this.erneuern_knoepfe(); + } + + + /** + * @author kcf + */ + private leeren() : void + { + this.aufbau.welt_leeren(); + this.aufbau.zuruecksetzen(); } @@ -427,6 +437,16 @@ module mod_vtm_manifestation } ) ; + // Leeren + document.querySelector("#knopf_leeren").addEventListener + ( + "click", + event => + { + this.leeren(); + } + ) + ; } } diff --git a/quelldatein/manifestation/web/vtm.css b/quelldatein/manifestation/web/vtm.css index 7494141..b397421 100644 --- a/quelldatein/manifestation/web/vtm.css +++ b/quelldatein/manifestation/web/vtm.css @@ -32,6 +32,11 @@ a:hover color: hsl(120, 50%, 75%); } +li + { + list-style-type: "» "; + } + body > header { font-size: 200%; @@ -105,24 +110,59 @@ body > header #knoepfe.initial > #knopf_testen {} #knoepfe.initial > #knopf_anhalten {display: none;} #knoepfe.initial > #knopf_bearbeiten {display: none;} +#knoepfe.initial > #knopf_leeren {} #knoepfe.ungewiss_laufend > #knopf_schritt {display: none;} #knoepfe.ungewiss_laufend > #knopf_testen {display: none;} #knoepfe.ungewiss_laufend > #knopf_anhalten {} #knoepfe.ungewiss_laufend > #knopf_bearbeiten {display: none;} +#knoepfe.ungewiss_laufend > #knopf_leeren {display: none;} #knoepfe.ungewiss_stehend > #knopf_schritt {} #knoepfe.ungewiss_stehend > #knopf_testen {} #knoepfe.ungewiss_stehend > #knopf_anhalten {display: none;} #knoepfe.ungewiss_stehend > #knopf_bearbeiten {} +#knoepfe.ungewiss_stehend > #knopf_leeren {display: none;} #knoepfe.fertig > #knopf_schritt {display: none;} #knoepfe.fertig > #knopf_testen {display: none;} #knoepfe.fertig > #knopf_anhalten {display: none;} #knoepfe.fertig > #knopf_bearbeiten {} +#knoepfe.fertig > #knopf_leeren {display: none;} #aufgabe_status { margin-bottom: 8px; } - + + +.hilfe_aktoren_aktor + { + display: flex; + flex-direction: row; + flex-wrap: wrap; + } + +.hilfe_aktoren_aktor > .hilfe_aktoren_aktor_name + { + flex-basis: 100%; + flex-shrink: 0; + flex-grow: 1; + + text-transform: capitalize; + } + +.hilfe_aktoren_aktor > .hilfe_aktoren_aktor_bild + { + flex-basis: 10%; + flex-shrink: 1; + flex-grow: 0; + } + +.hilfe_aktoren_aktor > .hilfe_aktoren_aktor_text + { + flex-basis: 90%; + flex-shrink: 1; + flex-grow: 1; + } + diff --git a/quelldatein/manifestation/web/vtm.html b/quelldatein/manifestation/web/vtm.html index a1e2281..896a145 100644 --- a/quelldatein/manifestation/web/vtm.html +++ b/quelldatein/manifestation/web/vtm.html @@ -8,22 +8,25 @@ -
Verrückte Turing-Maschinen
- - +
!translate:allgemein.titel
+ + +
@@ -32,62 +35,68 @@
-

Dieses Spiel ist inspiriert von Manufacturia, Crazy Machines, World of Goo … und auch von unvergessenen Stunden Hardware-Praktikum im Informatik-Studium :P

-
-
Steuerung
+

+
+
!translate:hilfe.steuerung.titel
    -
  • Links-Klick/Rechts-Klick: Feldtyp wechseln
  • -
  • Mausrad-Drehen: Feld drehen
  • +
  • !translate:hilfe.steuerung.eintrag1
  • +
  • !translate:hilfe.steuerung.eintrag2
-
-
Figur
-

Die Figur kann durch Aktoren auf dem Spielplan umher bewegt werden und wird als schwarzer Kreis dargestellt.

-

Zudem verfügt die Figur über ein Liste von gesetzen Symbolen (Band), dargestellt durch farbige Punkte neben der Figur. Gelesen wird das Band immer an der vordersten Stelle und geschrieben wird an die hinterste Stelle (FIFO-Prinzip).

+
+
!translate:aufbau.figur.worter.singular
+

!translate:hilfe.figur.satz1

+

!translate:hilfe.figur.satz2

-
-
Aktoren
-

Jedes Feld des Spielplans kann mit einem Aktor bestückt werden, der je nach Typ unterschiedliche Einflüsse auf die Figur ausübt. Folgende Typen stehen zur Verfügung:

+
+
!translate:aufbau.aktoren.woerter.plural
+

!translate:hilfe.aktoren.einleitung

    -
  • -
    Erzeuger
    -

    Der Erzeuger ist fest platziert auf dem ganz linken Feld des Spielplans. An ihm wird die Spielfigur auf den Plan gesetzt und bewegt sich anschließend in die angezeigte Richtung.

    +
  • +
    !translate:aufbau.aktoren.arten.erzeuger.name
    +
    +
    !translate:hilfe.aktoren.erzeuger
  • -
  • -
    Ausgang
    -

    Ebenfalls fest platziert aber auf dem ganz rechten Feld des Spielplans wird der Ausgang. Steuert man die Figur zu diesem Feld, so wird der aktuelle Band-Inhalt ausgelesen und akzeptiert.

    +
  • +
    !translate:aufbau.aktoren.arten.annehmer.name
    +
    +
    !translate:hilfe.aktoren.annehmer
  • -
  • -
    Verwerfer
    -

    Jedes leere Feld beendet den Lauf der Figur mit einer Abweisung des aktuellen Band-Inhalts.

    +
  • +
    !translate:aufbau.aktoren.arten.verwerfer.name
    +
    +
    !translate:hilfe.aktoren.verwerfer
  • -
  • -
    Beförderer
    -

    Dieser Aktor dient dazu die Figur von einem Feld zu einem benachbarten zu befördern ohne dabei den Band-Inhalt zu ändern.

    +
  • +
    !translate:aufbau.aktoren.arten.befoerderer.name
    +
    +
    !translate:hilfe.aktoren.befoerderer
  • -
  • -
    Schreiber
    -

    Um ein Symbol auf dem Band zu schreiben, wird dieser Aktor benötigt. Die jeweilige Farbe gibt an, welches Symbol geschrieben wird und die Richtung zeigt, wohin die Figur anschließend befördert wird.

    +
  • +
    !translate:aufbau.aktoren.arten.schreiber.name
    +
    +
    !translate:hilfe.aktoren.schreiber
  • -
  • -
    Leser
    -

    Beim Leser wird das erste Symbol auf dem Band der Figur betrachtet und die übereinstimmende Richtung gewählt, zu welcher die Figur bewegt im Anschluss wird. Gibt es einen passenden Ausgang, so wird das gelesene Symbol vom Band entfernt. Falls kein Ausgang gefunden wird oder das Band leer ist, wird der Ersatz-Ausgang (grau) gewählt.

    +
  • +
    !translate:aufbau.aktoren.arten.leser.name
    +
    +
    !translate:hilfe.aktoren.leser
-
-
Aufgaben
-

Ziel ist das Lösen von bestimmten Aufgaben. Dabei wird zwischen zwei Arten von Aufgaben unterschieden:

+
+
!translate:aufbau.aufgaben.woerter.plural
+

!translate:hilfe.aufgaben.einleitung

    -
  • -
    Akzeptor
    -

    Hierbei geht es darum den Band-Inhalt der Figur zu untersuchen und zu entscheiden, ob er eine bestimmte Bedingung erfüllt oder nicht. Fall ja, so steuert man die Figur in den Ausgang; andernfalls auf ein beliebiges leeres Feld.

    -

    Beispiel: Genau dann akzeptieren, wenn das Band mindestens zwei mal rot enthält.

    +
  • +
    !translate:aufbau.aufgaben.arten.akzeptor.name
    +

    !translate:hilfe.aufgaben.akzeptor.erklaerung

    +

    !translate:hilfe.aufgaben.akzeptor.beispiel

  • -
  • -
    Transduktor
    -

    Bei einer Transduktor-Aufgabe soll eine Ausgabe erzeugt werden, die in einer bestimmten Beziehung zur vorgefundenen Eingabe steht, also sozusagen eine Funktion angewendet werden.

    -

    Beispiel: Die Eingabe zwei mal wiederholt.

    +
  • +
    !translate:aufbau.aufgaben.arten.transduktor.name
    +

    !translate:hilfe.aufgaben.transduktor.erklaerung

    +

    !translate:hilfe.aufgaben.transduktor.beispiel

diff --git a/todo.md b/todo.md index 9ce9ae4..9a27c9c 100644 --- a/todo.md +++ b/todo.md @@ -1,6 +1,5 @@ -- reset-button - automatisch zu "bearbeiten" wechseln wenn fehlerhaft -- test schrittweise ablaufen -- Tests anzeigen -- zufällige Tests +- Tests anzeigen? +- zufällige Tests? +- Drehung beibehalten? diff --git a/werkzeuge/bauen.sh b/werkzeuge/bauen.sh new file mode 100755 index 0000000..eddad46 --- /dev/null +++ b/werkzeuge/bauen.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +make +