达加兹:持久性故事

任何足够先进的技术都无法与魔术区分开。
亚瑟·克拉克
 
Arthur Clark)-我不想再作比较...让我成为一个比喻。
中国Mieville


从事大型项目的工作地铁潜水相似。解决特定问题,我们开辟了新的机会。随着时间的流逝,这些机会将变得越来越强大,并与其他机会联系在一起,这使我们能够以全新的,完全出乎意料的方式解决旧的,更为重要的复杂问题。我有一个很好的例子。我想谈谈他。

common-setup 模块被认为是一种简单的调试工具。通常,能够返回到特定位置以定位问题非常有用。但是这种数字排列方式是在游戏中短暂出现的,其恢复值得进行大量工作。我需要一个工具来自动执行此过程,并且做到了。实际上,我可以通过描述棋子在板上的位置来轻松编码任何位置:

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

然后,我可以将这些参数添加到url中以重现位置。这是通用设置的作用。该模块将所有中间位置的描述保存在日志中,并可以重现它们。这不是一个非常完善的机制。例如,如果我们不知道它属于哪个游戏,那么这种描述就不会给我们任何东西。还有其他缺点,我将在后面讨论。现在,是时候见见我们故事中的下一位参与者了。


渐进级别选项来自Zillions of Games,而且很长一段时间我都不明白为什么需要它。尝试关闭所有灯泡(很简单),您将了解我在说什么。玩家获胜后,渐进级别将查看当前网址,如果他在其中找到一个数字,则将其增加一个。实际上,这是一种吸引玩家的好方法,但他的能力不限于此。有几轮比赛。完成一项比赛后,玩家将按照某些规则重新分配棋子并重新开始比赛。


这种方法通常在非洲mankali中使用例如,Ovalhu,游戏不仅会重新开始。玩家使用在上一轮中捕获的谷物来初始填充其孔。未能填补的漏洞将被视为退出游戏;无法使用。实际上,在每个回合中,都会在新板上玩新游戏。只有当下一轮的失败者无法填补至少一个洞时,他的最终失败才被认可。

这个机会可以被广泛理解。

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


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


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


, , . . "", , , , .

下一步几乎是偶然地采取的。我的游戏中有声音。我真的很喜欢他,但世界上可能有人讨厌他。对他们来说,有可能将其关闭。看起来效果很好,但是设置没有保存到任何地方,每次刷新页面后,声音都不得不再次关闭(这更加令人讨厌)。我被要求以某种方式解决此问题,我想到的第一个解决方案是cookie(第一个解决方案并不总是成功的)。

这是它的样子
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";
    }
}

我不想乱扔垃圾,因此Cookie的寿命很短,直到关闭浏览器窗口为止。然后我想:“为什么不也教通用设置存储在cookie中呢?” 我必须设置max-age参数,但这是值得的。首先,当窗口意外关闭时,现在保存了游戏状态。作为奖励,使用AI切换游戏模式/没有AI机器人也不会重置游戏。那很棒!

当然,我必须提供其他东西
, , , , 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, , , , .

不幸的是,有些游戏不适用于通过通用设置模块保存状态的方法。上面提到的Kamisado,完成移动的能力(对于除第一个移动之外的所有移动)都取决于上一个移动完成的字段。有些游戏的机制更为复杂:


磨坊中,除了通常的动作之外,还有一些额外的动作-如果玩家连续排列三张棋子,则他有权从董事会中删除一个对手的棋子。此外,规则禁止连续两次构建相同的三元组。所有这些意味着要使游戏正常运行,您必须保存以前的移动历史。幸运的是,有这样的机会。会话管理器

模块保存了游戏的历史记录,允许玩家后退一个或多个动作,并可能执行另一个动作。而且,顾问程序选项与此机制相关联,该机制告诉玩家与机器人一起玩时可能的举动。回想起来,用cookie保存游戏历史的想法似乎很明显,但我并没有马上想到。

对应游戏首次出现
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 .

下一步非常明显-我开始将各方SGF-描述保存在cookie中,然后他们告诉我这不是很现代,我将所有内容都移到了localStorage(这简化了代码并解决了Google Chrome中的一些调试问题)。在这一点上,读者可能有一个问题。我有两种用于相同目的的机制,其中一种机制比另一种机制更完善。为什么不将所有游戏切换为会话持久性?不幸的是,这不是那么简单。

在整个游戏系列中,保存会话不适用:

  1. (Shatranj, Sittuyin, Janggi, Stratego, Luzhanqi, Banqi )
  2. , session-manager (Ur, Puluc, Shen, Backgammon, Chaturaji )
  3. (Kamisado, Washington, Ohvalhu)
  4. 最后,出于性能原因,有些游戏无法使用会话管理器的持久性(在游戏开发之初,在Fanorona中,由于其明显的简单性,这很奇怪,存在很多与拍摄细节相关的处女作)在这个游戏中)

总的来说,我为相同的目的设计了两种机制。这很棒,因为我可以选择要应用的那个。

All Articles