I wanted to use enums, structs, and classes to create small, elegant objects for a basic chess game.
It started with the small squares in the chess board, and created the logic part in the main definition and an extension that is use for rendering
enum Row: Character {
case A = "A"
case B = "B"
case C = "C"
case D = "D"
case E = "E"
case F = "F"
case G = "G"
case H = "H"
}
enum Column: Int {
case One = 1
case Two = 2
case Three = 3
case Four = 4
case Five = 5
case Six = 6
case Seven = 7
case Eight = 8
}
struct Square {
let row: Row
let col: Column
}
extension Square {
var position: SCNVector3 {
get {
// calculated based on row and column
}
}
}
Then I wanted to to something similar for the pieces, so I defined these enums
enum PieceType: String {
case Pawn = "Pawn"
case Rook = "Rook"
case Knight = "Knight"
case Bishop = "Bishop"
case Queen = "Queen"
case King = "King"
}
enum PieceColor {
case White
case Black
}
If this would have been Objective-C then I would have created a base class and used subclasses to override and customize behavior for the specific pieces (pawn, rook, knight, etc.). This class would have been implemneted as a class cluster so that one of the subclasses would have been returned based on the type that was passed to the initliazer
class Piece {
let type: PieceType
let color: PieceColor
var location: Square?
init(_ type: PieceType, color: PieceColor) {
// In ObjC I would have done a class cluster here
}
var possibleSquaresToMoveTo: [Square] {
get {
return [] // base class isn't meant to be used
}
}
}
class Knight: Piece {
init(color: PieceColor) {
super.init(.Knight, color: color)
}
override var possibleSquaresToMoveTo: [Square] {
get {
// calculate possible squares based on the Knights movement pattern and the current location
}
}
}
The main problem I have with this design is that it's still possible to create a base instance, so the Piece initlizer shouldn't really be used.
My next idea was to rethink the possibleSquaresToMoveTo
calculated property. Perhaps the Swift way would be to define a function that maps from the current square to all the possible squares that can be moved to (Square -> [Square]
)
In either case, the Chessboard would have to be involved to filter the results since the Piece doesn't know of all the other Pieces on the board and their locations. So maybe all of this logic really belongs in the board (alhtough I kind of like the idea that the piece gives the basic pattern and the board filters it down).
In either case, I'm trying to involve having switch aPiece.type
in the code (with a class cluster I would only have it in the Piece initiliazer)
What would be a nice Swift (possibly even functional) way of solving this problem?
I'm also having a similar extension on the
Piece
class that get's the correctSCNGeometry
object from a file based on the type and the color