From Chessprogramming wiki
Jump to: navigation, search

Home * Programming * Languages * Pascal

Pascal is an imperative, procedural programming language developed and published in 1970 by Niklaus Wirth from ETH Zurich. It is a small and efficient language intended to encourage good programming practices using structured programming and data structuring. Pascal is based on Algol and named in honor of the French mathematician and philosopher Blaise Pascal, like many programming languages, but unlike C, Pascal allows nested procedure definitions to any level of depth, and also allows most kinds of definitions and declarations inside procedures and functions.

UCSD Pascal

A notable Pascal system was UCSD-Pascal from University of California, San Diego that ran on a machine-independent operating system, the UCSD p-System portable. In the early 1980s, UCSD Pascal was ported to Apple II computers to provide a structured alternative to the Basic interpreters that came with the machines.

Turbo Pascal

An increased popularity of Pascal on home computers of the early 80s arose from the fast one-pass Turbo Pascal compiler, running under CP/M for 8-bit 8080/Z80 based computers, as well as CP/M-86 and MS-DOS for 8086 and later x86 based 16- and 32-bit computers. Borland licensed the PolyPascal compiler core [2], written by Anders Hejlsberg, and added user interface and editor, considered as one of the first Integrated development environment for home computers. Anders Hejlsberg later joined the company as an employee and was the architect for all versions of the Turbo Pascal compiler and the first three versions of Borland Delphi.

By 1995 Borland had dropped Turbo Pascal and replaced it with the RAD environment Delphi, based on Object Pascal. Early versions of Turbo Pascal are free downloadable from Embarcadero Technologies [3].

Inline Assembly

Early versions of Turbo Pascal could include inline machine code as hexadecimal Byte sequence, while later Inline Assembly was suported. None portable Inline assembly enabled programmers to access hardware features that were otherwise not directly available, and it was in fact overused by experienced Turbo Pascal programmers, as it could be seen from the source code of Turbo Chess [4], available from the Turbo GameWorks Book [5] by Kaare Danielsen [6].

Source Sample

A sample of a recursive Search routine in Turbo Pascal from KC Chess: Kevin & Craig's Chess Program [7]:

{  Search:  This routine handles all of the tree searching except the first  }
{  level which of the tree which is handled by the main routine.  Given the  }
{  player, all of his moves are generated, and then each one is made.  The   }
{  enemy's maximum countermove score is subtracted from the move score, and  }
{  this gives the net value for the player making the move.  The maximum     }
{  net score is remembered and returned by this function.  The player's move }
{  is then taken back, and all of his other possible moves are tried in this }
{  same way.  If the score of any move exceeds the given cutoff value, then  }
{  no other of the player's moves are checked, and the score that exceeded   }
{  (or matched) the cutoff value is returned.  If the given depth is one or  }
{  less, then the enemy's countermoves are not checked, only the points for  }
{  taking the pieces, minus the points of the player's piece if the enemy's  }
{  piece is protected.  However, if the current player's move being          }
{  considered is a take and it is given that all of moves to that point      }
{  have been AllTakes, then enemy countermoves will be checked down to a     }
{  given depth of -1.  To calculate the enemy's best score in retaliation    }
{  to the given player's move, this routine is called recursively with the   }
{  enemy as the player to move, and a depth of the one originally given, -1. }
{  The new cutoff value is the score of the move that was just made, minus   }
{  the the best score that was found so far.  If the enemy's countermoves    }
{  score exceeds or matches this countermove value, then the net score of    }
{  the original player's move cannot exceed the best found so far, and the   }
{  move will be thrown out.  The new value for AllTakes is passed on as true }
{  if all moves heretofor have been takes, and the current player's move is  }
{  a take.  This routine is the core of the computer's 'thinking'.           }
  function Search (Turn: PieceColorType; CutOff, Depth: integer; AllTakes : boolean) : integer;
    var MoveList: MoveListType;
        j, LineScore, Score, BestScore, STCutOff: integer;
        Movement: MoveType;
        Attacked, Protected: integer;
        NoMoves, TakingPiece: boolean;
      {*** get the player's move list ***}
      GenMoveList (Turn, MoveList);
      NoMoves := true;
      BestScore := NegInfinity;
      j := MoveList.NumMoves;

      {*** go through all of the possible moves ***}
      while (j > 0) do begin
          Movement := MoveList.Move[j];
          {*** make the move ***}
          MakeMove (Movement, false, Score);
          {*** make sure it is legal (not moving into check) ***}
          AttackedBy (Player[Turn].KingRow, Player[Turn].KingCol, Attacked, Protected);
          if (Attacked = 0) then begin
              NoMoves := false;
              if (Score = STALE_SCORE) then
                  {*** end the search on a stalemate ***}
                  LineScore := Score
              else begin
                  TakingPiece := Movement.PieceTaken.image <> BLANK;
                  if (Depth <= 1) and not (AllTakes and TakingPiece and (Depth >= PLUNGE_DEPTH)) then begin
                      {*** have reached horizon node of tree: score points for piece taken ***}
                      {*** but assume own piece will be taken if enemy's piece is protected ***}
                      if Movement.PieceTaken.image <> BLANK then begin
                          AttackedBy (Movement.ToRow, Movement.ToCol, Attacked, Protected);
                          if Attacked > 0 then
                              LineScore := Score - CapturePoints[Movement.PieceMoved.image]
                              LineScore := Score;
                      end else
                          LineScore := Score;
                  end else begin
                      {*** new cutoff value ***}
                      STCutOff := Score - BestScore;
                      {*** recursive call for enemy's best countermoves score ***}
                      LineScore := Score - Search (EnemyColor[Turn], STCutOff,
                                                   Depth - 1, AllTakes and TakingPiece);
              {*** remember player's maximum net score ***}
              if (LineScore > BestScore) then BestScore := LineScore;
          {*** un-do the move and check for cutoff ***}
          UnMakeMove (Movement);
          if BestScore >= CutOff then j := 0 else j := j - 1;
      if (BestScore = STALE_SCORE) then
          BestScore := -STALE_SCORE;   {stalemate means both players lose}
      if NoMoves then
          {*** player cannot move ***}
          if Player[Turn].InCheck then
              {*** if he is in check and cannot move, he loses ***}
              BestScore := - CapturePoints[KING]
              {*** if he is not in check, then both players lose ***}
              BestScore := -STALE_SCORE; {prefer stalemate to checkmate}
      Search := BestScore;
    end; {Search}

See also

Pascal Engines


Forum Posts

External Links


Up one Level