Mercurial > projects > doodle
view doodle/main/prog/chess.d @ 132:bc5baa585b32
Updated to dmd 2.060
author | David Bryant <bagnose@gmail.com> |
---|---|
date | Thu, 02 Aug 2012 15:32:43 +0930 |
parents | 1bc3475624d3 |
children |
line wrap: on
line source
// // Notes: // ply = half move (ie black or white's half of the move) import std.stdio; import std.ascii; import std.traits; import std.range; enum Side { White, Black } enum Name { King, Queen, Rook, Bishop, Knight, Pawn } struct Piece { Side side; Name name; } string toString(Piece piece) { return [ [ "\u2654", "\u2655", "\u2656", "\u2657", "\u2658", "\u2659" ], [ "\u265A", "\u265B", "\u265C", "\u265D", "\u265E", "\u265F" ] ] [piece.side][piece.name]; } // // // enum File { _A, _B, _C, _D, _E, _F, _G, _H } char toChar(File f) { return "abcdefgh"[f]; } enum Rank { _1, _2, _3, _4, _5, _6, _7, _8 } char toChar(Rank r) { return "12345678"[r]; } struct Coord { File file; Rank rank; } string toString(in Coord coord) { return toChar(coord.file) ~ "+" ~ toChar(coord.rank); } // // // struct Board { struct Square { this(in Side side, in Name name) { occupied = true; piece = Piece(side, name); } bool occupied = false; Piece piece; // valid if occupied } this(in Square[8][8] squares_) { squares = squares_; } Square square(Coord coord) const { return squares[coord.file][coord.rank]; } private: Square * at(Coord coord) { return &squares[coord.file][coord.rank]; } void add(Piece piece, Coord coord) { auto square = at(coord); if (square.occupied) { // error } else { square.occupied = true; square.piece = piece; } } void remove(Coord coord) { auto square = at(coord); if (square.occupied) { square.occupied = false; } else { // error } } void move(Coord source, Coord dest) { auto source_sq = at(source); auto dest_sq = at(dest); if (source_sq.occupied && !dest_sq.occupied) { source_sq.occupied = false; dest_sq.occupied = true; dest_sq.piece = source_sq.piece; } else { // error } } Square[8][8] squares = [ [ Square(Side.White, Name.Rook), Square(Side.White, Name.Pawn), Square(), Square(), Square(), Square(), Square(Side.Black, Name.Pawn), Square(Side.Black, Name.Rook) ], [ Square(Side.White, Name.Knight), Square(Side.White, Name.Pawn), Square(), Square(), Square(), Square(), Square(Side.Black, Name.Pawn), Square(Side.Black, Name.Knight) ], [ Square(Side.White, Name.Bishop), Square(Side.White, Name.Pawn), Square(), Square(), Square(), Square(), Square(Side.Black, Name.Pawn), Square(Side.Black, Name.Bishop) ], [ Square(Side.White, Name.Queen), Square(Side.White, Name.Pawn), Square(), Square(), Square(), Square(), Square(Side.Black, Name.Pawn), Square(Side.Black, Name.Queen) ], [ Square(Side.White, Name.King), Square(Side.White, Name.Pawn), Square(), Square(), Square(), Square(), Square(Side.Black, Name.Pawn), Square(Side.Black, Name.King) ], [ Square(Side.White, Name.Bishop), Square(Side.White, Name.Pawn), Square(), Square(), Square(), Square(), Square(Side.Black, Name.Pawn), Square(Side.Black, Name.Bishop) ], [ Square(Side.White, Name.Knight), Square(Side.White, Name.Pawn), Square(), Square(), Square(), Square(), Square(Side.Black, Name.Pawn), Square(Side.Black, Name.Knight) ], [ Square(Side.White, Name.Rook), Square(Side.White, Name.Pawn), Square(), Square(), Square(), Square(), Square(Side.Black, Name.Pawn), Square(Side.Black, Name.Rook) ] ]; } void dump(in Board board) { bool light_square = true; foreach_reverse(r; EnumMembers!Rank) { write(toChar(r)); foreach(f; EnumMembers!File) { if (light_square) { write("\033[47m"); } else { write("\033[40m"); } Board.Square square = board.square(Coord(f, r)); if (square.occupied) { write(toString(square.piece)); } else { write(" "); } light_square = !light_square; } writeln("\033[0m"); light_square = !light_square; } write(" "); foreach(f; EnumMembers!File) { writef("%s", toChar(f)); } writeln(""); } // // // enum KingState { Safe, Check, CheckMate } class Game { struct SideState { KingState kingState; bool kingMoved; bool queenRookMoved; bool kingRookMoved; } struct Ply { this(Coord source_, Coord dest_) { source = source_; dest = dest_; } Coord source; Coord dest; } @property Board board() { return _board; } struct Flags { bool check; bool mate; } // Default initial pieces, white to play this () { } // Restore a previous game this (Board board, Flags whiteFlags, Flags blackFlags, Side nextPly) { _board = board; _nextPly = nextPly; } enum Acceptance { Normal, Check, Mate, Illegal } Acceptance apply(in Ply ply) { auto source = _board.square(ply.source); auto dest = _board.square(ply.dest); /+ auto sq1 = square(update.source); auto sq2 = square(update.dest); if (sq1.piece == Piece.Pawn && update.dest.file != update.source.file) { // en-passant } else if (sq1.piece == Piece.King && update.dest.file - update.source.file > 1) { // castle } +/ return Acceptance.Normal; } private { struct PieceState { bool uncaptured; Coord coord; // valid if uncaptured } Board _board; Side _nextPly; SideState _whiteSideState; PieceState[8] _whitePieceState; SideState _blackSideState; PieceState[8] _blackPieceState; } } void main(string[] args) { Board board; dump(board); /+ Game game; +/ }