PGN SAN: Determining the "from" square

Discussion of chess software programming and technical issues.

Moderator: Ras

delphiguru
Posts: 2
Joined: Tue Nov 30, 2021 3:35 pm
Full name: Sam D Hunt

PGN SAN: Determining the "from" square

Post by delphiguru »

FYI, this is a Delphi XE2 program for Windows 10. Delphi is Pascal on steroids. :-)
Recently, I posted about my work on my chess board entitled "Shaibels' Chess Board". I suggested that maintaining a parall array of Piece records was a good approach. Wrong! I have completely rplaced the internal data structure with simple functions and static and dynamic properties.
Here is a very short description of my program:
At design time, squares are named 'a1' to 'h8', their colors are set appropriately, and their "tag" property value is set to the index of an image list of pieces.
At runtime and on the FormShow method, a TImage is created and placed inside each square. The TImages are named 'img' + the squares name 'a1'...'h8'.
NORMAL PLAY MODE:
The program opens waiting for white to move.
To make a move, touch or click the piece you want to move, then click the square to which you want to move it.
The first click captures the TImage.parent property which is the square's name and changes the square borders to beveled.
Clicking the second square also captures the TImage.parent property.
After the second click, the move is immediately executed, then validated. If the move is an invalid move, the move is undone.
Besides the obvious invalid moves, my program checks to see if a move has placed the player's king in check, which invalidates the move also.
When a player places their opponent's king in check, the checked king's square color changes to red.
My program properly manages all moves, En Passant, and short and long castling for both black and white.
OPENING PGN SAN FILES...
I spent the past two days rewriting my GetFromSquares procedure. How it works...
1. parses the SAN into white and black moves
2. calcs the target square for each.
3. calcs all possible from squares for the piece being moved. (max possible: 1 pawn, 2 rooks, 2 knights, 2 bishops, etc.)
4. if more than one square name is returned, each from square's move is validated. Only one will be valid. This becomes the from square.
5. then the board is updated to reflect the new move.
That's basically it.
Here's the code from my GetFromSquares procedure.
I am happy to share the entire program code base, if anyone is interested.
For now, I will dontinue debugging the completed code and begin rewriting the TCPIP which supports chat and play between two people on the internet.
I am attaching a screen print of my program, having just opened and "played" a PGN SAN file.
If anyone would like to help me test this, I will be happy to give you the complete program when completed.
Enjoy. Sam

Code: Select all

procedure TfShaibelsChessBoard.GetFromSquares(sPieceColor,sPiece,sFile:string);
var
  x,y,iNumSquaresFound,iThisMove,iLength:integer;
  sThisPieceColor,sThisPieceName,sSLFile,sPGN:string;
  iRank:integer;
  cFile:char;
begin
  iNumSquaresFound := 0;
  slFromSquares.Clear;
  for iRank := 1 to 8 do
  begin
    for cFile := 'a' to 'h' do
    begin
      sThisPieceColor := PieceColor(cFile + inttostr(iRank));
      sThisPieceName := PieceName(cFile + inttostr(iRank));
      if (sPiece = 'P') then
      begin
        if (sThisPieceColor = sPieceColor) then
        begin
          if (sThisPieceName = sPiece) then
          begin
            if (cFile = sFile) then
            begin
              slFromSquares.Add(cFile + inttostr(iRank));
              inc(iNumSquaresFound);
            end;
          end;
        end;
      end
      else
      begin//all pieces
        if (sThisPieceColor = sPieceColor) and (sThisPieceName = sPiece) then
          slFromSquares.Add(cFile + inttostr(iRank));
        inc(iNumSquaresFound);
      end
    end;
  end;
  if iNumSquaresFound = 0 then
    messagedlg('No from squares found for ' + sPieceColor + sPiece +sFile,mtwarning,[mbok],0);
end;