Just for you: Perft(5) the movie

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Just for you: Perft(5) the movie

Post by sje »

Rated G for anyone with an terminal emulator which can interpret ANSI escape sequences:

https://dl.dropboxusercontent.com/u/316 ... t5movie.gz

Download, then:

Code: Select all

gzcat perft5movie.gz
It takes about 45 seconds for playback, varying with the swiftiness of your system.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Playback on Linux

Post by sje »

Playback on Linux

I have verified that the standard terminal emulator on Linux correctly handles playback of the perft() movie. The movie looks a little better if the terminal font is changed from a Regular to a Bold variant. Any font family should work as long as it is monospace.

--------

I'm tempted to write a screensaver version. But for years I've also been tempted to write a screensaver which looked like a half dozen HAL 9000 status monitor displays, and I haven't gotten around to that yet. These displays would look very much like those in the film except that upon closer examination they would be seen to display actual status information from the host computer.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Now with subtitles!

Post by sje »

I've added a subtitle facility to Oscar's perft() movie generator. The single subtitle line is the current variation which leads to the displayed position.

This change adds to both the movie file size and the playback time. It's worth it, though. Adding the path count as a second subtitle line would more than double the movie file size, so I'll leave that out for now.

Same place, just bigger this time:

https://dl.dropboxusercontent.com/u/316 ... t5movie.gz

Same instructions; download, then:

Code: Select all

gzcat perft5movie.gz
If someone has gotten the playback to work on Windows, please post so that others can give it a go.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

The much smaller perft(4) movie

Post by sje »

The much smaller perft(4) movie:

https://dl.dropboxusercontent.com/u/316 ... t4movie.gz

Playback of the above takes about three seconds.
mar
Posts: 2559
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Just for you: Perft(5) the movie

Post by mar »

Nice movie, a bit too long though :) And maybe I would change some of the colors (not much to choose from).
ANSI sequences are fun, reminds me of BBSes and old text mode games.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: Just for you: Perft(5) the movie

Post by sje »

mar wrote:Nice movie, a bit too long though :) And maybe I would change some of the colors (not much to choose from).
ANSI sequences are fun, reminds me of BBSes and old text mode games.
Soon I'll have Oscar ready for release and then you'll be able to fiddle with the movie generator, plus see a movie as it's being generated.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Code snippet: Perft movie stuff

Post by sje »

From Oscar.c and subject to change:

Code: Select all

// Perft movie routines

static void PmPutChar(Pm * const pmptr, const char ch)
{
  // This routine is the gateway for outputing characters to the given perft movie.
  
  fputc(ch, pmptr->vfptr);
}

static void PmPutStr(Pm * const pmptr, const char * const chptr)
{
  // This routine outputs a string to the given ASCII movie file.
  
  ui index = 0;
  while (chptr[index] != '\0')
    PmPutChar(pmptr, chptr[index++]);
}

static void PmPutEscSeq(Pm * const pmptr)
{
  // This routine outputs an ASCII escape sequence prefix to the given perft movie.
  
  PmPutStr(pmptr, "\x1b[");
}

static void PmPutEscSeqStr(Pm * const pmptr, const char * const str)
{
  // This routine outputs an ASCII escape sequence prefix and a string to the given perft movie.
  
  PmPutEscSeq(pmptr);
  PmPutStr(pmptr, str);
}

static void PmAttributesReset(Pm * const pmptr)
{
  // This routine outputs an attributes reset directive to the given perft movie.
  
  PmPutEscSeqStr(pmptr, "0m");
}

static void PmClearDisplay(Pm * const pmptr)
{
  // This routine outputs a clear display directive to the given perft movie.
  
  PmPutEscSeqStr(pmptr, "2J");
}

static void PmClearToEOL(Pm * const pmptr)
{
  // This routine outputs a clear to EOL directive to the given perft movie.
  
  PmPutEscSeqStr(pmptr, "0K");
}

static void PmCursorOff(Pm * const pmptr)
{
  // This routine turns off the cursor on the given perft movie.
  
  PmPutEscSeqStr(pmptr, "?25l");
}

static void PmCursorOn(Pm * const pmptr)
{
  // This routine turns on the cursor on the given perft movie.
  
  PmPutEscSeqStr(pmptr, "?25h");
}

static void PmCursorMove(Pm * const pmptr, const ui row, const ui column)
{
  // This routine outputs a cursor positioning directive to the given perft movie.
  
  char cv[TextLineLen];
  
  sprintf(cv, "%u;%uH", (row + 1), (column + 1));
  PmPutEscSeqStr(pmptr, cv);
}

static void PmSetColors(Pm * const pmptr, const Ac acfore, const Ac acback)
{
  // This routine outputs a color directive to the given perft movie.
  
  char cv[TextLineLen];
  
  sprintf(cv, "%u;%um", (acfore + 30), (acback + 40));
  PmPutEscSeqStr(pmptr, cv);
}

static void PmPutMan(Pm * const pmptr, const Man man, const Sq sq)
{
  // This routine outputs a chessman on a square to the given perft movie.
  
  const File file = MapSqToFile(sq);
  const Rank rank = MapSqToRank(sq);
  Ac acfore, acback;
  
  
  if ((rank & 1) == (file & 1))
    acback = AcGreen;
  else
    acback = AcWhite;
  if (IsManVacant(man))
    acfore = AcBlack;
  else
  {
    if (IsManWhite(man))
      acfore = AcRed;
    else
      acfore = AcBlue;
  };
  PmCursorMove(pmptr, (RankLen - 1 - rank), (file * 2));
  PmSetColors(pmptr, acfore, acback);
  if (IsManVacant(man))
    PmPutStr(pmptr, "  ");
  else
  {
    PmPutChar(pmptr, CvColorToChar[CvManToColor[man]]);
    PmPutChar(pmptr, CvPieceToChar[CvManToPiece[man]]);
  };
}

static void PmPutBoard(Pm * const pmptr, const Board * const boardptr)
{
  // This routine outputs a chessboard to the given perft movie.
  
  Rank rank;
  
  for (rank = Rank8; rank >= Rank1; rank--)
  {
    File file;
    
    for &#40;file = FileA; file <= FileH; file++)
    &#123;
      const Sq sq = MapFileRankToSq&#40;file, rank&#41;;
      const Man man = boardptr->manvec&#91;sq&#93;;
      
      PmPutMan&#40;pmptr, man, sq&#41;;
    &#125;;
  &#125;;
&#125;

static void PmPushMove&#40;Pm * const pmptr, const Move move&#41;
&#123;
  if &#40;pmptr->mpcount < PmMoveLen&#41;
  &#123;
    SanRec sanrec;
    SanRecLoadFromMove&#40;&sanrec, move&#41;;
    
    pmptr->cols&#91;pmptr->mpcount&#93; = pmptr->column;
    PmCursorMove&#40;pmptr, RankLen, pmptr->column&#41;;
    PmAttributesReset&#40;pmptr&#41;;
    if &#40;pmptr->mpcount > 0&#41;
    &#123;
      PmPutChar&#40;pmptr, ' ');
      pmptr->column++;
    &#125;;
    PmPutStr&#40;pmptr, sanrec.chvec&#41;;
    pmptr->column += StrLength&#40;sanrec.chvec&#41;;
  &#125;;
  pmptr->mpcount++;
&#125;

static void PmPopMove&#40;Pm * const pmptr&#41;
&#123;
  pmptr->mpcount--;
  if &#40;pmptr->mpcount < PmMoveLen&#41;
  &#123;
    pmptr->column = pmptr->cols&#91;pmptr->mpcount&#93;;
    PmCursorMove&#40;pmptr, RankLen, pmptr->column&#41;;
    PmAttributesReset&#40;pmptr&#41;;
    PmClearToEOL&#40;pmptr&#41;;
  &#125;;
&#125;

static void PmUpdateBoard&#40;Pm * const pmptr, const Board * const boardptr, const Move move&#41;
&#123;
  const Mc mc = GetMc&#40;move&#41;;
  Sq sqvec&#91;5&#93;;
  Sq sq;
  ui index = 0;
  
  switch &#40;mc&#41;
  &#123;
    case McReg&#58;
      sqvec&#91;index++&#93; = GetFrSq&#40;move&#41;;
      sqvec&#91;index++&#93; = GetToSq&#40;move&#41;;
      break;
      
    case McEPC&#58;
    &#123;
      const Color other = CvColorToOtherColor&#91;CvManToColor&#91;GetFrMan&#40;move&#41;&#93;&#93;;
      const Sq vpsq = NextSq&#91;CvColorToAdvDir&#91;other&#93;&#93;&#91;GetToSq&#40;move&#41;&#93;;
      
      sqvec&#91;index++&#93; = GetFrSq&#40;move&#41;;
      sqvec&#91;index++&#93; = GetToSq&#40;move&#41;;
      sqvec&#91;index++&#93; = GetToSq&#40;vpsq&#41;;
    &#125;;
      break;
      
    case McCQS&#58;
    case McCKS&#58;
    &#123;
      const Color color = CvManToColor&#91;GetFrMan&#40;move&#41;&#93;;
      const Castling castling = CvColorMcToCastling&#91;color&#93;&#91;mc&#93;;
      
      sqvec&#91;index++&#93; = GetFrSq&#40;move&#41;;
      sqvec&#91;index++&#93; = GetToSq&#40;move&#41;;
      sqvec&#91;index++&#93; = CastInfo&#91;castling&#93;.r0sq;
      sqvec&#91;index++&#93; = CastInfo&#91;castling&#93;.r1sq;
    &#125;;
      break;
      
    case McPPN&#58;
    case McPPB&#58;
    case McPPR&#58;
    case McPPQ&#58;
      sqvec&#91;index++&#93; = GetFrSq&#40;move&#41;;
      sqvec&#91;index++&#93; = GetToSq&#40;move&#41;;
      break;
      
    default&#58;
      break;
  &#125;;
  sqvec&#91;index&#93; = SqNil;
  
  index = 0;
  while &#40;IsSqNotNil&#40;sq = sqvec&#91;index++&#93;))
    PmPutMan&#40;pmptr, boardptr->manvec&#91;sq&#93;, sq&#41;;
&#125;
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Also, movies for perft(6) and perft(7)

Post by sje »

Also, operft has made movies for perft(6) and perft(7). I even managed to toss in some minor optimizations which reduced the movie size by a few percent. Alas, although gzip can compress a movie by 98+%, the results for perft(6) and perft(7) are still far too large to post:

Code: Select all

-rw-r--r--  1 sje  staff   214694036 Sep 28 05&#58;18 perft6movie.gz
-rw-r--r--  1 sje  staff  6059485118 Sep 28 09&#58;47 perft7movie.gz
The length of a compressed movie is about one byte per each call to Execute() and Retract().

--------

There is so little overhead producing ASCII chess movies that the technique could be unobtrusively employed in a regular chess program for the dynamic display of the position under analysis, or perhaps for each analysis position for each search thread.

There would be no need to update the movie display for each call to Execute() and Retract(), because there's no need to update any visual at a rate faster than the display refresh frequency. A 60 Hz redraw should be sufficient.

It would be easy to do. A separate movie program would run in its own terminal emulator window and manage the movie output. This movie program would connect to the chess program via a shared memory segment or some other low overhead linkage and snapshot the position and current variation data sixty times a second.
ernest
Posts: 2041
Joined: Wed Mar 08, 2006 8:30 pm

Re: Just for you: Perft(5) the movie

Post by ernest »

sje wrote:Download, then:

Code: Select all

gzcat perft5movie.gz
In Windows, I use 7-zip and get a file called amov (no extension)
How do I play that "movie" ?
ZirconiumX
Posts: 1334
Joined: Sun Jul 17, 2011 11:14 am

Re: Just for you: Perft(5) the movie

Post by ZirconiumX »

ernest wrote:
sje wrote:Download, then:

Code: Select all

gzcat perft5movie.gz
In Windows, I use 7-zip and get a file called amov (no extension)
How do I play that "movie" ?
It relies on ANSI escape codes; something that Windows does not implement. gzcat dumps amov to the terminal, resulting in a nice pretty perft movie.

Matthew:out
Some believe in the almighty dollar.

I believe in the almighty printf statement.