Title: Submitted by Azhar Ali
1Ax Chess, an efficient representation of Chess
targeted for a chess AI program and a mobile
device
Submitted by Azhar Ali Advisor Dr. Mohammad
Zubair
2Contents
- Objective
- Overview
- Motivation
- Need for an Efficient Chess representation
- Why yet another one?
- Technologies Used
- Approach
- Object Oriented Design
- Compile Time Programming
- Screenshots
- Lessons Learned
- Other Ideas (Memory Management)
- References
3Objective
- Ax Chess, an efficient representation of Chess
-
- Concentrate on using different programming
paradigms - Write Concise code, without loosing efficiency.
- Use compile-time programming techniques
- Learn the constraints related to programming on
smartphones, and - accordingly port Ax Chess to Symbian Platform
(S60 devices).
4Overview of Ax Chess
- Valid Moves
- All valid piece moves, enpassant, castling,
pawn promotion, etc - Checkmate
- One players King is under attack and cant
escape the threat - Stalemate
- The players King is not under threat, but
there arent any legal moves to play - Threefold repetition
- This is a situation occurs when the same
position occurs three times. - In this situation the player can claim a draw.
- 50 move rule
- Minimal Draw Algorithm
- Undo Redo
- Chess API
5Need for an Efficient Chess representation
Working of a chess AI program
- When the game begins, white has choice of 20
moves. - Followed by a whites move, black has another
20 moves in reply, thus we - get 400 different positions after the first
move by both sides. The number - grows to 20,000 after two moves. Minimax
algorithm works this way, and - several techniques are used for pruning such
trees. - For each move in the such trees, the chess AI
needs to know the result - such as checkmate, stalemate, etc. And also
it needs the support of Undo - operation while backtracking the tree.
- Deep Fritz 10 can see 18-ply (i.e., 9 moves on
both sides) deep. - This mean the chess representation's
functions would be executed - more than a million times.
6(No Transcript)
7Why yet another one?
There are a lot of excellent chess playing
softwares like Fritz, Extreme, Crafty, etc for PC
and Chess Tiger, etc., for Smart Phones. A lot of
effort is going on to improve these softwares. To
get into such development stream one needs
experience like programming a simple chess AI and
understanding the real efficiency concerns which
are involved in the chess AI computations. The
aim of this project is to get such experience.
8Technologies/Tools used and why?
- C - flexible, and it allows me to think in
more than one paradigms - STL, BOOST - more efficient, better portability,
concise code - better thinking process
because of high level constructs, - automatic memory
management without sacrificing - effciency, support for
custom memory allocators - Symbian C
- Ax Chess tested on Gentoo 2.6, Ubuntu 6.10 and
Windows XP - emacs, g, gdb, make, cppunit, gprof
- Symbian 8.0a SDK, Metrowerks CodeWarrior,
Microsoft Visual Studio 2003
9Object Oriented Design
Piece bool moveValid(..) void move(..)
Board Piece pieces88
Rook bool moveValid(..) void move(..)
Knight bool moveValid(..) void move(..)
GameManager
Bishop bool moveValid(..) void move(..)
Queen bool moveValid(..) void move(..)
King bool moveValid(..) void move(..)
Pawn bool moveValid(..) void move(..)
10An example from my project about different
programming paradigms, and the support offered by
C.
An Efficient solution for moveValid()
enum PieceID WPAWN, WKNIGHT, WBISHOP, WROOK,
WQUEEN, WKING, BPAWN, BKNIGHT, BBISHOP,
BROOK, BQUEEN, BKING, NONE
bool moveValid(const Position from, const
Position to) PieceID id
board.piece(from) if (id WROOK id
BROOK) return rookMoveValid(from, to,
board) else if (id WKNIGHT id
BKNIGHT) return knightMoveValid(from, to,
board) else if (id WBISHOP id
BBISHOP) return bishopMoveValid(from, to,
board) else if (id WQUEEN id
BQUEEN) return queenMoveValid(from, to,
board) else if (id WKING id BKING)
return kingMoveValid(from, to, board)
else if (id WPAWN id BPAWN) return
pawnMoveValid(from, to, board) return
false
11Object Oriented Design
class Piece public Piece(Color, const
Position) virtual bool moveValid(const
Position, const Board) 0 virtual void
move(const Position, Board)
class Rook public Piece public
Rook(Color, const Position) virtual bool
moveValid(const Position, const Board)
virtual void move(const Position, Board)
class Knight public Piece public
Knight(Color, const Position) virtual bool
moveValid(const Position, const Board)
virtual void move(const Position, Board)
Similarly, Bishop, Queen, King and Pawn classes
12An Elegant solution for moveValid()
class Piece public Piece(Color, const
Position) virtual bool moveValid(const
Position, const Board) 0 virtual void
move(const Position, Board)
bool BoardmoveValid(const Position from,
const Position to) Piece p
board.piece(from) return p
p-gtmoveValid(to, board)
bool moveValid(const Position from, const
Position to) PieceID id
board.piece(from) if (id WROOK id
BROOK) return rookMoveValid(from, to,
board) else if (id WKNIGHT id
BKNIGHT) return knightMoveValid(from, to,
board) else if (id WBISHOP id
BBISHOP) return bishopMoveValid(from, to,
board) else if (id WQUEEN id
BQUEEN) return queenMoveValid(from, to,
board) else if (id WKING id BKING)
return kingMoveValid(from, to, board)
else if (id WPAWN id BPAWN) return
pawnMoveValid(from, to, board) return
false
13Cost of Dynamic Binding
bool BoardmoveValid(const Position from,
const Position to) Piece p
board.piece(from) return p
p-gtmoveValid(to, board)
Object layout of a class derived from Piece
Rook
vtable for Rook
data members
RTTI
vptr
RookmoveValid()
Rookmove()
Compiler generated code for p-gtmoveValid(to,board
)
Note function_offset and vptr_offset known at
compile time load object_address vptr_offset,
reg1 load reg1 function_offset, reg2 call reg2
14A better solution (one less dereference)
enum PieceID WPAWN, WKNIGHT, WBISHOP, WROOK,
WQUEEN, WKING, BPAWN, BKNIGHT, BBISHOP,
BROOK, BQUEEN, BKING, NONE
bool (moveValid12)(const Position, const
Position, const Board)
pawnMoveValid, knightMoveValid, bishopMoveValid,
rookMoveValid, queenMoveValid,
kingMoveValid, pawnMoveValid,
knightMoveValid, bishopMoveValid,
rookMoveValid, queenMoveValid, kingMoveValid
bool moveValid(const Position from, const
Position to) PieceID id
board.piece(from) return id ! NONE
(moveValidid)(from, to, board)
bool BoardmoveValid(const Position from,
const Position to) Piece p
board.piece(from) return p
p-gtmoveValid(to, board)
15An Elegant and Efficient Solution for
moveValid()
- Equivalent to the if-else version
- Has all the benefits of the if-else version and
none of the drawbacks
enum PieceID WPAWN, WKNIGHT, WBISHOP, WROOK,
WQUEEN, WKING, BPAWN, BKNIGHT, BBISHOP,
BROOK, BQUEEN, BKING, NONE
typedef boosttuple lt PawnMoveValid,
KnightMoveValid, BishopMoveValid, RookMoveValid,
QueenMoveValid, KingMoveValid, PawnMoveValid,
KnightMoveValid, BishopMoveValid,
RookMoveValid, QueenMoveValid, KingMoveValid
gt TUPLE TUPLE moveValidFunctors bool
moveValid(const Position from, const Position
to) PieceID id board.piece(from)
return id ! NONE call(moveValidFunctors, id,
from, to, board)
16Compile time Programming
bool moveValid(const Position from, const
Position to) PieceID id
board.piece(from) return id ! NONE
call(moveValidFunctors, id, from, to, board)
The compiler translates the line
call(moveValidFunctors, id, from, to, board) in
above code to the following
return id 11 ? KingMoveValid(from, to,
board) (id 10 ? QueenMoveValid(from, to,
board) ... (id 0 ? PawnMoveValid(from,
to, board)))...)
The above call construct is written using
Templates and partial Template specialization
17Chess API
enum MoveResult INVALIDMOVE, VALIDMOVE, CHECK,
CHECKMATE, STALEMATE, DRAW,
THREEFOLDREPETITION, FIFTYMOVERULE // string
format d2d4, e7e5, b1c3, etc., MoveResult
move(const string) // position (0, 0) (0, 7)
gt black rook, (7, 0) (7, 7) gt white
rook MoveResult move(const Move) bool
whiteTurn() const PieceID chessBoardIterator()
void undo(size_t nmoves 1) void redo(size_t
nmoves 1) void pawnPromoter(PieceID
()(PieceID)) void recordPossibleMoves(const
Position, vectorltPositiongt) void
generate_moves(vectorltMovegt)
18Screenshots
19Lessons Learned
- Concepts of C
- (Internal representation of Objects, Templates,
Compile-time computations, - Policy based design, etc)
- Idea about different programming paradigms and
efficiency considerations - STL and BOOST
- Memory Management
- Things related to C programming on Symbian OS
- Symbian OS Internals
- Symbian OS Exceptions the Cleanup Stack
- Descriptors and Dynamic Arrays and Buffers
- Event-Driven Multitasking using Active Objects
- Symbian OS Threads and Processes
- Graphics for Display, Interaction, etc
20Symbian
- Constraints in programming on a Symbian
Enviroment, when compared to a PC - different way of exception handling
- low memory
- lack of STL and BOOST
- Symbian C Compiler is not so sophisticated to
do - Compile time computations
- The port of Ax Chess is done considering all
these aspects
21 Other Ideas I got during the course of this
project. Memory Management
- Datastructures provided by STL are used, which
currently manage memory automatically. - Internally they call new/delete for memory
allocation and deallocation. - The above mentioned dynamic memory
allocators/dealloactors matter when efficieny is - concerned. For example Each "new" operation
executes a OS call to get memory allocated - from free store, and each "delete" involves in
returning the allocated memory to the free - pool. These are costly operations. And using
"new/delete"s frequently in a chess AI program - is going to cost too much.
- I have noticed a certain situation in Chess AI,
where at one time during the computers turn to - play, the Chess AI is very busy searching the
best possible move and when it is the opponents - turn the chess AI is idle. This situation could
be exploited for memory management. - I wrote a Garbage Collector that has the
following characteristics. - Uses Mark Sweep (with Compaction) algorithm.
- Has allocation speed approximately equal to
that of Stack's. - The data structures in STL can be configured
with custom memory allocators. I can integrate - my garbage collector with my code, so that the
chess AI program uses a lot of memory while
22References
- Bjarne Stroustrup, The C Programming
Language - Mathew H. Austern, Generic Programming and the
STL - Vandevoorde Josuttis, C Templates
- Andrie Alexandrescu, Modern C Design
- Scott Meyers, Effective C, More Effective
C, Effective STL - Jo Stichbury, Symbian OS Explained Effective
C Programming for - Smartphones
- Richard Harrison, Symbian OS C for Mobile
Phones