Author: Steven Edwards
Date: 01:51:58 02/09/04
Circumstances have limited the time available for work on Symbolic recently, but
at least I have gotten the Lisp interpreter in better shape and have written the
beginning of the Lisp source for Symbolic itself. A copy is included here,
which will no doubt give even more evidence to some that Lisp is hard to
understand.
;;;; S1.lsp: Symbolic ChessLisp move selection
(defconstant ProgramAuthor "S. J. Edwards")
(defconstant ProgramDate "2004.02.08")
;; Inputs
(defvar TheInputFEN nil "The FEN for the root of the search")
(defvar TheInputHist nil "The history Pos/Move list for the root of the
search")
;; Outputs
(defvar TheSelectedMove nil "The search result move, if any")
(defvar TheError nil "The search result error, if any")
;; Global tree items
(defvar TheTree nil "The search tree")
(defvar TheRootNode nil "The root node of the search tree")
(defvar TheRootPos nil "The root position of the search tree")
(defvar TheRootMoves nil "The root moves of the search tree")
(defvar TheRootMoveCount 0 "The number of root moves of the search tree")
;; Functions
(defun SelectMove (MyRootFEN MyRootHist)
"Select a chess move from the given root FEN and history"
(ResetGlobals)
(let ((NoFault t))
(when NoFault
(if (not (string? MyRootFEN))
(progn
(setf TheError "SelectMove: MyRootFEN must be a string")
(setf NoFault nil))
(progn
(setf TheInputFEN MyRootFEN))))
(when NoFault
(if (not (list? MyRootHist))
(progn
(setf TheError "SelectMove: MyRootHist must be a list")
(setf NoFault nil))
(progn
(setf TheInputHist MyRootHist))))
(when NoFault
(when (null? (PosValFromFEN TheInputFEN))
(setf TheError "SelectMove: MyRootFEN is invalid")
(setf NoFault nil)))
(when NoFault
(InitializeTreeGlobals MyRootFEN)
(when (zero? TheRootMoveCount)
(setf TheError "SelectMove: No moves available")
(setf NoFault nil)))
(when NoFault
(setf TheSelectedMove (SelectMoveAux))
(when (null? TheSelectedMove)
(setf TheError "SelectMove: No move was found")
(setf NoFault nil)))
(when NoFault
(princ "The selected move is: ")
(princ (getprop TheSelectedMove 'SAN))
(terpri))
(if NoFault TheSelectedMove TheError)))
(defun SelectMoveAux ()
"Select a chess move from the established global variables"
;; Is only one move available?
(when (null? TheSelectedMove)
(when (one? TheRootMoveCount)
(setf TheSelectedMove (car TheRootMoves))))
;; Is a checkmating move available?
(when (null? TheSelectedMove)
(setf TheSelectedMove (FirstCheckmatingMove TheRootNode)))
;; Is a winning tablebase move available?
(when (null? TheSelectedMove)
(setf TheSelectedMove (FirstWinningTablebaseMove TheRootNode)))
;; Is a decent book move available?
(when (null? TheSelectedMove)
(setf TheSelectedMove (DecentBookMove TheRootNode)))
;; Randomly pick a move
(when (null? TheSelectedMove)
(setf TheSelectedMove (RandomElement TheRootMoves)))
TheSelectedMove)
(defun ResetGlobals ()
"Reset global variables at the start of a search"
(setf TheSelectedMove nil)
(setf TheError nil)
(setf TheTree nil)
(setf TheRootNode nil)
(setf TheRootPos nil)
(setf TheRootMoves nil)
(setf TheRootMoveCount 0))
(defun InitializeTreeGlobals (MyRootFEN)
"Initialize global variables at the start of a search from the input"
(setf TheTree (TreeFromFEN MyRootFEN))
(setf TheRootNode (getprop TheTree 'RootNode))
(setf TheRootPos (getprop TheRootNode 'Position))
(setf TheRootMoves (getprop TheRootNode 'Moves))
(setf TheRootMoveCount (getprop TheRootNode 'DesCount))
TheTree)
(defun FirstCheckmatingMove (MyNode)
"Return the first checkmating move, if any, from a node"
(ExpandNode MyNode)
(let ((CheckmatingMove nil) (RemainingMoves (getprop MyNode 'Moves)))
(dowhile (and (null? CheckmatingMove) RemainingMoves)
(if (Checkmating? (car RemainingMoves))
(setf CheckmatingMove (car RemainingMoves))
(setf RemainingMoves (cdr RemainingMoves))))
CheckmatingMove))
(defun DecentBookMoveNode? (MyNode)
"Is a node a decent book move node?"
(and
(getprop MyNode 'IsBook)
(< (getprop MyNode 'BookExpectation) 0.0)))
(defun CollectDecentBookMoveSubnodes (MyNode)
"Return a list of decent book subnodes from a node"
(ExpandNode MyNode)
(let ((Collection nil) (Subnodes (getprop MyNode 'Subnodes)))
(dolist (Subnode Subnodes)
(when (DecentBookMoveNode? Subnode)
(setf Collection (cons Subnode Collection))))
Collection))
(defun DecentBookMove (MyNode)
"Return a decent book move from a node, if any"
(let ((BookMove nil) (Collection (CollectDecentBookMoveSubnodes MyNode)))
(when Collection
(setf BookMove (RandomElement Collection)))
BookMove))
(defun WinningTablebaseNode? (MyNode)
"Is a node a winning tablebase node?"
(and
(getprop MyNode 'IsTablebase)
(LosingScore? (getprop MyNode 'TablebaseScore))))
(defun FirstWinningTablebaseMove (MyNode)
"Return the first winning tablebase move from a node, if any"
(ExpandNode MyNode)
(let ((WinningTablebaseMove nil) (RemainingSubnodes (getprop MyNode
'Subnodes)))
(dowhile (and (null? WinningTablebaseMove) RemainingSubnodes)
(if (WinningTablebaseNode? (car RemainingSubnodes))
(setf WinningTablebaseMove (getprop (car RemainingSubnodes)
'PriorMove))
(setf RemainingSubnodes (cdr RemainingSubnodes))))
WinningTablebaseMove))
(defun RandomElement (MyList)
"Return a randomly selected element from a list"
(nth (random (length MyList)) MyList))
;;;; End of S1.lsp
This page took 0.01 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.