# HG changeset patch # User Oleksandr Gavenko # Date 1410280664 -10800 # Node ID 8f96d09a4d9438bcb3f9982d7e087e8f2b8ef192 # Parent fba85224a8f0bdef0a636130b69159c7b9c90254 Add Blind cycle AI. Add example of setting passing. diff -r fba85224a8f0 -r 8f96d09a4d94 2048.html --- a/2048.html Tue Sep 09 18:45:26 2014 +0300 +++ b/2048.html Tue Sep 09 19:37:44 2014 +0300 @@ -11,6 +11,9 @@ @@ -103,9 +114,16 @@
bling random
-
+
-
next merge makes max score
+
blind cycle
+
+ clockwise +
+
+ max move in one direction +
+
@@ -381,6 +399,12 @@ "ai-random": function() { return new ai.random(ui.brdEngine); }, + "ai-blind-cycle": function(aiDom) { + var cfg = {}; + cfg.clockwise = aiDom.querySelectorAll("input[name='clockwise']")[0].checked; + cfg.whilePossible = aiDom.querySelectorAll("input[name='whilePossible']")[0].checked; + return new ai.blindCycle(ui.brdEngine, cfg); + }, "ai-next-max-score": function() { return new ai.nextMaxScore(ui.brdEngine); }, @@ -419,9 +443,8 @@ ui.ai.enable = function(aiDom) { if (ui.ai.current) ui.ai.current.cleanup(); - var ai = ui.ai.algList[aiDom.id]; ui.ai.moveToTop(aiDom); - ui.ai.current = ai(); + ui.ai.current = ui.ai.algList[aiDom.id](aiDom); } ui.brdEngine = BoardArr2d; // TODO make user selectable diff -r fba85224a8f0 -r 8f96d09a4d94 ai.js --- a/ai.js Tue Sep 09 18:45:26 2014 +0300 +++ b/ai.js Tue Sep 09 19:37:44 2014 +0300 @@ -2,6 +2,7 @@ var ai = {}; ai.dirs = ["up", "down", "left", "right"]; +ai.canDirs = ["canUp", "canDown", "canLeft", "canRight"]; // Each strategy is a function that except current board position as 2d array and context from // previous call to share state/precomputed values between calls. @@ -29,6 +30,43 @@ //////////////////////////////////////////////////////////////// +// Blind cycle AI. +//////////////////////////////////////////////////////////////// + +ai.blindCycle = function(brdEngine, cfg) { + this.brdEngine = brdEngine; + this.cfg = cfg || {}; + this.cfg.untilPossible = this.cfg.untilPossible || false; + this.cfg.clockwise = this.cfg.clockwise || false; +} +ai.blindCycle.dirs = ["left", "down", "right", "up"]; +ai.blindCycle.canDirs = ["canLeft", "canDown", "canRight", "canUp"]; +ai.blindCycle.prototype.nextDir = function(dir) { + if (this.cfg.clockwise) + return (dir + (4-1)) % 4; + else + return (dir + 1) % 4; +} +ai.blindCycle.prototype.analyse = function(brd) { + var origBrd = new this.brdEngine(brd); + this.prevDir = this.prevDir || 0; + if (!this.cfg.untilPossible) + this.prevDir = this.nextDir(this.prevDir); + console.log(this.prevDir); + while (true) { + if (origBrd[ai.blindCycle.canDirs[this.prevDir]]()) + return ai.blindCycle.dirs[this.prevDir]; + this.prevDir = this.nextDir(this.prevDir); + } +} +/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */ +ai.blindCycle.prototype.cleanup = function() { + delete this.prevDir; +} + + + +//////////////////////////////////////////////////////////////// // 1 level deep on max scores. ////////////////////////////////////////////////////////////////