Computer Chess Club Archives


Search

Terms

Messages

Subject: Symbolic: sample ChessLisp source: Tracker.lsp

Author: Steven Edwards

Date: 12:57:09 03/03/05


;;;; Tracker.lsp: Target tracking utilities
;;
;; Copyright (C) 2005 by S. J. Edwards / All rights reserved.
;;
;; Revised: 2005.02.27 by chessnotation@yahoo.com
;;
;; Distribution is prohibited except when explicitly permitted by the author.
;; There is no warranty, implied or otherwise.  Use at your own risk.

;; A tracker is a Lisp object that records the origin squares of the chess
;; men in a sequence of positions.  Each man in the current ("now") position
;; can be tracked to a unique origin square in a starting ("org") position.
;; This capability is required to maintain a positive identification of men
;; that remains invariant across move sequences.  It a solution to the
;; classical frame problem within the context of man location.
;;
;; Tracking targets is required by the planner as it needs to be able to
;; identify men that may change position in the dynamic scope of a plan.
;; Also, tracking also supports distinguishing among multiple men of the
;; same color and piece kind.  With tracker support, an enemy man can run
;; but it can't hide.
;;
;; Inside each tracker is a pair of symbol board vectors.  The first records
;; the origin squares (effectively, the unique IDs) of all the men in a
;; position.  This origin vector is indexed by origin square and gives the
;; current square (nil if none) of the man.  The second symbol board acts as
;; the inverse of the first; it is indexed by an occupied square index for
;; the current position and gives the origin square of the man.
;;
;; Also included in a tracker are a pair of pushdown stacks that record
;; delta information; each delta is recorded and executed when a move is
;; played.  When a move is retracted, the delta is popped and then retracted
;; on the two symbol boards.
;;
;; Each delta is a list of one or more substitution directives, and each
;; directive is a square index followed by the old and new contents of the
;; corresponding symbol board.


(defun MakeTracker (MyPV)
  "Construct a new tracker from a position value."
  (let ((Result (make-vector 4)))
    (setf (vref Result 0) (MakeSqSymBoard MyPV)) ; OrgToNow
    (setf (vref Result 1) nil) ; OrgToNow delta list stack
    (setf (vref Result 2) (MakeSqSymBoard MyPV)) ; NowToOrg
    (setf (vref Result 3) nil) ; NowToOrg delta list stack
    Result))


(defun TrackerGetOrgSq (MyTracker MyNowSq)
  "Return the OrgSq for a NowSq in a tracker."
  (vref (vref MyTracker 2) MyNowSq))


(defun TrackerGetNowSq (MyTracker MyOrgSq)
  "Return the NowSq for a OrgSq in a tracker."
  (vref (vref MyTracker 0) MyOrgSq))


(defun TrackerGoDo (MyTracker MyMV)
  "Update a tracker with a move."
  (let ((DeltaPair (TrackerDeltasFromMove MyTracker MyMV)))
    (TrackerGoDoDeltaPair
      MyTracker (first DeltaPair) (second DeltaPair))))


(defun TrackerUnDo (MyTracker)
  "Reverse update a tracker."
  (SymBoardUnDoDelta (vref MyTracker 0) (pop (vref MyTracker 1)))
  (SymBoardUnDoDelta (vref MyTracker 2) (pop (vref MyTracker 3))))


(defun TrackerGoDoDeltaPair (MyTracker MyOrgDelta MyNowDelta)
  "Update a tracker with a an Org/New delta pair."
  (SymBoardGoDoDelta (vref MyTracker 0) (push MyOrgDelta (vref MyTracker 1)))
  (SymBoardGoDoDelta (vref MyTracker 2) (push MyNowDelta (vref MyTracker 3))))


(defun TrackerDeltasFromMove (MyTracker MyMV)
  "Calculate an Org/New delta pair for a tracker and a move."
  (let*
    (
      (OrgDelta nil)
      (NowDelta nil)
      (NowFrSq (FrSqFromMV MyMV))
      (OrgFrSq (vref (vref MyTracker 2) NowFrSq))
      (NowToSq (ToSqFromMV MyMV))
      (OrgToSq (vref (vref MyTracker 2) NowToSq))
    )

    ;; Handle regular capture

    (when OrgToSq
      (push (list OrgToSq NowToSq nil) OrgDelta))

    ;; Handle primary mover

    (push (list OrgFrSq NowFrSq NowToSq) OrgDelta)
    (push (list NowFrSq OrgFrSq nil) NowDelta)
    (push (list NowToSq OrgToSq OrgFrSq) NowDelta)

    ;; Special cases

    (unless (RegularMove? MyMV)
      (cond
        ((EnPassant? MyMV)
          (let*
            (
              (NowVictimSq (EPVictimSq MyMV))
              (OrgVictimSq (vref (vref MyTracker 2) NowVictimSq))
            )
            (push (list OrgVictimSq NowVictimSq nil) OrgDelta)
            (push (list NowVictimSq OrgVictimSq nil) NowDelta)))
        ((CastlingKS? MyMV)
          (if (White? (FrManFromMV MyMV))
            (let ((OrgRookSq (vref (vref MyTracker 2) SqH1)))
              (push (list OrgRookSq SqH1 SqF1) OrgDelta)
              (push (list SqH1 OrgRookSq nil) NowDelta)
              (push (list SqF1 nil OrgRookSq) NowDelta))
            (let ((OrgRookSq (vref (vref MyTracker 2) SqH8)))
              (push (list OrgRookSq SqH8 SqF8) OrgDelta)
              (push (list SqH8 OrgRookSq nil) NowDelta)
              (push (list SqF8 nil OrgRookSq) NowDelta))))
        ((CastlingQS? MyMV)
          (if (White? (FrManFromMV MyMV))
            (let ((OrgRookSq (vref (vref MyTracker 2) SqA1)))
              (push (list OrgRookSq SqA1 SqD1) OrgDelta)
              (push (list SqA1 OrgRookSq nil) NowDelta)
              (push (list SqD1 nil OrgRookSq) NowDelta))
            (let ((OrgRookSq (vref (vref MyTracker 2) SqA8)))
              (push (list OrgRookSq SqA8 SqD8) OrgDelta)
              (push (list SqA8 OrgRookSq nil) NowDelta)
              (push (list SqD8 nil OrgRookSq) NowDelta))))
        (t nil)))

    ;; Return the result

    (list OrgDelta NowDelta)))


(defun DisplayTracker (MyStream MyTracker)
  "Display the org and now square symbol boards of a tracker."
  (DisplaySqSymBoard MyStream (vref MyTracker 0))
  (format MyStream "%n")
  (DisplaySqSymBoard MyStream (vref MyTracker 2))
  (values))



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.