Page 4 of 5

Re: Game moves statistics, any program for that ?

Posted: Mon May 19, 2014 4:36 am
by Uberdude
Correct oca

Re: Game moves statistics, any program for that ?

Posted: Mon May 19, 2014 7:42 am
by Bill Spight
oca wrote:Current version of the program tells me that :

Code: Select all

MOVE : 9, ["Nobi","Peep","Shoulder hit"]
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
  +--------------------------------------+
0 |. . . . . . . . . . . . . . . . . . . |
1 |. . . . . . . . . . . . . . . . . . . |
2 |. . . . . . . . . . . . . . . . . . . |
3 |. . . X . . . . . X . . . X . X . . . |
4 |. . . . . . . . . . . . . . . . X . . |
5 |. . . . . . . . . . . . . . . O O . . |
6 |. . . . . . . . . . . . . . . . . . . |
7 |. . . . . . . . . . . . . . . . X . . |
8 |. . . . . . . . . . . . . . . . .(O). |
9 |. . . X . . . . . X . . . . . X X O . |
0 |. . . . . . . . . . . . . . . . . O . |
1 |. . . . . . . . . . . . . . . . . . . |
2 |. . . . . . . . . . . . . . . . . . . |
3 |. . . . . . . . . . . . . . . . . . . |
4 |. . . . . . . . . . . . . . . . . . . |
5 |. . . X . . . . . X . . . . . X . . . |
6 |. . . . . . . . . . . . . . . . . . . |
7 |. . . . . . . . . . . . . . . . . . . |
8 |. . . . . . . . . . . . . . . . . . . |
  +--------------------------------------+

"Nobi" -> ok
"Peep" -> ok
but "Shoulder hit"... is this a shoulder hit ? from below :-?


"Crawl" :)

Re: Game moves statistics, any program for that ?

Posted: Mon May 19, 2014 2:14 pm
by Uberdude
Uberdude wrote:A shoulder hit is only from above: the hitter must be nearer the centre than the hitee so you can't use pure local pattern matching. It's normal for it to be 4th line hitting 3rd but not necessary. Also both stones should be single stones with 4 liberties.


Actually maybe just single stones with fewer liberties are ok too: if you play diagonally above a stone on the edge with 3 liberties, or 2-2 to a 1-1 stone with 2 liberties perhaps that can be called a shoulder hit too, though it's so strange to have 1st line stones like that it's unlikely to ever happen in a real game.

Re: Game moves statistics, any program for that ?

Posted: Tue May 20, 2014 3:07 am
by oca
Hi,
What would you say about this one, "empty triangle" or "connection" or both... (or something else)

Code: Select all

MOVE : 76, []
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
  +--------------------------------------+
0 |. . . O . . . O . . . . . . . . . . . |
1 |. X O . . . O . O X . . O X . . . . . |
2 |. . X O O O X O X X . O . X . . . . . |
3 |. . X X . . X X . X . . . X . X . . . |
4 |. . . . . . . . . . . O . . . . X . . |
5 |. . . . . . . . . . O . . . X O O X . |
6 |. . X . . . . . . . . . . . O . . . . |
7 |. . . . . . . . . . . . . . O X X X . |
8 |. . . . . . . . . . . . . . . O O O . |
9 |. . . X . . . . . X . . . . . X X O . |
0 |. . . . . . . . . . . . . . . . . O . |
1 |. . . . . . . . . . . . . . . . . . . |
2 |. O . . . . . . . . . . . . . . . . . |
3 |. . O . X . . . . . . . . . . . X . . |
4 |. O X . . . . O . O . . . . . . . . . |
5 |. .(X)X X . . X O X . . . . X X X . . |
6 |. . O O X . . X O X . . . O X O O . . |
7 |. . . . X . . X O . . . O . O X X . . |
8 |. . . . . . . . . . . . . O . . . . . |
  +--------------------------------------+

Re: Game moves statistics, any program for that ?

Posted: Tue May 20, 2014 4:47 am
by RBerenguel
Empty triangle. Wouldn't say connection because there was no threat to cut, but this is a little wavy to do programatically anyway

Re: Game moves statistics, any program for that ?

Posted: Tue May 20, 2014 5:03 am
by Dusk Eagle
A simple heuristic would be that this shape is an empty triangle, and not a connection. The kosumi was already connected.

Code: Select all

 X .
(X)X

Re: Game moves statistics, any program for that ?

Posted: Tue May 20, 2014 9:46 am
by Bill Spight
oca wrote:Hi,
What would you say about this one, "empty triangle" or "connection" or both... (or something else)

Code: Select all

MOVE : 76, []
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
  +--------------------------------------+
0 |. . . O . . . O . . . . . . . . . . . |
1 |. X O . . . O . O X . . O X . . . . . |
2 |. . X O O O X O X X . O . X . . . . . |
3 |. . X X . . X X . X . . . X . X . . . |
4 |. . . . . . . . . . . O . . . . X . . |
5 |. . . . . . . . . . O . . . X O O X . |
6 |. . X . . . . . . . . . . . O . . . . |
7 |. . . . . . . . . . . . . . O X X X . |
8 |. . . . . . . . . . . . . . . O O O . |
9 |. . . X . . . . . X . . . . . X X O . |
0 |. . . . . . . . . . . . . . . . . O . |
1 |. . . . . . . . . . . . . . . . . . . |
2 |. O . . . . . . . . . . . . . . . . . |
3 |. . O . X . . . . . . . . . . . X . . |
4 |. O X . . . . O . O . . . . . . . . . |
5 |. .(X)X X . . X O X . . . . X X X . . |
6 |. . O O X . . X O X . . . O X O O . . |
7 |. . . . X . . X O . . . O . O X X . . |
8 |. . . . . . . . . . . . . O . . . . . |
  +--------------------------------------+


It's guzumi (see http://senseis.xmp.net/?Guzumi ). Specifically, a good empty triangle. :)

Re: Game moves statistics, any program for that ?

Posted: Tue May 20, 2014 11:15 am
by RBerenguel
Oh, right. Threatens a neat cut at that, but this seems hard to analyse automatically ;)

Re: Game moves statistics, any program for that ?

Posted: Wed May 21, 2014 1:19 am
by oca
Bill Spight wrote:It's guzumi (see http://senseis.xmp.net/?Guzumi ). Specifically, a good empty triangle. :)

RBerenguel wrote:Oh, right. Threatens a neat cut at that, but this seems hard to analyse automatically ;)


Oh guzumi, thank you Bill... and yes... that seems very difficult for me to analyse it automatically...
Even Nobi was more complex then excpeted... my first try found "Nobi" moves everywhere....

Current version of Nobi is slightly becoming "une usine à gaz" like we say in french (a "gas factory" ? do we say that in english ? or is it "white elephant" ???) anyway here is the code for whose who may be interested...

Code: Select all


Nobi :
====
   var pattern = [
   "oo?",
   "X1o",
   "oo?"];

   var patternFirstLine = [
   "X1",
   "oo"];
   
   var matching = p.getMatchingPositions(patternFirstLine, stone, game );
   for (var i = 0;i<matching.length;i++) {
      var m = matching[i];
      var s1 = m[0];
      var isFirstLine = (
         (s1.x === 0) ||
         (s1.y === 0) ||
         (s1.x === (game[0].length-1)) ||
         (s1.y === (game.length-1)));
      
         if( isFirstLine) {
            return true;
         }
   }
   return p.isPattern(pattern, stone, game) ;


The main pattern is :

"oo?"
"X1o"
"oo?"

1 : is the last played move
X : is a stone of same color then '1'
o : means "a stone of a different color of '1', or empty
? : means we don't care what is in this position

in the same we but not on that pattern:

'x' would be "a stone of same color of '1' or empty
'O' a stone of a different color of '1'

But just that pattern failed to find nobi on the first line... cause the whole pattern must be containd in the game for the engine to consider that the pattern match a position on the goban.

So I did the "getMatchingPositions(...)" stuff which basicly retrive the position of '1' in another "smaller" pattern and then check if '1' is on first line...
   


Re: Game moves statistics, any program for that ?

Posted: Wed May 21, 2014 2:01 am
by RBerenguel
oca wrote:
Bill Spight wrote:It's guzumi (see http://senseis.xmp.net/?Guzumi ). Specifically, a good empty triangle. :)

RBerenguel wrote:Oh, right. Threatens a neat cut at that, but this seems hard to analyse automatically ;)


Oh guzumi, thank you Bill... and yes... that seems very difficult for me to analyse it automatically...
Even Nobi was more complex then excpeted... my first try found "Nobi" moves everywhere....

Current version of Nobi is slightly becoming "une usine à gaz" like we say in french (a "gas factory" ? do we say that in english ? or is it "white elephant" ???) anyway here is the code for whose who may be interested...

Code: Select all


Nobi :
====
   var pattern = [
   "oo?",
   "X1o",
   "oo?"];

   var patternFirstLine = [
   "X1",
   "oo"];
   
   var matching = p.getMatchingPositions(patternFirstLine, stone, game );
   for (var i = 0;i<matching.length;i++) {
      var m = matching[i];
      var s1 = m[0];
      var isFirstLine = (
         (s1.x === 0) ||
         (s1.y === 0) ||
         (s1.x === (game[0].length-1)) ||
         (s1.y === (game.length-1)));
      
         if( isFirstLine) {
            return true;
         }
   }
   return p.isPattern(pattern, stone, game) ;


The main pattern is :

"oo?"
"X1o"
"oo?"

1 : is the last played move
X : is a stone of same color then '1'
o : means "a stone of a different color of '1', or empty
? : means we don't care what is in this position

in the same we but not on that pattern:

'x' would be "a stone of same color of '1' or empty
'O' a stone of a different color of '1'

But just that pattern failed to find nobi on the first line... cause the whole pattern must be containd in the game for the engine to consider that the pattern match a position on the goban.

So I did the "getMatchingPositions(...)" stuff which basicly retrive the position of '1' in another "smaller" pattern and then check if '1' is on first line...
   




Hmmm... not sure if this applies to Sensei's definition of nobi. I hope Bill chimes in for this, but seems like nobi needs to be "moving ahead", getting more liberties. So in your template, at least some of the o's around 1 should be empty to satisfy this (but there are more conditions for this to work anyway.) Btw, you write very readable JS, if you put it up somewhere (github? bitbucket?) I'll sure give it a look in its entirety (if my node.js install works, haven't checked on this computer)

Re: Game moves statistics, any program for that ?

Posted: Wed May 21, 2014 2:43 am
by oca
RBerenguel wrote:if you put it up somewhere (github? bitbucket?) I'll sure give it a look in its entirety (if my node.js install works, haven't checked on this computer)


maybe be not clean enougth or commented enougth for github but here is a zip file that contains it all.

you just need to extract that somewhere.
then you need nodejs...

and then you can quickly just try that command :

D:\dev\js\movestat>node main sgf/a.sgf

which should gives you the following result:

Code: Select all

D:\dev\js\movestat>
D:\dev\js\movestat>node main sgf/a.sgf
Plugin : plugin_count_moves.js
Plugin : plugin_moves.js
Found 1 games in file 'sgf/a.sgf'
----------------------------------------------------------------------
PLUGIN : COUNT MOVES

4 moves
----------------------------------------------------------------------
PLUGIN : MOVE STATISTICS

WARNING :
More a toy then a serious analysis tool...
This is just a prototype, the result is still very... approximative...

                  black   white
                  -----   -----
          Hoshi :     2       2
         Sansan :     0       0
         Tengen :     0       0
         Komoku :     0       0
         Kakari :     0       0
           Nobi :     0       0
         Kosumi :     0       0
           Hane :     0       0
     Ikken tobi :     0       0
     Niken tobi :     0       0
        Kogeima :     0       0
         Ogeima :     0       0
    Daidaigeima :     0       0
      Cross cut :     0       0
           Peep :     0       0
            Cap :     0       0
   Shoulder hit :     0       0
          Tsuke :     0       0
           Bump :     0       0
            Cut :     0       0
 Empty triangle :     0       0
  Full triangle :     0       0
           Turn :     0       0
    Bamboo join :     0       0
    Table shape :     0       0
    Tiger mouth :     0       0
        Ponnuki :     0       0
 Tortoise Shell :     0       0
   Elephant eye :     0       0
          Crawl :     0       0
         Atari* :     0       0
     Connection :     0       0

=============================================================
Not identified :
Black : 0
White : 0

D:\dev\js\movestat>


Files are :

main.js : the main program file, that take care of reading the sgf file and then invoke some plugins for each moves.
ascii.js : just a quick one to echo a basic ascii board... mainly for debug...
engine.js and group.js : rule engine, not the cleanest one... an old one I use to quickly write as a test...
pattern.js : used to generate rotated and mirrored patterns, and to see if they match in a game

So... main.js read a given file (or a dir and then iterate on each of the files),
for each file, it loops for each of the games and finally, loops for each moves in the game (taking only the first variation path)

Now comes the notion of plugin... a plugin is a file that should be in the plugins dir, and that should not start with the _ char (so that we can disable them easily by just changing their name).

Each plugin should expose 3 functions :
- getTitle that just return the name of the plugin as a string
- onFinish, which is called by the engine at the really end of all files/games/moves handling, this is where the plugin should echo things...
- and onMove : which is where a move is sent by the engine to the plugin.

onMove recieve some data to do its work.
- a "move" , which is an object representing the move as sent by the sgf parser
- a "stone", which is very similar to the move, but in another form (yes it's a bit redondant...)
- a "st_group" which is a structure of a group (this is the group that the stone belong to) a group structure contains its stones and liberties
- a game which is... the game.... (as an array of array [line1, line2,...line19] where lines are somthing like [0,0,1,2,0,...,1], 0 being empty, 1 is black and 2 is white... ), game[0][0] is top / left

- st_groups is a list of all groups at current position (again with their stones and liberties)

the easiest way to start is to look at the file "plugins/plugin_count_moves.js" and play with it echoing the structures
with code like JSON.stringify (st_group,null,2); for instance.


The move analysis part in in the file "plugins/plugin_moves.js" and is basicly a big list of moves, each with a name and a function called "is" that should return "true" is the last play move is of its shape...

Ok, that should be enougth for a starting point I hope...


PS: if that just don't work, may be try to install the sgf parser manually with command :

"npm install smartgame" as told here "https://www.npmjs.org/package/smartgame"

Re: Game moves statistics, any program for that ?

Posted: Wed May 21, 2014 3:52 am
by oca
Another one that explain more in detail the structure that the program use.

Click Here To Show Diagram Code
[go]$$B
$$ +-------------------+
$$ | . . . . . . . . . |
$$ | . . . . . . . . . |
$$ | . . X 1 . . , . . |
$$ | . . . . . . . . . |
$$ | . . . . , . . . . |
$$ | . . . . . . . . . |
$$ | . . , . . . O . . |
$$ | . . . . . . . . . |
$$ | . . . . . . . . . |
$$ +-------------------+[/go]


Code: Select all


for move black 1, the arguments passed to onMove callback function would then be the following :

move : The last played move (black 1) (as given by the sgf parser, usefull to check pass move for instance)
{"B":"dc"}  // warning, this is sgf coords, that will including the letter 'i'

stone : Another represenation of the move that match well with the other parameters. 'c' means 'color' and 1 is for a black stone (2 for a white one)
{"x":3,"y":2,"c":1}

st_group : the group the last played move belongs to.
{
   "stones":[
      {"x":2,"y":2,"c":1},
      {"x":3,"y":2,"c":1}
   ],

   "liberties" : [
      {"x":2,"y":1},
      {"x":2,"y":3},
      {"x":1,"y":2},
      {"x":3,"y":1},
      {"x":3,"y":3},
      {"x":4,"y":2}
   ]
}

game : [
   [0,0,0,0,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,0],
   [0,0,0,0,0,0,0,0,0],
   [0,0,0,0,0,0,2,0,0],
   [0,0,0,0,0,0,0,0,0],
   [0,0,0,0,0,0,0,0,0]
]

st_groups : all groups for actual position.
[
   {
      "stones":[ {"x":2,"y":2,"c":1},{"x":3,"y":2,"c":1}],
      "liberties":[
         {"x":2,"y":1},
         {"x":2,"y":3},
         {"x":1,"y":2},
         {"x":3,"y":1},
         {"x":3,"y":3},
         {"x":4,"y":2}
      ]
   },{
      "stones":[{"x":6,"y":6,"c":2}],
      "liberties":[{"x":6,"y":5},{"x":6,"y":7},{"x":7,"y":6},{"x":5,"y":6}]
   }
]



A simple example plugin to display that kind of stuff :

Code: Select all

var nb = 0;
var buffer ="";
exports.getTitle = function() {
   return "Show structures";
};

exports.onMove = function(move, stone, st_group, game, st_groups) {
   nb ++;
   if (nb == 3) {

      buffer += "game :\n";
      buffer += JSON.stringify(game)+"\n\n";

      buffer += "move :\n";
      buffer += JSON.stringify(move)+"\n\n";

      buffer += "stone :\n";
      buffer += JSON.stringify(stone)+"\n\n";

      buffer += "st_group :\n";
      buffer += JSON.stringify(st_group)+"\n\n";

      buffer += "st_groups :\n";
      buffer += JSON.stringify(st_groups)+"\n\n";
      
   }
};

exports.onFinish = function() {
   console.log(buffer);
};

Re: Game moves statistics, any program for that ?

Posted: Thu May 22, 2014 7:40 am
by joellercoaster
RBerenguel wrote:Lisp programmers are pretty much happy


You rang?

(Not done Common Lisp in a few decades so CLOS is forever in the past, but Clojure is a very comfortable modern Lisp and you're right - OO is something I think about little indeed ;))

Re: Game moves statistics, any program for that ?

Posted: Thu May 22, 2014 8:26 am
by RBerenguel
joellercoaster wrote:
RBerenguel wrote:Lisp programmers are pretty much happy


You rang?

(Not done Common Lisp in a few decades so CLOS is forever in the past, but Clojure is a very comfortable modern Lisp and you're right - OO is something I think about little indeed ;))


I don't understand what "rang" means here... But yes, I've programmed in Common Lisp (probably the only relevant program for the world is my code to generate Lavaurs chords, which has been improved by other people meanwhile) in the past. Not much any more, though (I still code a bit in Emacs Lisp, so my Lisp fix is always close at hand) since for most tasks I'm faster in Go, Javascript or some kludge with awk. Or when I need to go full crazy with what I'm doing and how to solve it, lately it means (likely) try to do it in Prolog or APL.

Re: Game moves statistics, any program for that ?

Posted: Thu May 22, 2014 1:24 pm
by Bill Spight
RBerenguel wrote:
oca wrote:Even Nobi was more complex then excpeted... my first try found "Nobi" moves everywhere....

Current version of Nobi is slightly becoming "une usine à gaz" like we say in french (a "gas factory" ? do we say that in english ? or is it "white elephant" ???) anyway here is the code for whose who may be interested...

Code: Select all


Nobi :
====
   var pattern = [
   "oo?",
   "X1o",
   "oo?"];

   var patternFirstLine = [
   "X1",
   "oo"];
   
   var matching = p.getMatchingPositions(patternFirstLine, stone, game );
   for (var i = 0;i<matching.length;i++) {
      var m = matching[i];
      var s1 = m[0];
      var isFirstLine = (
         (s1.x === 0) ||
         (s1.y === 0) ||
         (s1.x === (game[0].length-1)) ||
         (s1.y === (game.length-1)));
      
         if( isFirstLine) {
            return true;
         }
   }
   return p.isPattern(pattern, stone, game) ;


The main pattern is :

"oo?"
"X1o"
"oo?"

1 : is the last played move
X : is a stone of same color then '1'
o : means "a stone of a different color of '1', or empty
? : means we don't care what is in this position

in the same we but not on that pattern:

'x' would be "a stone of same color of '1' or empty
'O' a stone of a different color of '1'

But just that pattern failed to find nobi on the first line... cause the whole pattern must be containd in the game for the engine to consider that the pattern match a position on the goban.

So I did the "getMatchingPositions(...)" stuff which basicly retrive the position of '1' in another "smaller" pattern and then check if '1' is on first line...
   




Hmmm... not sure if this applies to Sensei's definition of nobi. I hope Bill chimes in for this, but seems like nobi needs to be "moving ahead", getting more liberties.


IMO, the Sensei's page suffers from having been written by a committee of amateurs. That is not to say that Japanese amateurs do much better. I expect that Hayashi gives a good definition, but I do not have it. Perhaps John Fairbairn will chime in. :)

Anyway, the necessary core of the idea of a nobi is that it extends a stone by playing next to it, thereby strengthening or reinforcing it. The trouble is, as oca indicates, many moves that do that are called something else. :( I am not aware of any play called a nobi in the literature where the nobi stone is adjacent to any other stone than the one that it extends. A play that extends towards the edge of the board is generally called a descent. But a play that extends from the 6th line to the 5th line might be called a nobi, I expect. A nobi almost always prevents a hane or block, but I can imagine a case where that might not be so.

Edit: For reference, you might enjoy this page: http://senseis.xmp.net/?BillSpight%2FStep :)