An early beta should be available by the end of this year.
The ReadMe file:
This is the ReadMe file version v2010.07.22 for the ChessLisp interpreter.
Copyright (C) 2010 by chessnotation@me.com (Some rights reserved)
License: Creative Commons Attribution-Share Alike 3.0
See: http://creativecommons.org/licenses/by-sa/3.0/
Caution: No warranty; use at your own risk.
Abstract:
ChessLisp is a general purpose Lisp which also contains features designed for chess programming. The general purpose features of ChessLisp are taken largely from Common Lisp; some features of Scheme are also present. The chess specific features are intended for abstraction, encapsulation, and execution efficiency in the chess application domain. The ChessLisp interpreter is realized as a portable ANSI C++ application that's simple to install and to operate.
General language features:
ChessLisp features are adopted from Common Lisp; a programmer with just about any Lisp experience can become familiar with ChessLisp without excessive effort. Some Common Lisp programs can run under the ChessLisp interpreter without modification while others can be easily and sometimes automatically changed to run. In most cases where there are differences between Common Lisp and ChessLisp, the ChessLisp functionality is a subset of the corresponding Common Lisp features.
One set of differences between ChessLisp and Common Lisp is that the system function predicate names are revised; they are the more sensible, Scheme-like names with a trailing question mark. Examples: atom? list? null? zero? positive? etc. Those who prefer to use the old style predicate names can write wrapper functions or macros.
ChessLisp, unlike just about all older Lisps, is case specific throughout.
The numeric types in ChessLisp are a subset of the Common Lisp numeric types. ChessLisp does not have a built-in complex type, it does not have a rational type, and it does not have arbitrary precision integers. While these types could be added, they are not in the initial release as their general utility in the chess domain is limited or nonexistent. ChessLisp does have a single floating point numeric type that uses the host C++ "double" for its realization. The ChessLisp single integer type is the 64 bit signed integer that uses the host C++ "long long int" for its realization. As might be guessed, the 64 bit integer type is extensively used in the chess specific language feature set for efficient bitboard representation.
There is no ChessLisp compiler in the initial release.
Chess specific language features:
The chess specific functions are easily distinguished from the rest of the ChessLisp functions as the former all start with an upper case letter while the latter all start with a lowercase letter (or a digit or some punctuation character).
ChessLisp constants are present for enumerations of chess scalar types. These types include: color, piece, man (color/piece combinations), ranks, files, squares, castlings, flanks, quadrants, move special cases (regular, en passant, kingside castling, queenside castling, promotion to a knight, promotion to a bishop, promotion to a rook, promotion to a queen), game results, game terminations, draw conditions, annotation flags, and PGN tags. Other types may be added as needed. Composition and decomposition functions are included as appropriate.
ChessLisp also has a Score scalar type and associated functions. The basic score quantum is the millipawn. Special Score values include MateIn<n>, LoseIn<n> (LoseIn0 is a synonym for Checkmated), DrawScore, IllegalScore, PosInf, and NegInf.
ChessLisp has a 64 bit Hash type for Zobrist hashing along with the appropriate functions for mapping a position or an entire game to a hash value.
ChessLisp structures are present for all commonly used chess classes. These structures include: BasicMove (from-square, to-square, from-man, to-man, special-case, and move-flags), Move (BasicMove plus a score), Board, FenScalars (active-color, castlings, ep-target, halfmove-counter, fullmove-number), FenPosition (a Board plus FenScalars), Bitboard (realized as a 64 bit integer), BBDB (a bitboard database), BasicPosition (FenPosition plus a BBDB), Position (BasicPosition plus a move and hash histories), PgnTagPair, PgnTagSet (a list of PgnTagPairs), Game (PgnTagSet plus a Position), and GameCollection. All of these structures have appropriate read and write routines for accessing formatted storage.
The basic routines for playing and unplaying moves are ExecuteMove and RetractMove. A Position object may be scrolled back and forth as desired. The Position structure and its many routines handle all the low level details.
Predicate functions for Position objects include: IsInitialPosition? IsDraw? IsRepeated? IsDrawByRepetition? IsDrawByStalemate? IsDrawByInsufficientMaterial? IsDrawByFiftyMoveRule? IsIsGameOver? IsLegal? IsCheck? IsCheckmate? IsMateIn1? and others as needed.
The basic move generator is GenerateMoves. Variants include: GenerateGainers (captures and promotions), GenerateHolders (non-gainers), and GenerateChecks. The result of a generation is a simple list of moves.
The number of moves in a position can be calculated by:
Code: Select all
(length (GenerateMoves position))
Code: Select all
(CountMoves position)
Code: Select all
(defun Perft (position plydepth)
(cond
((zero? plydepth) 1)
((one? plydepth) (CountMoves position))
(t
(let ((sum 0) (newplydepth (1- plydepth)))
(dolist (move (GenerateMoves position))
(ExecuteMove position move)
(incf sum (Perft position newplydepth))
(RetractMove position))
sum))))
Code: Select all
(Perft (LoadPosition "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" 4))
Code: Select all
197281
The real fun starts with patterns and pattern matching. More on this later.