# HG changeset patch # User Oleksandr Gavenko # Date 1410349768 -10800 # Node ID a18fc2601ce8a4ffabe651ace68c80e8808e4727 # Parent 3d56325d7002a28aae34951638aa722c74197901 Add blind eight random AI. diff -r 3d56325d7002 -r a18fc2601ce8 2048.html --- a/2048.html Wed Sep 10 13:26:10 2014 +0300 +++ b/2048.html Wed Sep 10 14:49:28 2014 +0300 @@ -73,6 +73,14 @@ display: inline-block; float: left; margin: 1px 4px; + padding: 2px; + border: 1px solid tan; + border-radius: 4px; + } + div.ai > div.option > input.int { + text-align: right; + max-width: 4em; + margin-rght: 2px; } .clearfix { clear: both; @@ -148,6 +156,23 @@
bling random
+
+ +
bling weight random
+
+ left weight +
+
+ right weight +
+
+ up weight +
+
+ down weight +
+
+
blind cycle
@@ -481,6 +506,14 @@ "ai-blind-random": function() { return new ai.blindRandom(ui.brdEngine); }, + "ai-blind-weight-random": function(aiDom) { + var cfg = {}; + cfg.left = aiDom.querySelectorAll("input[name='left']")[0].value; + cfg.right = aiDom.querySelectorAll("input[name='right']")[0].value; + cfg.up = aiDom.querySelectorAll("input[name='up']")[0].value; + cfg.down = aiDom.querySelectorAll("input[name='down']")[0].value; + return new ai.blindWeightRandom(ui.brdEngine); + }, "ai-blind-cycle": function(aiDom) { var cfg = {}; cfg.clockwise = aiDom.querySelectorAll("input[name='clockwise']")[0].checked; diff -r 3d56325d7002 -r a18fc2601ce8 ai.js --- a/ai.js Wed Sep 10 13:26:10 2014 +0300 +++ b/ai.js Wed Sep 10 14:49:28 2014 +0300 @@ -1,8 +1,8 @@ "use strict"; var ai = {}; -ai.dirs = ["up", "down", "left", "right"]; -ai.canDirs = ["canUp", "canDown", "canLeft", "canRight"]; +ai.dirs = ["up", "right", "down", "left"]; +ai.canDirs = ["canUp", "canRight", "canDown", "canLeft"]; // 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. @@ -10,7 +10,7 @@ //////////////////////////////////////////////////////////////// -// Random AI. +// Blind random AI. //////////////////////////////////////////////////////////////// ai.blindRandom = function(brdEngine) { @@ -20,8 +20,8 @@ var origBrd = new this.brdEngine(brd); while (true) { var rnd = Math.floor(Math.random()*4); - if (origBrd[["canUp", "canDown", "canLeft", "canRight"][rnd]]()) - return ["up", "down", "left", "right"][rnd]; + if (origBrd[ai.canDirs[rnd]]()) + return ai.dirs[rnd]; } } /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */ @@ -30,6 +30,49 @@ //////////////////////////////////////////////////////////////// +// Blind weight random AI. +//////////////////////////////////////////////////////////////// + +ai.blindWeightRandom = function(brdEngine, cfg) { + this.brdEngine = brdEngine; + this.cfg = this.cfg || {}; + var left = ai.blindWeightRandom.fixWeight(this.cfg.left); + var right = ai.blindWeightRandom.fixWeight(this.cfg.right); + var up = ai.blindWeightRandom.fixWeight(this.cfg.up); + var down = ai.blindWeightRandom.fixWeight(this.cfg.down); + var total = left + right + up + down; + this.threshold1 = left/total; + this.threshold2 = (left+down)/total; + this.threshold3 = (left+down+right)/total; +} +ai.blindWeightRandom.fixWeight = function(val) { + val = val && parseFloat(v) || 1; + if (val <= 0) + val = 1; + return val; +} +ai.blindWeightRandom.prototype.analyse = function(brd) { + var origBrd = new this.brdEngine(brd); + while (true) { + var rnd = Math.random(); + if (rnd < this.threshold1) + var dir = 0; + else if (rnd < this.threshold2) + var dir = 1; + else if (rnd < this.threshold3) + var dir = 2; + else + var dir = 3; + if (origBrd[ai.canDirs[dir]]()) + return ai.dirs[dir]; + } +} +/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */ +ai.blindWeightRandom.prototype.cleanup = function() { } + + + +//////////////////////////////////////////////////////////////// // Blind cycle AI. ////////////////////////////////////////////////////////////////