patterncsharpModerate
Enum, constants, or other to represent chess pieces
Viewed 0 times
piecesrepresentenumchessotherconstants
Problem
I'm learning C# and I decided to write a chess program to help me practice the concepts I'm learning in my book. I started the Board class tonight, which is going to handle 1) the board state and 2) checking if moves are legal.
I feel like I need to give careful consideration to how I represent the board. I started with a list of constants:
Then I realized I could use an
I then go to declare the board array and I had to use this ugly-looking monstrosity:
```
private sbyte[,] board =
{
{(sbyte)Piece.BROOK, (sbyte)P
I feel like I need to give careful consideration to how I represent the board. I started with a list of constants:
// CONSTANTS
private const sbyte EMPTYSQUARE = 0;
private const sbyte WKING = 1;
private const sbyte WQUEEN = 2;
private const sbyte WROOK = 3;
private const sbyte WBISHOP = 4;
private const sbyte WKNIGHT = 5;
private const sbyte WPAWN = 6;
private const sbyte BKING = 7;
private const sbyte BQUEEN = 8;
private const sbyte BROOK = 9;
private const sbyte BBISHOP = 10;
private const sbyte BKNIGHT = 11;
private const sbyte BPAWN = 12;
private const sbyte GAMEINPROGRESS = 0;
private const sbyte CHECKMATEWHITE = 1;
private const sbyte CHECKMATEBLACK = 2;
private const sbyte NOLEGALMOVESDRAW = 3;
private const sbyte THREEMOVEDRAW = 4;
private const sbyte FIFTYMOVEDRAW = 5;
private const sbyte WHITERESIGNED = 6;
private const sbyte BLACKRESIGNED = 7;
// VARIABLES
private sbyte[,] board =
{
{9, 11, 10, 8, 7, 10, 11, 9},
{12,12, 12, 12, 12, 12, 12,12},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{6, 6, 6, 6, 6, 6, 6, 6},
{3, 5, 4, 2, 1, 4, 5, 3}
};Then I realized I could use an
enum here, which I hear is good practice so you don't go mixing up your "magic numbers":private enum Piece
{
EMPTY, WKING, WQUEEN, WROOK, WBISHOP, WKNIGHT, WPAWN, BKING, BQUEEN, BROOK, BBISHOP, BKNIGHT, BPAWN
}
private enum State
{
GAMEINPROGRESS, CHECKMATEWHITE, CHECKMATEBLACK, NOLEGALMOVEDRAW, THREEMOVEDRAW, FIFTYMOVEDRAW, WHITERESIGNED, BLACKRESIGNED
}I then go to declare the board array and I had to use this ugly-looking monstrosity:
```
private sbyte[,] board =
{
{(sbyte)Piece.BROOK, (sbyte)P
Solution
I think it definitely makes sense to use an object hierarchy here. What's the difference between a black and a white pawn? Its colour! (which will affect which way it can move relative to the board).
All pieces must have exactly one colour, and we have two to chose from:
As we've already reasoned, all pieces have to have a colour and unless you've got a defective set, none of the pieces can change colour midway through. Sounds like we have an invariant that we want all pieces to obey. We can lock that up with a base class:
By making the piece class abstract, we are saying "you can't have a generic Piece, you have to have a specialized subclass". Let's see what that some of those might look like:
Now you can start playing around with a board. To be completely honest, I haven't thought enough about it to figure out how I'd really want it to look but something like the following would be enough to get along with.
}
Any common behaviour you should find behind all pieces you should add it to the base class
Edit
I thought the above made it clear that I think there should be an abstract method on the piece class that deals with movement. I didn't commit to making a suggestion on the signature of the method because I haven't seen what you're doing currently. I have the impression OP intends on "moving pieces" entirely within the board class.
All pieces must have exactly one colour, and we have two to chose from:
public enum PieceColour
{
White = 0,
Black = 1
}As we've already reasoned, all pieces have to have a colour and unless you've got a defective set, none of the pieces can change colour midway through. Sounds like we have an invariant that we want all pieces to obey. We can lock that up with a base class:
public abstract class Piece
{
private readonly PieceColour colour;
public PieceColour Colour { get { return colour; } }
protected Piece(PieceColour colour)
{
this.colour = colour;
}
}By making the piece class abstract, we are saying "you can't have a generic Piece, you have to have a specialized subclass". Let's see what that some of those might look like:
public class Pawn : Piece
{
public Pawn(PieceColour colour)
: base(colour)
{
}
}
public class Rook : Piece
{
public Rook(PieceColour colour)
: base(colour)
{
}
}
public class Knight : Piece
{
public Knight(PieceColour colour)
: base(colour)
{
}
}Now you can start playing around with a board. To be completely honest, I haven't thought enough about it to figure out how I'd really want it to look but something like the following would be enough to get along with.
Tuple is just a convenient wrapper around two ints (the coordinates of a space).public class Board
{
private Dictionary, Piece> currentState;
public static Board CreateNewBoard()
{
var board = new Board();
board.currentState = new Dictionary, Piece>
{ // x, y
{ new Tuple(0, 0), new Rook(PieceColour.White) },
{ new Tuple(1, 0), new Knight(PieceColour.White) }
// etc.
};
return board;
}
}}
Any common behaviour you should find behind all pieces you should add it to the base class
Piece, for example they can all move...Edit
I thought the above made it clear that I think there should be an abstract method on the piece class that deals with movement. I didn't commit to making a suggestion on the signature of the method because I haven't seen what you're doing currently. I have the impression OP intends on "moving pieces" entirely within the board class.
Code Snippets
public enum PieceColour
{
White = 0,
Black = 1
}public abstract class Piece
{
private readonly PieceColour colour;
public PieceColour Colour { get { return colour; } }
protected Piece(PieceColour colour)
{
this.colour = colour;
}
}public class Pawn : Piece
{
public Pawn(PieceColour colour)
: base(colour)
{
}
}
public class Rook : Piece
{
public Rook(PieceColour colour)
: base(colour)
{
}
}
public class Knight : Piece
{
public Knight(PieceColour colour)
: base(colour)
{
}
}public class Board
{
private Dictionary<Tuple<int, int>, Piece> currentState;
public static Board CreateNewBoard()
{
var board = new Board();
board.currentState = new Dictionary<Tuple<int, int>, Piece>
{ // x, y
{ new Tuple<int, int>(0, 0), new Rook(PieceColour.White) },
{ new Tuple<int, int>(1, 0), new Knight(PieceColour.White) }
// etc.
};
return board;
}
}Context
StackExchange Code Review Q#73721, answer score: 11
Revisions (0)
No revisions yet.