Code: Select all
var g = [
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,-1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,1,-1,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0]
];
console.log("Position :");
console.log (toStringBW(g).toUpperCase());
console.log("\nProximity");
console.log (toStringBW(prox(g),g));
console.log("\nZorbist (4 iterations) :");
console.log (toStringBW(zorbist(g),g));
console.log("\nBouzy (5 dilations then 21 erosions)");
console.log (toStringBW(bouzy(g,5,21),g));
console.log("\nBouzy (4 dilations then 13 erosions)");
console.log (toStringBW(bouzy(g,4,13),g));
function prox(p) {
a = init(p,50);
var size_y = a.length;
var size_x = a[0].length;
var r = [];
for (var y = 0;y < size_y; y ++) {
r[y] = [];
for (var x = 0;x < size_x; x ++) {
var onBoardNearPos = keepPositionsOnBoardOnly(size_x, size_y,near(x,y,1));
var score = a[y][x];
for (var i = 0;i < onBoardNearPos.length ; i++) {
var pos = onBoardNearPos[i];
if ( a[pos.y][pos.x] > 0) {
score ++;
} else if ( a[pos.y][pos.x] < 0) {
score --;
}
}
r[y][x] = score;
}
}
return r;
}
function zorbist(a) {
var r = init(g,50);
var nbIteration = 4;
for (var i = 0;i< nbIteration;i++) {
r = z(r);
}
return r;
}
/*
* Compute an "array" of score for a game position
*/
function z(a) {
var size_y = a.length;
var size_x = a[0].length;
var r = [];
for (var y = 0;y < size_y; y ++) {
r[y] = [];
for (var x = 0;x < size_x; x ++) {
var top = {pos:"top", x : x, y : y-1};
var bottom = {pos:"bottom", x : x, y : y+1};
var left = {pos:"left", x : x-1, y : y};
var right = {pos:"right", x : x+1, y : y};
var onBoardNearPos = keepPositionsOnBoardOnly(size_x, size_y,[top,bottom,left,right]);
var score = a[y][x];
for (var i = 0;i < onBoardNearPos.length ; i++) {
var pos = onBoardNearPos[i];
if ( a[pos.y][pos.x] > 0) {
score ++;
} else if ( a[pos.y][pos.x] < 0) {
score --;
}
}
r[y][x] = score;
}
}
return r;
}
/* Taken from : http://www.delorie.com/gnu/docs/gnugo/gnugo_201.html
The algorithm is just : 5 dilations, then 21 erosions.
*/
function bouzy(a,nbDilations, nbErosions) {
var r = init(a,128);
for (var d = 0;d< nbDilations; d++) {
r = dilation(r);
}
for (var e = 0;e< nbErosions; e++) {
r = erosion(r);
}
return r;
}
/*
dilation :
--------
for each intersection of the goban,
if the intersection is >= 0, and not adjacent to a < 0 one, then
add to the intersection the number of adjacent >0 intersections.
The same for other color :
if the intersection is <= 0, and not adjacent to a > 0 one, then
subtract the number of < 0 intersections.
*/
function dilation(a) {
var size_y = a.length;
var size_x = a[0].length;
var r = [];
for (var y = 0;y < size_y; y ++) {
r[y] = [];
for (var x = 0;x < size_x; x ++) {
var intersection = a[y][x];
var adj = keepPositionsOnBoardOnly(size_x, size_y, adjacent(x,y));
var adjacentGreaterThanZero = 0;
var adjacentLessThanZero = 0;
for (var i = 0; i<adj.length;i++) {
var posToCheck = a[adj[i].y][adj[i].x];
if (posToCheck < 0) {
adjacentLessThanZero++;
} else if (posToCheck > 0) {
adjacentGreaterThanZero++ ;
}
}
var isAdjacentToLessThanZero = (adjacentLessThanZero > 0);
var isAdjacentToGreaterThanZero = (adjacentGreaterThanZero > 0);
if ((intersection >= 0) && (! isAdjacentToLessThanZero)) {
intersection += adjacentGreaterThanZero;
} else if ((intersection >= 0) && (! isAdjacentToGreaterThanZero)) {
//intersection += adjacentLessThanZero;
intersection -= adjacentLessThanZero; // FIXED... was bugged
}
r[y][x] = intersection;
}
}
return r;
}
/*
erosion :
-------
for each intersection > 0 (or < 0), subtract (or add) the number of adjacent <= 0 (or >= 0) intersection.
Stop at zero.
*/
function erosion(a) {
var size_y = a.length;
var size_x = a[0].length;
var r = [];
for (var y = 0;y < size_y; y ++) {
r[y] = [];
for (var x = 0;x < size_x; x ++) {
var intersection = a[y][x];
var adj = keepPositionsOnBoardOnly(size_x, size_y, adjacent(x,y));
var adjacentLessOrEqualsToZero = 0;
var adjacentGreaterorEqualsToZero = 0;
for (var i = 0; i<adj.length;i++) {
var posToCheck = a[adj[i].y][adj[i].x];
if (posToCheck <= 0) {
adjacentLessOrEqualsToZero++;
} else if (posToCheck >= 0) {
adjacentGreaterorEqualsToZero++ ;
}
}
if (intersection > 0) {
intersection = intersection - adjacentLessOrEqualsToZero;
if (intersection < 0) {
intersection = 0;
}
} else if (intersection < 0) {
intersection = intersection + adjacentGreaterorEqualsToZero;
}
r[y][x] = intersection;
}
}
return r;
}
/*
*
*/
function init(a,v) {
var size_y = a.length;
var size_x = a[0].length;
var r = [];
for (var y = 0;y < size_y; y ++) {
r[y] = [];
for (var x = 0;x < size_x; x ++) {
r[y][x] = g[y][x] * v;
}
}
return r;
}
function keepPositionsOnBoardOnly(size_x, size_y, a) {
var r = [];
for (var i = 0;i < a.length ; i++) {
var x = a[i].x;
var y = a[i].y;
if ((x >= 0) && (y>=0) && (x < size_x) && (y < size_y)) {
r.push(a[i]);
}
}
return r;
}
function near (x, y, distance) {
var r = [];
for (var _y = y-distance; _y<= y+distance ; _y++ ){
for (var _x = x-distance; _x<= x+distance ; _x++ ){
r.push({x:_x, y:_y});
}
}
return r;
}
function adjacent(x,y) {
var top = {pos:"top", x : x, y : y-1};
var bottom = {pos:"bottom", x : x, y : y+1};
var left = {pos:"left", x : x-1, y : y};
var right = {pos:"right", x : x+1, y : y};
return [top,bottom,left,right];
}
/*
* a few rendering functions...
*/
function centerString ( str, width ) {
var padding = " ";
padding = padding.substr( 0, 1 );
if( str.length < width ) {
var len = width - str.length;
var remain = ( len % 2 === 0 ) ? "" : padding;
var pads="";
for (var i = 0;i < parseInt( len / 2 , 10);i++){
pads = pads + padding;
}
return pads + str + pads + remain;
} else {
return str;
}
}
function toStringNum(a) {
var size_y = a.length;
var size_x = a[0].length;
var r = "";
for (var y = 0; y < size_y; y ++) {
for (var x = 0; x < size_x; x ++) {
var v = a[y][x].toString();
r += centerString(v,5);
}
r +="\n";
}
return "\n"+r;
}
function toStringBW(a,g) {
var size_y = a.length;
var size_x = a[0].length;
var r = "";
for (var y = 0; y < size_y; y ++) {
for (var x = 0; x < size_x; x ++) {
var v = a[y][x];
if (v > 0) {
if (g && (g[y][x] == 1)) {
r +="X ";
} else {
r +="x ";
}
} else if (v < 0){
if (g && (g[y][x] == -1)) {
r +="O ";
} else {
r +="o ";
}
} else {
r +=". ";
}
}
r +="\n";
}
return "\n"+r;
}