Rename Player enum to PieceType

pull/3/head
Mathieu GROUSSEAU 4 weeks ago
parent ffdfebe560
commit b9853390ed

@ -18,7 +18,7 @@ for move in rules.validMoves(board: board) {
print(move)
}
print("Moves for \(Player.A):")
print("Moves for \(PieceType.A):")
for move in rules.validMoves(board: board, for_player: .A) {
print(move)
}
@ -42,7 +42,7 @@ while case .Playing(let turn) = rules.state {
direction: .Bottom
) {
case .Border(let at), .Piece(let at, _):
board[at] = Piece(owner: turn)
board[at] = Piece(type: turn)
case .Occupied:
fatalError("Occupied???")
}

@ -1,6 +1,6 @@
import Model
extension Player: CustomStringConvertible {
extension PieceType: CustomStringConvertible {
public var description: String {
switch self {
case .A:
@ -17,7 +17,7 @@ extension Board: CustomStringConvertible, CustomDebugStringConvertible {
for row in 0..<self.rows {
for col in 0..<self.columns {
str += self[col, row]?.owner.description ?? ""
str += self[col, row]?.type.description ?? ""
}
str += "\n"
@ -27,7 +27,7 @@ extension Board: CustomStringConvertible, CustomDebugStringConvertible {
}
public var debugDescription: String {
return "Board[\(self.columns)x\(self.rows), \(self.countPieces { p in p.owner == .A }) A and \(self.countPieces { p in p.owner == .B }) B pieces]"
return "Board[\(self.columns)x\(self.rows), \(self.countPieces { p in p.type == .A }) A and \(self.countPieces { p in p.type == .B }) B pieces]"
}
}

@ -9,10 +9,10 @@ final class CustomTypesTests: XCTestCase {
return
}
board[1, 1] = Piece(owner: .A)
board[2, 1] = Piece(owner: .A)
board[2, 2] = Piece(owner: .A)
board[1, 2] = Piece(owner: .B)
board[1, 1] = Piece(type: .A)
board[2, 1] = Piece(type: .A)
board[2, 2] = Piece(type: .A)
board[1, 2] = Piece(type: .B)
let text: String = board.description

@ -1,8 +1,8 @@
public struct Piece : Sendable {
public let owner: Player
public let type: PieceType
// Required for public visibility
public init(owner: Player) {
self.owner = owner
public init(type: PieceType) {
self.type = type
}
}

@ -0,0 +1,3 @@
public enum PieceType: CaseIterable, Sendable {
case A, B
}

@ -1,3 +0,0 @@
public enum Player: CaseIterable, Sendable {
case A, B
}

@ -63,14 +63,14 @@ public struct FourInARowRules: Rules {
}
public func validMoves(board: Board) -> [Move] {
return Player.allCases.flatMap({
return PieceType.allCases.flatMap({
player in self.validMoves(board: board, for_player: player).map({
action in Move(player: player, action: action)
})
})
}
public func validMoves(board: Board, for_player player: Player) -> [Move.Action] {
public func validMoves(board: Board, for_player player: PieceType) -> [Move.Action] {
var moves: [Move.Action] = [];
for c in 0..<board.columns {
@ -110,7 +110,7 @@ public struct FourInARowRules: Rules {
} else if board.countPieces() == board.columns * board.rows {
self.state = .Finished(winner: nil)
} else {
let next: Player = switch move.player {
let next: PieceType = switch move.player {
case .A: .B
case .B: .A
}
@ -122,7 +122,7 @@ public struct FourInARowRules: Rules {
}
internal static func countMaxRow(center: Coords, board: Board) -> Int {
guard let of = board[center]?.owner else { return 0 }
guard let of = board[center]?.type else { return 0 }
var maxLength = 0
// For each "axis" (described as one direction)
@ -135,7 +135,7 @@ public struct FourInARowRules: Rules {
while true {
pos = Coords(pos.col + dc, pos.row + dr)
if !board.isInBounds(pos) || board[pos]?.owner != of { break }
if !board.isInBounds(pos) || board[pos]?.type != of { break }
length += 1
}
}

@ -1,8 +1,8 @@
public struct Move: Equatable {
public let player: Player
public let player: PieceType
public let action: Action
public init(player: Player, action: Action) {
public init(player: PieceType, action: Action) {
self.player = player
self.action = action
}

@ -11,13 +11,13 @@ public protocol Rules {
func validMoves(board: Board) -> [Move]
func validMoves(board: Board, for_player player: Player) -> [Move.Action]
func validMoves(board: Board, for_player player: PieceType) -> [Move.Action]
mutating func onMoveDone(move: Move, board: Board) -> Void
}
public enum GameState: Equatable {
case Playing(turn: Player)
case Playing(turn: PieceType)
case Finished(winner: Player?)
case Finished(winner: PieceType?)
}

@ -16,8 +16,8 @@ public struct TicTacToeRules: Rules {
}
public func isValid(board: Board) -> Bool {
abs(board.countPieces(filter: { p in p.owner == .A }) -
board.countPieces(filter: { p in p.owner == .B })) <= 1
abs(board.countPieces(filter: { p in p.type == .A }) -
board.countPieces(filter: { p in p.type == .B })) <= 1
}
public func isValid(board: Board, move: Move) -> Bool {
@ -38,15 +38,15 @@ public struct TicTacToeRules: Rules {
return self.validMoves(board: board, for_player: player).map { Move(player: player, action: $0) }
}
private static func nextPlayer(board: Board) -> Player {
if board.countPieces(filter: { p in p.owner == .A }) > board.countPieces(filter: { p in p.owner == .B }) {
private static func nextPlayer(board: Board) -> PieceType {
if board.countPieces(filter: { p in p.type == .A }) > board.countPieces(filter: { p in p.type == .B }) {
.B
} else {
.A
}
}
public func validMoves(board: Board, for_player player: Player) -> [Move.Action] {
public func validMoves(board: Board, for_player player: PieceType) -> [Move.Action] {
var moves: [Move.Action] = []
for col in 0..<board.columns {
@ -72,7 +72,7 @@ public struct TicTacToeRules: Rules {
} else if board.countPieces() == board.columns * board.rows {
self.state = .Finished(winner: nil)
} else {
let next: Player = switch move.player {
let next: PieceType = switch move.player {
case .A: .B
case .B: .A
}

@ -32,7 +32,7 @@ final class EmptyBoardTests: XCTestCase {
func testCustomSubscript() throws {
for r in 0..<board.rows {
for c in 0..<board.columns {
for p: Player in [.A, .B] {
for p: PieceType in [.A, .B] {
try self.setUpWithError()
try self._testCustomSubscript(at: Coords(c, r), player: p)
@ -43,19 +43,19 @@ final class EmptyBoardTests: XCTestCase {
}
}
private func _testCustomSubscript(at: Coords, player: Player) throws {
board[at] = Piece(owner: player)
private func _testCustomSubscript(at: Coords, player: PieceType) throws {
board[at] = Piece(type: player)
XCTAssertEqual(board[at]?.owner, player)
XCTAssertEqual(board[at]?.type, player)
}
func testCounts() throws {
board[1, 2] = Piece(owner: .B)
board[0, 2] = Piece(owner: .A)
board[1, 1] = Piece(owner: .A)
board[1, 2] = Piece(type: .B)
board[0, 2] = Piece(type: .A)
board[1, 1] = Piece(type: .A)
XCTAssertEqual(board.countPieces { piece in piece.owner == .A }, 2)
XCTAssertEqual(board.countPieces { piece in piece.owner == .B }, 1)
XCTAssertEqual(board.countPieces { piece in piece.type == .A }, 2)
XCTAssertEqual(board.countPieces { piece in piece.type == .B }, 1)
}
func testInsertsSides() throws {
@ -129,9 +129,9 @@ final class EmptyBoardTests: XCTestCase {
] {
// ensure it works with any player
board[Coords(pair: pos)] = if (pos.0 + pos.1) & 1 == 1 {
Piece(owner: .A)
Piece(type: .A)
} else {
Piece(owner: .B)
Piece(type: .B)
}
}

@ -15,9 +15,9 @@ final class FilledBoardTests: XCTestCase {
for row in 0..<board.rows {
for col in 0..<board.columns {
board[col, row] = if (row & 1) == 1 {
Piece(owner: .A)
Piece(type: .A)
} else {
Piece(owner: .B)
Piece(type: .B)
}
}
}

@ -37,7 +37,7 @@ final class FourInARowRulesTests: XCTestCase {
}
func testMovesOfPlayerAreValid() throws {
for player in Player.allCases {
for player in PieceType.allCases {
try self.setUpWithError()
try self._testMovesOfPlayerAreValid(player: player)
@ -46,7 +46,7 @@ final class FourInARowRulesTests: XCTestCase {
}
}
private func _testMovesOfPlayerAreValid(player: Player) throws {
private func _testMovesOfPlayerAreValid(player: PieceType) throws {
for action in self.rules.validMoves(board: self.board, for_player: player) {
rules.state = .Playing(turn: player)
XCTAssertTrue(self.rules.isValid(board: board, move: Move(player: player, action: action)), "\(action)")
@ -55,7 +55,7 @@ final class FourInARowRulesTests: XCTestCase {
func testOnMoveDone() {
let coord = Coords(1, board.rows - 1)
board[coord] = Piece(owner: .A)
board[coord] = Piece(type: .A)
let move = Move(player: .A, action: .InsertOnSide(side: .Top, offset: 1))
self.rules.onMoveDone(move: move, board: self.board)
@ -64,16 +64,16 @@ final class FourInARowRulesTests: XCTestCase {
}
func testOnMoveDoneDraw() {
board[0, 0] = Piece(owner: .A)
board[1, 0] = Piece(owner: .A)
board[2, 0] = Piece(owner: .B)
board[0, 1] = Piece(owner: .B)
board[1, 1] = Piece(owner: .B)
board[2, 1] = Piece(owner: .A)
board[0, 2] = Piece(owner: .A)
board[1, 2] = Piece(owner: .A)
board[0, 0] = Piece(type: .A)
board[1, 0] = Piece(type: .A)
board[2, 0] = Piece(type: .B)
board[0, 1] = Piece(type: .B)
board[1, 1] = Piece(type: .B)
board[2, 1] = Piece(type: .A)
board[0, 2] = Piece(type: .A)
board[1, 2] = Piece(type: .A)
board[2, 2] = Piece(owner: .B)
board[2, 2] = Piece(type: .B)
XCTAssertTrue(rules.isValid(board: board))
@ -85,15 +85,15 @@ final class FourInARowRulesTests: XCTestCase {
}
func testOnMoveDoneWin() {
board[0, 0] = Piece(owner: .A)
board[1, 0] = Piece(owner: .A)
board[2, 0] = Piece(owner: .A) //
board[0, 1] = Piece(owner: .B)
board[1, 1] = Piece(owner: .B)
board[2, 1] = Piece(owner: .A)
board[0, 2] = Piece(owner: .A)
board[1, 2] = Piece(owner: .A)
board[2, 2] = Piece(owner: .B)
board[0, 0] = Piece(type: .A)
board[1, 0] = Piece(type: .A)
board[2, 0] = Piece(type: .A) //
board[0, 1] = Piece(type: .B)
board[1, 1] = Piece(type: .B)
board[2, 1] = Piece(type: .A)
board[0, 2] = Piece(type: .A)
board[1, 2] = Piece(type: .A)
board[2, 2] = Piece(type: .B)
XCTAssertTrue(rules.isValid(board: board))
@ -118,15 +118,15 @@ final class FourInARowRulesTests: XCTestCase {
// AAA
// BAB
// BBA
board[0, 0] = Piece(owner: .A)
board[1, 0] = Piece(owner: .A)
board[2, 0] = Piece(owner: .A)
board[0, 1] = Piece(owner: .B)
board[1, 1] = Piece(owner: .A)
board[2, 1] = Piece(owner: .B)
board[0, 2] = Piece(owner: .B)
board[1, 2] = Piece(owner: .B)
board[2, 2] = Piece(owner: .A)
board[0, 0] = Piece(type: .A)
board[1, 0] = Piece(type: .A)
board[2, 0] = Piece(type: .A)
board[0, 1] = Piece(type: .B)
board[1, 1] = Piece(type: .A)
board[2, 1] = Piece(type: .B)
board[0, 2] = Piece(type: .B)
board[1, 2] = Piece(type: .B)
board[2, 2] = Piece(type: .A)
self._testCountMaxRow(coords: coords, expected: expected)

Loading…
Cancel
Save