Move encoding for speech synthesis

Discussion of chess software programming and technical issues.

Moderator: Ras

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

Move encoding for speech synthesis

Post by sje »

Move encoding for speech synthesis

Back in the Old Days I wrote a move encoder for speech synthesis; it needed phoneme codes and also the horrid sprintf() as there was no C++ back then. Now things are so much easier.

The test position:
[d]
The moves:

Code: Select all

Ba6 Bb3 Bb5 Bd2 Bd3 Bd5 Be3 Be6 Bf4 Bg5 Bh6 Bxf7+ Kd2 Kf1 Kxf2 Na3 Nbc3 Nd2 Nd4 Nec3 Nf4 Ng1 Ng3 O-O Qd2 Qd3 Qd4 Qd5 Qd6 Qxd7+ Rf1 Rg1 a3 a4 b3 b4 c3 e6 g3 g4 h3 h4
The moves encoded for speech synthesis:

Code: Select all

The white bishop at square c4 moves to square a6.
The white bishop at square c4 moves to square b3.
The white bishop at square c4 moves to square b5.
The white bishop at square c1 moves to square d2.
The white bishop at square c4 moves to square d3.
The white bishop at square c4 moves to square d5.
The white bishop at square c1 moves to square e3.
The white bishop at square c4 moves to square e6.
The white bishop at square c1 moves to square f4.
The white bishop at square c1 moves to square g5.
The white bishop at square c1 moves to square h6.
The white bishop at square c4 captures the black pawn at square f7 giving check.
The white king at square e1 moves to square d2.
The white king at square e1 moves to square f1.
The white king at square e1 captures the black knight at square f2.
The white knight at square b1 moves to square a3.
The white knight at square b1 moves to square c3.
The white knight at square b1 moves to square d2.
The white knight at square e2 moves to square d4.
The white knight at square e2 moves to square c3.
The white knight at square e2 moves to square f4.
The white knight at square e2 moves to square g1.
The white knight at square e2 moves to square g3.
White castles king side.
The white queen at square d1 moves to square d2.
The white queen at square d1 moves to square d3.
The white queen at square d1 moves to square d4.
The white queen at square d1 moves to square d5.
The white queen at square d1 moves to square d6.
The white queen at square d1 captures the black pawn at square d7 giving check.
The white rook at square h1 moves to square f1.
The white rook at square h1 moves to square g1.
The white pawn at square a2 moves to square a3.
The white pawn at square a2 moves to square a4.
The white pawn at square b2 moves to square b3.
The white pawn at square b2 moves to square b4.
The white pawn at square c2 moves to square c3.
The white pawn at square e5 moves to square e6.
The white pawn at square g2 moves to square g3.
The white pawn at square g2 moves to square g4.
The white pawn at square h2 moves to square h3.
The white pawn at square h2 moves to square h4.
The encoder:

Code: Select all

std::string Move::EncodeVerbose(void) const
{
  std::ostringstream oss;

  if (IsNullOrVoid())
  {
    if (IsNull())
      oss << "Null";
    else
      oss << "Void";
    oss << " move";
  }
  else
  {
    const Color good = GoodColor();
    const Color evil = EvilColor();
    const Mc mc = GetMc();
    
    switch (mc)
    {
      case McReg: // Regular move
        oss <<
          "The " << ColorNameLCVec[good] <<
          " " << PieceNameLCVec[CvManToPiece[GetFrMan()]] <<
          " at square " << SqNameVec[GetFrSq()];
        if (IsSimpleCapture())
          oss <<
            " captures the " << ColorNameLCVec[evil] <<
            " " << PieceNameLCVec[CvManToPiece[GetToMan()]] <<
            " at square " << SqNameVec[GetToSq()];
        else
          oss << " moves to square " << SqNameVec[GetToSq()];
        break;
        
      case McEPC: // En passant capture
        oss <<
          "The " << ColorNameLCVec[good] <<
          " " << PieceNameLCVec[PiecePawn] <<
          " at square " << SqNameVec[GetFrSq()] <<
          " moves to square " << SqNameVec[GetToSq()] <<
          " capturing the " << ColorNameLCVec[evil] <<
          " " << PieceNameLCVec[PiecePawn] <<
          " at square " << SqNameVec[GetToSq() + CvColorToForwardDelta[evil]] <<
          " en passant";
        break;
        
      case McCQS: // Castles queenside
        oss << ColorNameUCVec[good] << " castles queen side";
        break;
        
      case McCKS: // Castles kingside
        oss << ColorNameUCVec[good] << " castles king side";
        break;
        
      case McPPN: // Pawn promotes to knight
      case McPPB: // Pawn promotes to bishop
      case McPPR: // Pawn promotes to rook
      case McPPQ: // Pawn promotes to queen
        oss <<
          "The " << ColorNameLCVec[good] <<
          " " << PieceNameLCVec[PiecePawn] <<
          " at square " << SqNameVec[GetFrSq()];
        if (IsSimpleCapture())
          oss <<
            " captures the " << ColorNameLCVec[evil] <<
            " " << PieceNameLCVec[CvManToPiece[GetToMan()]] <<
            " at square " << SqNameVec[GetToSq()];
        else
          oss << " moves to square " << SqNameVec[GetToSq()];
        oss << " and promotes to a " << PieceNameLCVec[CvMcToPiece[mc]];
        break;
        
      default:
        SwitchFault("Move::EncodeVerbose");
        break;
    };
    
    if (IsCheck())
    {
      oss << " giving ";
      if (IsCheckmate())
        oss << "checkmate";
      else
        oss << "check";
    };

    oss << ".";
  };

  return oss.str();
}
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: Move encoding for speech synthesis

Post by sje »

It would be possible, although maybe not preferable, to attempt abbreviation. An obvious try would be to suppress the origination square if only one of the moving piece kind is on the board. And if only one of a kind of move were present, then the code might emit something like "Black castles", "White captures", "Black checks", or "White checkmates".

A simpler and more useful change would be to substitute personal pronouns [I/you], [my/your] for color names.

A very ambitious modification would be to supply a year parameter to the encoder. The further in the past, the more ornate the move description.

"His Royal Majesty's Chevalier on his Queen's Field leaps from the First Square of Her Majesty's Knight's House to the Third Square of Her Majesty's Cleric's House."
User avatar
hgm
Posts: 28481
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Move encoding for speech synthesis

Post by hgm »

We spent a lot of attention to good ways for audio feedback in the WinBoard version for the blind (i.e. the JAWS version). This involved cooperation with actual blind people.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Chesss for blind or low vision people

Post by sje »

My dad is blind, but does not play chess.

For chess players who are blind or with low (i,e., very poor) vision, I recommend this peg chess set:

http://www.maxiaids.com/products/3348/D ... s-Set.html

The black pieces each have a little metal cap, and the black squares are slightly raised.