3. Python → Pascal Translation Table
3.1 Data Types
@dataclass |
RECORD |
Pascal records are value types |
list[TPos] |
TPosArray = array of TPos |
Dynamic array |
set() |
ARRAY OF BOOLEAN |
Boolean grid is O(1) lookup |
dict[str,int] |
RECORD or ARRAY |
Use typed arrays when keys are known |
Optional[T] |
T + Found: Boolean |
Pass Found as out parameter |
int |
Integer |
32-bit signed |
float |
Double |
64-bit IEEE 754 |
str |
AnsiString (with {$H+}) |
Pascal strings are 1-indexed |
bool |
Boolean |
True / False |
None |
Depends on type |
Use sentinel value or Found flag |
Enum |
(gpSetup, gpPlaying, gpResults) |
Pascal enumerated type |
3.2 Control Flow
for i in range(n): |
for i := 0 to n-1 do |
for x in list: |
for i := 0 to Length(list)-1 do then
list[i] |
while True: |
repeat ... until False; or
while True do |
break |
Break |
continue |
Continue |
if x is None: |
if not Found then or sentinel check |
pass |
{ nothing } or dummy begin end |
try/except |
try ... except ... end |
3.3 Functions and Procedures
def foo() -> None: |
procedure Foo; |
def foo() -> int: |
function Foo: Integer; |
return x |
Result := x (preferred) or Foo := x |
def foo(x: int = 5): |
Two overloaded procedures (no defaults in TP/FPC) |
*args |
Not directly supported — use array parameter |
lambda x: x*2 |
Inline function or local nested function |
out param |
var Param or out Param (FPC
extension) |
3.4 Classes
class Foo: |
TFoo = class(TObject) |
def __init__(self): |
constructor Create(AOwner...); |
def __del__(self): |
destructor Destroy; override; |
self.x |
FX (F-prefix convention for private fields) |
@property |
property X: T read FX write FX; |
isinstance(x, T) |
x is T |
super().__init__() |
inherited Create(...) |
3.5 Dynamic Arrays
{ Python: path = [] }
var Path : TPosArray; { declared, Length = 0 }
{ Python: path.append(pos) }
SetLength(Path, Length(Path)+1);
Path[Length(Path)-1] := Pos;
{ Python: len(path) }
Length(Path)
{ Python: path[0:5] }
{ Pascal: must copy manually or use slice pointer tricks }
{ Python: del path[-1] }
SetLength(Path, Length(Path)-1);
3.6 String Operations
{ Python: f"({r}, {c})" }
Format('(%d, %d)', [R, C])
{ Python: str(n) }
IntToStr(N)
{ Python: float(s) }
StrToFloat(S) { raises exception on error }
StrToFloatDef(S, 0.0) { returns default on error }
{ Python: s.upper() }
UpperCase(S)
{ Python: s.strip() }
Trim(S)
{ Python: ','.join(list) }
{ Pascal: manual loop with string concatenation }
3.7 Math
{ Python: import math / import random }
uses Math, SysUtils;
{ Python: random.random() }
Random { returns 0.0 <= x < 1.0 }
{ Python: random.randint(0, n-1) }
Random(N) { returns 0 <= x < N }
{ Python: random.shuffle(list) }
{ Pascal: Fisher-Yates — see ShuffleIntArray in console source }
{ Python: math.min(a, b) }
Min(A, B) { from Math unit }
{ Python: math.floor(x) }
Trunc(X) { or Floor(X) from Math }
{ Python: round(x) }
Round(X) { banker's rounding in Pascal — watch for .5 cases }
4. Key Algorithm Translations
4.1 Visited Set
# Python — hash set, O(1)
visited: Set[Tuple] = set()
visited.add((r, c, l))
if (r, c, l) in visited:
{ Pascal — boolean grid, O(1), faster and type-safe }
Visited : array of array of array of Boolean;
Visited[L][R][C] := True;
if Visited[L][R][C] then
4.2 Valid Moves
# Python
def valid_moves(pos, visited, rows, cols, levels):
r, c, l = pos
return [(r+dr, c+dc, l+dl)
for dr, dc, dl in KNIGHT_MOVES_3D
if 0<=r+dr<rows and 0<=c+dc<cols
and 0<=l+dl<levels
and (r+dr,c+dc,l+dl) not in visited]
{ Pascal }
function CountMoves(const Pos: TPos; const Vis: TBoolGrid): Integer;
var i, nr, nc, nl : Integer;
begin
Result := 0;
for i := 0 to MOVE_COUNT-1 do
begin
nr := Pos.R + KnightMoves[i].DR;
nc := Pos.C + KnightMoves[i].DC;
nl := Pos.L + KnightMoves[i].DL;
if InBounds(nr,nc,nl) and not Vis[nl][nr][nc] then
Inc(Result);
end;
end;
4.3 Warnsdorff’s Rule
# Python — list comprehension + min()
return min(candidates,
key=lambda p: len(valid_moves(p, visited|{p},
rows, cols, levels)))
{ Pascal — explicit loop, same O(24²) complexity }
BestScore := MaxInt;
for j := 0 to NCands-1 do
begin
i := Cands[Shuffled[j]];
Next := ...;
Vis[Next.L][Next.R][Next.C] := True; { temporarily mark }
Score := CountMoves(Next, Vis);
Vis[Next.L][Next.R][Next.C] := False; { unmark }
if Score < BestScore then
begin
BestScore := Score;
Result := Next;
Found := True;
end;
end;
4.4 Color Grid Initialization
# Python
self.board = [
[[random.choice(COLOR_NAMES) if random.random() < 0.22 else None
for _ in range(cols)]
for _ in range(rows)]
for _ in range(levels)]
{ Pascal }
procedure InitBoardColors(var Colors: TColorGrid; const Cfg: TConfig);
var l, r, c : Integer;
begin
SetLength(Colors, Cfg.Levels);
for l := 0 to Cfg.Levels-1 do
begin
SetLength(Colors[l], Cfg.Rows);
for r := 0 to Cfg.Rows-1 do
begin
SetLength(Colors[l][r], Cfg.Cols);
for c := 0 to Cfg.Cols-1 do
if Random(100) < 20 then Colors[l][r][c] := Random(COLOR_COUNT)
else Colors[l][r][c] := -1; { -1 = no color }
end;
end;
end;
6. Compiler Directives Reference
{$MODE OBJFPC} { Enable Object Pascal with Free Pascal extensions }
{$H+} { Use AnsiString (heap-allocated) not ShortString }
{$RANGECHECKS ON} { Catch array out-of-bounds at runtime (debug) }
{$RANGECHECKS OFF}{ Turn off for production build (faster) }
{$O+} { Optimize (same as -O2 on command line) }
{$IFDEF WINDOWS} { Conditional compilation for Windows }
{$IFDEF UNIX} { Conditional compilation for Linux/Mac }
7. GitHub Module Structure
nabs-platform/
├── python/
│ ├── knights_tour_3d.py ← Phase 1 template (DONE)
│ └── requirements.txt
├── browser/
│ ├── knights_tour_browser.html ← Browser game (DONE)
│ └── nabs_demo.html ← NABS UI demo (DONE)
├── pascal/
│ ├── knights_tour_3d.pas ← Console version (DONE)
│ ├── knights_tour_gui.pas ← Lazarus GUI unit (DONE)
│ ├── knights_tour_gui.lpr ← Lazarus project file (DONE)
│ └── PASCAL_NOTES.md ← This file (DONE)
├── cpp/ ← Phase 3 (next)
│ ├── knights_tour_3d.cpp
│ └── CMakeLists.txt
├── THEORY.md ← WFFs, predicate calculus (DONE)
└── README.md ← Project overview (DONE)
EFE Health Systems · NABS Platform · Toledo, Ohio Pascal
implementation complete — C++ Phase 3 next