From 98e4ad2232ae857ffff5e2026e2ca9d4f4482855 Mon Sep 17 00:00:00 2001 From: Mathieu GROUSSEAU Date: Tue, 21 Jan 2025 19:30:54 +0100 Subject: [PATCH] Throw away and redo most of board + filling notation points to score... --- CustomTypes/Sources/CustomTypes/Display.swift | 11 +- .../Tests/CustomTypesTests/DisplayTests.swift | 10 +- Model/Sources/Model/Board.swift | 151 ++++++++---------- Model/Sources/Model/Coords.swift | 14 ++ Model/Sources/Model/Direction.swift | 16 ++ Model/Sources/Model/Piece.swift | 9 +- Model/Sources/Model/Player.swift | 3 + Model/Sources/Model/Side.swift | 3 - Model/Tests/ModelTests/EmptyBoardTests.swift | 131 ++++++++++++--- Model/Tests/ModelTests/FilledBoardTests.swift | 48 +++--- 10 files changed, 249 insertions(+), 147 deletions(-) create mode 100644 Model/Sources/Model/Coords.swift create mode 100644 Model/Sources/Model/Direction.swift create mode 100644 Model/Sources/Model/Player.swift delete mode 100644 Model/Sources/Model/Side.swift diff --git a/CustomTypes/Sources/CustomTypes/Display.swift b/CustomTypes/Sources/CustomTypes/Display.swift index fdb9966..e1add0c 100644 --- a/CustomTypes/Sources/CustomTypes/Display.swift +++ b/CustomTypes/Sources/CustomTypes/Display.swift @@ -1,11 +1,11 @@ import Model -extension Piece: CustomStringConvertible { +extension Player: CustomStringConvertible { public var description: String { switch self { - case .PlayerA: + case .A: "🔴" - case .PlayerB: + case .B: "🟡" } } @@ -17,7 +17,7 @@ extension Board: CustomStringConvertible, CustomDebugStringConvertible { for row in 0..= 0 && column < self.columns && row >= 0 && row < self.rows, "Coordinates out of bounds") + private func isInBounds(_ pos: Coords) -> Bool { + pos.col >= 0 && pos.col < self.columns && pos.row >= 0 && pos.row < self.rows + } + + private func ensureBounds(_ pos: Coords) { + precondition(isInBounds(pos), "Coordinates out of bounds") } public subscript(column: Int, row: Int) -> Piece? { + get { self[Coords(column, row)] } + + set { self[Coords(column, row)] = newValue } + } + + public subscript(pos: Coords) -> Piece? { get { - checkBounds(column, row) - return grid[column][row] + ensureBounds(pos) + return grid[pos.col][pos.row] } - set { - checkBounds(column, row) - grid[column][row] = newValue + set(piece) { + ensureBounds(pos) + grid[pos.col][pos.row] = piece } } - public func countPieces() -> (a: Int, b: Int) { - var a = 0 - var b = 0 + public func countPieces(filter: (Piece) -> Bool = { piece in true }) -> Int { + var count = 0 for column in grid { for piece in column { - switch piece { - case .PlayerA: - a += 1 - case .PlayerB: - b += 1 - case nil: - break + if let piece = piece { + if filter(piece) { + count += 1 + } } } } - return (a, b) + return count } - @discardableResult - public mutating func insert(piece: Piece, side: Side = .Top, offset: Int, pushing push: Bool = false) -> Bool { + // insertion coordinate computation is intentionally separated from actual insertion because the user may want to + // display a where the piece would end-up before doing the actual insertion + + public func getInsertionCoordinates(direction: Direction, offset: Int) -> Coords { precondition(offset >= 0, "Offset out of bounds") - switch side { + switch direction { case .Top: precondition(offset < self.columns, "Offset (column) out of bounds") - - if self.grid[offset].first! != nil { - if (!push) { - return false - } - - Board.shiftDown(column: &self.grid[offset]) - } - - self.grid[offset][0] = piece - - return true + return Coords(offset, 0) case .Left: precondition(offset < self.rows, "Offset (row) out of bounds") - - if self.grid.first![offset] != nil { - if (!push) { - return false - } - - self.shiftRight(row: offset) - } - - self.grid[0][offset] = piece - - return true + return Coords(0, offset) case .Bottom: precondition(offset < self.columns, "Offset (column) out of bounds") - - if self.grid[offset].last! != nil { - if (!push) { - return false - } - - Board.shiftUp(column: &self.grid[offset]) - } - - let lastIndex = self.grid[offset].count - 1 - self.grid[offset][lastIndex] = piece - - return true + return Coords(offset, self.rows - 1) case .Right: precondition(offset < self.rows, "Offset (row) out of bounds") - - if self.grid.last![offset] != nil { - if (!push) { - return false - } - - self.shiftLeft(row: offset) - } - - self.grid[self.columns - 1][offset] = piece - - return true + return Coords(self.columns - 1, offset) } } - private static func shiftDown(column: inout [Piece?]) { - for i in (1.. FallResult { + ensureBounds(initialCoords) + + let dir: (dc: Int, dr: Int) = switch direction { + case .Top: (0, -1) + case .Left: (-1, 0) + case .Bottom: (0, 1) + case .Right: (1, 0) } - } - - private mutating func shiftLeft(row: Int) { - for i in 0..<(grid.count - 1) { - self.grid[i][row] = self.grid[i + 1][row] + + if (self[initialCoords] != nil) { + return FallResult.Occupied } - } - - private mutating func shiftRight(row: Int) { - for i in 1..