Dagaz: Eine Persistenzgeschichte

Jede ausreichend fortschrittliche Technologie ist von Magie nicht zu unterscheiden.
Arthur Clark
 
- Ich möchte kein Vergleich mehr sein ... Mach mich zu einer Metapher.
China Mieville Die


Arbeit an einem großen Projekt ähnelt dem U-Bahn-Tauchen . Durch die Lösung bestimmter Probleme eröffnen wir neue Möglichkeiten. Mit der Zeit werden diese Möglichkeiten stärker, verbinden sich mit anderen Möglichkeiten und dies ermöglicht es uns, alte, viel wichtigere und komplexere Probleme auf eine neue, völlig unerwartete Weise zu lösen. Ich habe ein gutes Beispiel zu diesem Thema. Und ich möchte über ihn sprechen.

Das Common-Setup- Modul wurde als einfaches Debugging-Tool konzipiert. Oft ist es sehr nützlich, zu einer bestimmten Position zurückkehren zu können, um das Problem zu lokalisieren. Diese Anordnung der Figuren tritt jedoch flüchtig im Spiel auf, und ihre Restaurierung ist eine beträchtliche Arbeit wert. Ich brauchte ein Tool, um diesen Prozess zu automatisieren, und ich habe es getan. Tatsächlich kann ich jede Position leicht codieren, indem ich die Position der Teile auf der Tafel beschreibe:

Setup = 0c3; 0a2; 0c2; 0d2; 1a1; 4b1; 5c1; 1d1; -1a4; 4b4; 5c4; 1d4; 0a3; 0d3; 0b2 ;; & turn = 0

Dann kann ich diese Parameter zur URL hinzufügen, um die Position zu reproduzieren. Dies ist, was Common-Setup tut. Das Modul speichert die Beschreibung aller Zwischenpositionen im Protokoll und ermöglicht deren Reproduktion. Dies ist kein sehr perfekter Mechanismus. Zum Beispiel gibt uns eine solche Beschreibung nichts, wenn wir nicht wissen, zu welchem ​​Spiel sie gehört. Es gibt andere Mängel, die ich später diskutieren werde. Jetzt ist es Zeit, den nächsten Teilnehmer unserer Geschichte zu treffen.


Die Progressive-Level-Option kam von Zillions of Games und ich habe lange nicht verstanden, warum sie benötigt wurde. Versuchen Sie, alle Lampen auszuschalten (es ist einfach) und Sie werden verstehen, wovon ich spreche. Nachdem der Spieler gewonnen hat, sieht Progressive Levels die aktuelle URL an und erhöht sie um eins, wenn er eine Zahl darin findet. In der Tat ist dies eine großartige Möglichkeit, den Spieler zu engagieren, aber seine Fähigkeiten sind nicht darauf beschränkt. Es gibt Spiele, die aus mehreren Runden bestehen. Nach Abschluss eines Spiels verteilen die Spieler nach bestimmten Regeln die Teile neu und beginnen erneut zu spielen.


Dieser Ansatz wird häufig in afrikanischem Mankali praktiziert . In Ovalhu zum Beispiel beginnt das Spiel nicht einfach von vorne . Die Spieler verwenden die in der vorherigen Runde erbeuteten Körner, um zunächst ihre Löcher zu füllen. Löcher, die nicht gefüllt wurden, gelten als aus dem Spiel entfernt und können nicht verwendet werden. Tatsächlich wird in jeder Runde ein neues Spiel auf einem neuen Brett gespielt. Erst wenn der Verlierer in der nächsten Runde nicht mindestens ein Loch füllen kann, wird seine endgültige Niederlage erkannt.

Diese Möglichkeit kann viel weiter verstanden werden.

, . common-setup . , , , . , .


, . «» , . , "Magyar Dama" ( , «»), Hive, , . , , , , , .


( , roguelike-). «», seed, . , ( ). (, ), .


, , . . "", , , , .

Der nächste Schritt wurde fast zufällig gemacht. In meinen Spielen ist Ton. Ich mag ihn wirklich, aber es gibt wahrscheinlich Menschen auf der Welt, die er nervt. Für sie war es möglich, es auszuschalten. Es scheint, dass dies gut funktioniert hat, aber die Einstellungen wurden nirgendwo gespeichert und nach jeder Seitenaktualisierung musste der Ton wieder ausgeschaltet werden (und das ärgerte noch mehr). Ich wurde gebeten, dieses Problem irgendwie zu beheben, und die erste Lösung, die mir in den Sinn kam, war ein Cookie (die erste Lösung ist nicht immer erfolgreich).

So sah es aus
Dagaz.Controller.sound = function() {
    if (Dagaz.Controller.soundOff) {
        sound.innerHTML = "no Sound";
        Dagaz.Controller.soundOff = false;
        document.cookie = "dagaz.sound=on";
    } else {
        sound.innerHTML = "Sound";
        Dagaz.Controller.soundOff = true;
        document.cookie = "dagaz.sound=off";
    }
}

Ich wollte keinen Müll wegwerfen, daher waren die Cookies nur von kurzer Dauer, bis das Browserfenster geschlossen wurde. Und dann dachte ich: "Warum nicht lehren, Common-Setup auch in Cookies zu speichern?" Ich musste den Max-Age- Parameter einstellen , aber es hat sich gelohnt. Erstens wurde der Status des Spiels jetzt gespeichert, als das Fenster versehentlich geschlossen wurde. Als Bonus hat das Umschalten des Spielmodus mit dem AI / no AI-Bot das Spiel ebenfalls nicht zurückgesetzt. Das war großartig!

Natürlich musste ich für etwas anderes sorgen
, , , , cookie ( ). «New game», . . , common-setup , ? cookie ( , ).

-
var getName = function() {
  var str = window.location.pathname.toString();
  var result = str.match(/\/([^.\/]+)\./);
  if (result) {
      return result[1].replace("-board", "").replace("-ai", "");
  } else {
      return str;
  }
}

var badName = function(str) {
  var result = str.match(/[?&]game=([^&*]*)/);
  if (result) {
      return result[1] != getName();
  } else {
      return true;
  }
}

var getCookie = function() {
  var str = document.cookie;
  var result = str.match(/dagaz\.(setup=[^*]*)/);
  if (result) {
      var r = decodeURIComponent(result[1]);
      if (badName(r)) return "";
      return "?" + r;
  } else {
      return "";
  }
}

var getSetup = function() {
  var str = window.location.search.toString();
  var result = str.match(/[?&]setup=([^&]*)/);
  if (result) {
      return result[1];
  } else {
      str = getCookie();
      result = str.match(/[?&]setup=([^&]*)/);
      if (result) {
          return result[1];
      } else {
          return "";
      }
  }
}

Dagaz.Model.getSetup = function(design, board) {
  var str = "";
  ...
  str = str + ";&turn=" + board.turn;
  if (Dagaz.Controller.persistense == "setup") {
      var s = str + "&game=" + getName() + "*";
      var maxage = getMaxage();
      if (maxage) {
        document.cookie = "dagaz.setup=" + encodeURIComponent(s) + "; max-age=" + maxage;
      } else {
        document.cookie = "dagaz.setup=" + encodeURIComponent(s);
      }
  }
  return "?setup=" + str;
}

, . , ( Pasang Chaturanji) , , , (Morris, Bolotoudou) common-setup , . , !


. ( , ). , Stratego Luzhanqi, ( ). (common-setup, , ), …


, , , common-setup , . ( Mana, , ), , .

, , . , random, c seed , , , - . , seed cookie, , , , .

Leider gibt es Spiele, für die die Methode zum Speichern des Status durch das Common-Setup-Modul nicht geeignet ist. Im oben erwähnten Kamisado hängt die Fähigkeit, einen Zug abzuschließen (für alle Züge außer dem allerersten), davon ab, in welchem ​​Feld der vorherige Zug ausgeführt wurde. Es gibt Spiele mit noch komplexerer Mechanik:


In der Mühle gibt es zusätzlich zu den üblichen Zügen Bonuszüge. Wenn ein Spieler seine drei Teile hintereinander angeordnet hat, hat er das Recht, die Teile eines Gegners vom Brett zu entfernen. Darüber hinaus verbieten die Regeln, zweimal hintereinander dasselbe Triplett zu bauen. All dies bedeutet, dass Sie den Verlauf früherer Züge speichern müssen, damit das Spiel ordnungsgemäß funktioniert. Zum Glück gibt es eine solche Gelegenheit.

Das Session-Manager- Modul speichert den Spielverlauf und ermöglicht es dem Spieler, einen oder mehrere Züge zurückzugehen und möglicherweise einen weiteren Zug auszuführen. Außerdem ist diesem Berater die Advisor-Option zugeordnet, die dem Spieler einen möglichen Zug beim Spielen mit dem Bot mitteilt. Rückblickend scheint die Idee, die Geschichte des Spiels in Cookies zu speichern, offensichtlich, aber ich bin nicht sofort darauf gekommen.

Das Korrespondenzspiel erschien zuerst
Dagaz . - , "Zillions of Games", 1998 . 2003 Zillions , , . Ed van Zon . "MindSports", .


MindSports Dagaz . Ed , Java-, , , . , Ed Dagaz, .

, , , , . , Dagaz, , - backend-, JavaScript- . Ed session-manager, . , , , , , , ( , ), , .

SGF , , session-manager , SGF . , , , , SGF ( , ). , MindSports, , 80 Dagaz .

Der nächste Schritt war ziemlich offensichtlich - ich fing an, die SGF- Beschreibung der Parteien in Cookies zu speichern , und dann sagten sie mir, dass es nicht sehr modern sei und ich alles auf localStorage verschoben habe (dies vereinfachte den Code und löste einige Debugging-Probleme in Google Chrome). An dieser Stelle kann der Leser eine Frage haben. Ich habe zwei Mechanismen für den gleichen Zweck, und einer von ihnen ist perfekter als der andere. Warum nicht alle Spiele auf Sitzungspersistenz umstellen ? Das ist leider nicht so einfach.

Es gibt ganze Spielefamilien, für die das Speichern von Sitzungen nicht gilt:

  1. (Shatranj, Sittuyin, Janggi, Stratego, Luzhanqi, Banqi )
  2. , session-manager (Ur, Puluc, Shen, Backgammon, Chaturaji )
  3. (Kamisado, Washington, Ohvalhu)
  4. Schließlich gibt es Spiele, in denen die Persistenz von Sitzungsmanagern aus Leistungsgründen nicht verwendet werden kann (seltsamerweise gibt es in Fanorona bei aller scheinbaren Einfachheit zu Beginn des Spiels eine große Anzahl möglicher Debüts, die sich auf die Besonderheiten der Aufnahme beziehen in diesem Spiel)

Im Allgemeinen habe ich zwei Mechanismen, die im Allgemeinen für denselben ausgelegt sind. Und das ist großartig, denn ich kann wählen, welche ich bewerben möchte.

All Articles