Live broadcast of engine pv

Discussion of anything and everything relating to chess playing software and machines.

Moderators: hgm, Rebel, chrisw

User avatar
Matthias Gemuh
Posts: 3245
Joined: Thu Mar 09, 2006 9:10 am

Re: Live broadcast of engine pv

Post by Matthias Gemuh »

Ferdy wrote:Finally implemented here.

http://www.chess.x10host.com/pgn4web/index.html

I rewrite the pgn output of ChessGUI to a different format, now the pv (taken from TLCV_File.txt output from ChessGUI) is embeded as part of move comment, so now I get pgn and pv at the same time, send it to server via ftp, then extract the pv via pgn4web custom function, and just use a javascript to display the pv on the page, no more server scripts needed.

I think Matthias Gemuh author of ChessGUI can easily incorparate this change, adding pv to the move comment.
Please send sample pgn with pv as comment to mgemuh at gmx.de
My engine was quite strong till I added knowledge to it.
http://www.chess.hylogic.de
User avatar
hgm
Posts: 27790
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Live broadcast of engine pv

Post by hgm »

The best way to add PVs to the PGN is as 'recursive variation'. Then PGN processing software can also walk through the PVs. If you hide them in a comment, they will just be ignored.
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Live broadcast of engine pv

Post by Ferdy »

Matthias Gemuh wrote:
Ferdy wrote:Finally implemented here.

http://www.chess.x10host.com/pgn4web/index.html

I rewrite the pgn output of ChessGUI to a different format, now the pv (taken from TLCV_File.txt output from ChessGUI) is embeded as part of move comment, so now I get pgn and pv at the same time, send it to server via ftp, then extract the pv via pgn4web custom function, and just use a javascript to display the pv on the page, no more server scripts needed.

I think Matthias Gemuh author of ChessGUI can easily incorparate this change, adding pv to the move comment.
Please send sample pgn with pv as comment to mgemuh at gmx.de
I will just post here.

Image
User avatar
Rebel
Posts: 6991
Joined: Thu Aug 18, 2011 12:04 pm

Re: Live broadcast of engine pv

Post by Rebel »

Ferdy wrote:Finally implemented here.

http://www.chess.x10host.com/pgn4web/index.html

I rewrite the pgn output of ChessGUI to a different format, now the pv (taken from TLCV_File.txt output from ChessGUI) is embeded as part of move comment, so now I get pgn and pv at the same time, send it to server via ftp, then extract the pv via pgn4web custom function, and just use a javascript to display the pv on the page, no more server scripts needed.

I think Matthias Gemuh author of ChessGUI can easily incorparate this change, adding pv to the move comment.
Nice!

Did you have to change your engine to make it work?
User avatar
Rebel
Posts: 6991
Joined: Thu Aug 18, 2011 12:04 pm

Re: Live broadcast of engine pv

Post by Rebel »

Ferdy wrote:
Rebel wrote:
Ferdy wrote:
Rebel wrote:Got it to work.

http://rebel13.nl/pgn4web/live1.html

Currently for version 241 only and the hopping needs a fix, point is, it is doable and quite easily.

Basically you can put anything in the file, even tell random jokes to entertain the audience in case the game is in a boring stage.
I am using chrome and it seems like the live pv is not consistent, after forced refresh it would show the pv before the move is made on the board but later, the pv is no longer updated. If you forced to refresh again, the live pv will show up and on later moves the live pv is no longer updated again. So I need to press the refresh button every time I wanted to see the live pv displayed.
Better now with Chrome?
Wow it looks great :)
But... but...but... Graham want clocks, let's give Graham clocks.

http://rebel13.nl/pgn4web/live1.html

And now Graham will complain he wants graphical clocks.

:wink:
User avatar
Graham Banks
Posts: 41423
Joined: Sun Feb 26, 2006 10:52 am
Location: Auckland, NZ

Re: Live broadcast of engine pv

Post by Graham Banks »

Rebel wrote:But... but...but... Graham want clocks, let's give Graham clocks.

http://rebel13.nl/pgn4web/live1.html

And now Graham will complain he wants graphical clocks.

:wink:
:P
Remember that I use ChessGUI and not Arena, so that might count against me anyway.
gbanksnz at gmail.com
Jesse Gersenson
Posts: 593
Joined: Sat Aug 20, 2011 9:43 am

Re: Live broadcast of engine pv

Post by Jesse Gersenson »

Ferdy wrote:How do you show to a web page the engine pv's during broadcast?
The problem is making something which works with more than one GUI. InBetween, or something similar, which is between the gui and the engine would give you independence from the GUI and/or the engine logs.

I wrote something last year which parsed arena's debug file and then fed this to node.js via ssh. It showed pv output, the refresh rate was limited by how quickly new lines of pv data could get to the web server. Was much smoother than longpolling.

Was using something like this on the machine which ran arena:

Code: Select all

#!/bin/bash
arenaLog='/home/arena/arena.debug'
a=`(stat -c%s $arenaLog)`
d=1
while true
do
  if [[ $a == `stat -c%s $arenaLog`  ]]
  then
    sleep 0.11;

  else

gamedataARRAY=(`grep tbhits $arenaLog|tail -1| sed 's/.*info //g'`)
#echo ${gamedataARRAY[3]}      # fourth element
		for i in ${!gamedataARRAY[@]}
		do 
			iplus1=$((  $i + 1 ));

			if [ "${gamedataARRAY[$i]}" = 'depth' ] 
			then
				depth="${gamedataARRAY[$i+1]}"
                                if [[ "$d" -gt "$depth" ]]
                                then
                                      echo "d > depth -- d=$d depth=$depth"
                                      echo "SEND A RESET $d $depth"
                                  d=$depth
                                      reset=1;
                                else
                                  reset=0
                                  echo "d <= depth --  d=$d depth=$depth"
                                  d=$depth
                                fi
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'time' &#93; 
			then
				time="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				time=$(( $time / 1000 ));
				time=`&#40;date -u --date="@$time"|cut -b15-19&#41;`
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'tbhits' &#93; 
			then
				tbhits="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				#pv="$&#123;testarray&#91;@&#93;&#58;6&#125;"
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'nps' &#93; 
			then
				nps="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				nps=$(( $nps / 1000 ))
				nps=`&#40;printf "%'.0f\n" $nps&#41;`

			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'nodes' &#93; 
			then
				nodes="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				nodes=`&#40;printf "%'.0f\n" $nodes&#41;`

			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'cp' &#93; 
			then
				cp="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				cp=`&#40;echo "scale=2;$cp"/100|bc -l|sed -e 's/^\./0./' -e 's/^-      \./-0./')`;
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'pv' &#93; 
			then
				#pv="$&#123;gamedataARRAY&#91;$i+10&#93;&#125;"
				#All elements following element&#91;0&#93;.
				#echo $&#123;arrayZ&#91;@&#93;&#58;1&#125;     # two three four five five
				#Only the two elements after element&#91;0&#93;.
				#echo $&#123;arrayZ&#91;@&#93;&#58;1&#58;2&#125;   # two three
				pv="$&#123;gamedataARRAY&#91;@&#93;&#58;$iplus1&#58;6&#125;" 
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'hashfull' &#93; 
			then
				hashfull="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
			fi

		done
		line=`&#40;echo "<i id=d>$depth</i> <i id=t>$time</i> <i id=n>$nodes</i> <i id=nps>$nps kN/s</i> <i id=cp>$cp</i> <i id=pv>$pv</i>")`;
                if &#91;&#91; $reset == 1 &#93;&#93;
                then
			ssh -p$sshport -C $sshuser@$sship "echo '&nbsp;'  >> gamedata;echo '&nbsp;' >> gamedata; echo '&nbsp;' >> gamedata;echo '&nbsp;' >> gamedata;exit"      
	                reset=0
                else
			echo "$line"|ssh -p$sshport -C $sshuser@$sship "cat >> gamedata;exit"
                fi
        date
        sleep 0.4;
        a=`&#40;stat -c%s $arenaLog&#41;`
  fi
done
And something like these two files, index.html and index.js, on the web server:
index.js

Code: Select all

var app = require&#40;'express')();
var http = require&#40;'http').Server&#40;app&#41;;
var io = require&#40;'socket.io')&#40;http&#41;;
Tail = require&#40;'tail').Tail;

app.get&#40;'/', function&#40;req, res&#41;&#123;

    //send the index.html file for all requests
    res.sendFile&#40;__dirname + '/index.html');

&#125;);

http.listen&#40;3001, function&#40;)&#123;

    console.log&#40;'listening on *&#58;3001');

&#125;);

// send 'msg' to client & console every 1000ms
setInterval&#40; function&#40;) &#123;

	var tail = new Tail&#40;"test.txt");
	tail.on&#40;"line", function&#40;data&#41; &#123;
	  io.emit&#40;'line', data&#41;;
	  console.log&#40;'line', data&#41;;
  	&#125;);
    var msg = Math.random&#40;);
//    io.emit&#40;'message', msg&#41;;
  //  console.log &#40;msg&#41;;

&#125;, 500&#41;;

Code: Select all

<html>
<head></head>

<body>
  <div id="message"></div>
  <div id="line"></div>

    <script src="/socket.io/socket.io.js"></script>
      <script>
    var socket = io&#40;);

socket.on&#40;'message', function&#40;msg&#41;&#123;
	console.log&#40;msg&#41;;
	document.getElementById&#40;"message").innerHTML = msg;
	&#125;
);
socket.on&#40;'line', function &#40;data&#41; &#123;

    console.log&#40;data&#41;;
	document.getElementById&#40;"line").innerHTML = data;

  &#125;);

  </script>
  </body>
  </html>
package.js:
package.json
{
"dependencies": {
"express": "^4.13.3",
"socket.io": "^1.3.6"
}
}
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Live broadcast of engine pv

Post by Ferdy »

Rebel wrote:
Ferdy wrote:Finally implemented here.

http://www.chess.x10host.com/pgn4web/index.html

I rewrite the pgn output of ChessGUI to a different format, now the pv (taken from TLCV_File.txt output from ChessGUI) is embeded as part of move comment, so now I get pgn and pv at the same time, send it to server via ftp, then extract the pv via pgn4web custom function, and just use a javascript to display the pv on the page, no more server scripts needed.

I think Matthias Gemuh author of ChessGUI can easily incorparate this change, adding pv to the move comment.
Nice!

Did you have to change your engine to make it work?
No. I reformat the livepgn that is sent to the server, added [%pv moves...] to the move comment of the last move in the live pgn.
This [%pv moves...] can be extracted using pgn4web custom function.
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Live broadcast of engine pv

Post by Ferdy »

Rebel wrote:
Graham Banks wrote:Nice!
Any chance of clocks being added?
Only if ChessGui has PGN clock support, Arena hasn't. From the PGN4WEB documentation:

Code: Select all

Clock information as provided by the DGT chessboards in PGN move comments, such as &#123;&#91;%clk 1&#58;59&#58;59&#93;&#125;, and in the PGN header, such as &#91;WhiteClock "2&#58;00&#58;00"&#93;, &#91;BlackClock "2&#58;00&#58;00"&#93; and &#91;Clock "W/1&#58;59&#58;59"&#93; is displayed in the following sections&#58;

  <div id="GameWhiteClock"></div>
  <div id="GameBlackClock"></div>
ChessGUI can, the option to output it has to be activated so that it will output [%clk...
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Live broadcast of engine pv

Post by Ferdy »

Jesse Gersenson wrote:
Ferdy wrote:How do you show to a web page the engine pv's during broadcast?
The problem is making something which works with more than one GUI. InBetween, or something similar, which is between the gui and the engine would give you independence from the GUI and/or the engine logs.

I wrote something last year which parsed arena's debug file and then fed this to node.js via ssh. It showed pv output, the refresh rate was limited by how quickly new lines of pv data could get to the web server. Was much smoother than longpolling.

Was using something like this on the machine which ran arena:

Code: Select all

#!/bin/bash
arenaLog='/home/arena/arena.debug'
a=`&#40;stat -c%s $arenaLog&#41;`
d=1
while true
do
  if &#91;&#91; $a == `stat -c%s $arenaLog`  &#93;&#93;
  then
    sleep 0.11;

  else

gamedataARRAY=(`grep tbhits $arenaLog|tail -1| sed 's/.*info //g'`)
#echo $&#123;gamedataARRAY&#91;3&#93;&#125;      # fourth element
		for i in $&#123;!gamedataARRAY&#91;@&#93;&#125;
		do 
			iplus1=$((  $i + 1 ));

			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'depth' &#93; 
			then
				depth="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
                                if &#91;&#91; "$d" -gt "$depth" &#93;&#93;
                                then
                                      echo "d > depth -- d=$d depth=$depth"
                                      echo "SEND A RESET $d $depth"
                                  d=$depth
                                      reset=1;
                                else
                                  reset=0
                                  echo "d <= depth --  d=$d depth=$depth"
                                  d=$depth
                                fi
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'time' &#93; 
			then
				time="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				time=$(( $time / 1000 ));
				time=`&#40;date -u --date="@$time"|cut -b15-19&#41;`
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'tbhits' &#93; 
			then
				tbhits="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				#pv="$&#123;testarray&#91;@&#93;&#58;6&#125;"
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'nps' &#93; 
			then
				nps="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				nps=$(( $nps / 1000 ))
				nps=`&#40;printf "%'.0f\n" $nps&#41;`

			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'nodes' &#93; 
			then
				nodes="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				nodes=`&#40;printf "%'.0f\n" $nodes&#41;`

			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'cp' &#93; 
			then
				cp="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
				cp=`&#40;echo "scale=2;$cp"/100|bc -l|sed -e 's/^\./0./' -e 's/^-      \./-0./')`;
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'pv' &#93; 
			then
				#pv="$&#123;gamedataARRAY&#91;$i+10&#93;&#125;"
				#All elements following element&#91;0&#93;.
				#echo $&#123;arrayZ&#91;@&#93;&#58;1&#125;     # two three four five five
				#Only the two elements after element&#91;0&#93;.
				#echo $&#123;arrayZ&#91;@&#93;&#58;1&#58;2&#125;   # two three
				pv="$&#123;gamedataARRAY&#91;@&#93;&#58;$iplus1&#58;6&#125;" 
			fi
			if &#91; "$&#123;gamedataARRAY&#91;$i&#93;&#125;" = 'hashfull' &#93; 
			then
				hashfull="$&#123;gamedataARRAY&#91;$i+1&#93;&#125;"
			fi

		done
		line=`&#40;echo "<i id=d>$depth</i> <i id=t>$time</i> <i id=n>$nodes</i> <i id=nps>$nps kN/s</i> <i id=cp>$cp</i> <i id=pv>$pv</i>")`;
                if &#91;&#91; $reset == 1 &#93;&#93;
                then
			ssh -p$sshport -C $sshuser@$sship "echo '&nbsp;'  >> gamedata;echo '&nbsp;' >> gamedata; echo '&nbsp;' >> gamedata;echo '&nbsp;' >> gamedata;exit"      
	                reset=0
                else
			echo "$line"|ssh -p$sshport -C $sshuser@$sship "cat >> gamedata;exit"
                fi
        date
        sleep 0.4;
        a=`&#40;stat -c%s $arenaLog&#41;`
  fi
done
And something like these two files, index.html and index.js, on the web server:
index.js

Code: Select all

var app = require&#40;'express')();
var http = require&#40;'http').Server&#40;app&#41;;
var io = require&#40;'socket.io')&#40;http&#41;;
Tail = require&#40;'tail').Tail;

app.get&#40;'/', function&#40;req, res&#41;&#123;

    //send the index.html file for all requests
    res.sendFile&#40;__dirname + '/index.html');

&#125;);

http.listen&#40;3001, function&#40;)&#123;

    console.log&#40;'listening on *&#58;3001');

&#125;);

// send 'msg' to client & console every 1000ms
setInterval&#40; function&#40;) &#123;

	var tail = new Tail&#40;"test.txt");
	tail.on&#40;"line", function&#40;data&#41; &#123;
	  io.emit&#40;'line', data&#41;;
	  console.log&#40;'line', data&#41;;
  	&#125;);
    var msg = Math.random&#40;);
//    io.emit&#40;'message', msg&#41;;
  //  console.log &#40;msg&#41;;

&#125;, 500&#41;;

Code: Select all

<html>
<head></head>

<body>
  <div id="message"></div>
  <div id="line"></div>

    <script src="/socket.io/socket.io.js"></script>
      <script>
    var socket = io&#40;);

socket.on&#40;'message', function&#40;msg&#41;&#123;
	console.log&#40;msg&#41;;
	document.getElementById&#40;"message").innerHTML = msg;
	&#125;
);
socket.on&#40;'line', function &#40;data&#41; &#123;

    console.log&#40;data&#41;;
	document.getElementById&#40;"line").innerHTML = data;

  &#125;);

  </script>
  </body>
  </html>
package.js:
package.json
{
"dependencies": {
"express": "^4.13.3",
"socket.io": "^1.3.6"
}
}
Thanks for the post.
I am new to this thing, and is working on windows, I tried to experiment it (based from Ed's project) on free account host and not able to run server script like node js. I have a working example here.

http://www.chess.x10host.com/pgn4web/index.html

It just show one pv at a time or every 1 sec, pgn with pv is sent to the sever, then read the pv via javascript and display it on a page the rest of the pgn is handled by pgn4web.

So how this works? You read arena log, create a data according to your needs and send it to server, server runs the node js, further processing the data. How the board is displayed on the page? does it use pgn4web?