From 95d95f6b606d1d0ecde002d0bce8d942e37ea988 Mon Sep 17 00:00:00 2001 From: DJYohann Date: Sun, 12 Feb 2023 16:38:53 +0100 Subject: [PATCH] feat - add display and scan method in CLT --- Src/CLT/CLT.xcodeproj/project.pbxproj | 24 ++++++++ Src/CLT/CLT/main.swift | 9 ++- Src/CLT/IO/ConsoleDisplay.swift | 8 +++ Src/CLT/IO/ConsoleRead.swift | 13 +++++ Src/CLT/IO/Displayable.swift | 6 ++ Src/CLT/IO/Readable.swift | 5 ++ Src/Model/Sources/Model/Board/Board.swift | 4 +- .../Sources/Model/Board/BoardResult.swift | 1 - Src/Model/Sources/Model/Game/Game.swift | 4 +- .../Sources/Model/Rules/ClassicRules.swift | 58 ++++++++++++++++++- Src/Model/Sources/Model/Rules/Rules.swift | 6 +- .../Tests/ModelTests/Board/BoardTests.swift | 20 +++---- .../Tests/ModelTests/Player/AITests.swift | 12 +--- .../ModelTests/Rules/ClassicRulesTests.swift | 3 +- 14 files changed, 137 insertions(+), 36 deletions(-) create mode 100644 Src/CLT/IO/ConsoleDisplay.swift create mode 100644 Src/CLT/IO/ConsoleRead.swift create mode 100644 Src/CLT/IO/Displayable.swift create mode 100644 Src/CLT/IO/Readable.swift diff --git a/Src/CLT/CLT.xcodeproj/project.pbxproj b/Src/CLT/CLT.xcodeproj/project.pbxproj index 25d3325..67a040a 100644 --- a/Src/CLT/CLT.xcodeproj/project.pbxproj +++ b/Src/CLT/CLT.xcodeproj/project.pbxproj @@ -9,6 +9,10 @@ /* Begin PBXBuildFile section */ 1E037925297971D7003044F5 /* Model in Frameworks */ = {isa = PBXBuildFile; productRef = 1E037924297971D7003044F5 /* Model */; }; 1E3E843529775FEB0087C5C2 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E843429775FEB0087C5C2 /* main.swift */; }; + 1E680E5D299939AA00DB3727 /* Displayable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E680E5C299939AA00DB3727 /* Displayable.swift */; }; + 1E680E5F29993A1B00DB3727 /* Readable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E680E5E29993A1B00DB3727 /* Readable.swift */; }; + 1E680E6129993A7900DB3727 /* ConsoleDisplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E680E6029993A7900DB3727 /* ConsoleDisplay.swift */; }; + 1E680E6329993B2400DB3727 /* ConsoleRead.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E680E6229993B2400DB3727 /* ConsoleRead.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -26,6 +30,10 @@ /* Begin PBXFileReference section */ 1E3E843129775FEB0087C5C2 /* CLT */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = CLT; sourceTree = BUILT_PRODUCTS_DIR; }; 1E3E843429775FEB0087C5C2 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 1E680E5C299939AA00DB3727 /* Displayable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Displayable.swift; sourceTree = ""; }; + 1E680E5E29993A1B00DB3727 /* Readable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Readable.swift; sourceTree = ""; }; + 1E680E6029993A7900DB3727 /* ConsoleDisplay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleDisplay.swift; sourceTree = ""; }; + 1E680E6229993B2400DB3727 /* ConsoleRead.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleRead.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -43,6 +51,7 @@ 1E3E842829775FEB0087C5C2 = { isa = PBXGroup; children = ( + 1E680E5B2999399500DB3727 /* IO */, 1E3E843329775FEB0087C5C2 /* CLT */, 1E3E843229775FEB0087C5C2 /* Products */, 1E3E843B2977619C0087C5C2 /* Frameworks */, @@ -72,6 +81,17 @@ name = Frameworks; sourceTree = ""; }; + 1E680E5B2999399500DB3727 /* IO */ = { + isa = PBXGroup; + children = ( + 1E680E5C299939AA00DB3727 /* Displayable.swift */, + 1E680E5E29993A1B00DB3727 /* Readable.swift */, + 1E680E6029993A7900DB3727 /* ConsoleDisplay.swift */, + 1E680E6229993B2400DB3727 /* ConsoleRead.swift */, + ); + path = IO; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -133,7 +153,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1E680E6129993A7900DB3727 /* ConsoleDisplay.swift in Sources */, 1E3E843529775FEB0087C5C2 /* main.swift in Sources */, + 1E680E6329993B2400DB3727 /* ConsoleRead.swift in Sources */, + 1E680E5F29993A1B00DB3727 /* Readable.swift in Sources */, + 1E680E5D299939AA00DB3727 /* Displayable.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Src/CLT/CLT/main.swift b/Src/CLT/CLT/main.swift index e03d772..fa437a2 100644 --- a/Src/CLT/CLT/main.swift +++ b/Src/CLT/CLT/main.swift @@ -16,8 +16,6 @@ func insertPiece(id : Int, column : Int, _ board : inout Board) { print("Unknown") case .negativeOrOutOfBound: print("Row or column must be posittive") - case .alreadyTake: - print("Column already take") } default: print("Rien") @@ -46,3 +44,10 @@ if var board = Board(withNbRows: 6, withNbColumns: 7) { print(board) } + +var grid : [[Int?]] = [[1,2,nil],[nil,nil,nil],[nil,nil,nil]] + +var b = Board(withGrid: grid) + +var displayer = ConsoleDisplay() +displayer.displayBoard(board: b!) diff --git a/Src/CLT/IO/ConsoleDisplay.swift b/Src/CLT/IO/ConsoleDisplay.swift new file mode 100644 index 0000000..b4711f6 --- /dev/null +++ b/Src/CLT/IO/ConsoleDisplay.swift @@ -0,0 +1,8 @@ +import Foundation +import Model + +public class ConsoleDisplay : Displayable { + public func displayBoard(board: Board) { + print(board) + } +} diff --git a/Src/CLT/IO/ConsoleRead.swift b/Src/CLT/IO/ConsoleRead.swift new file mode 100644 index 0000000..0b8c739 --- /dev/null +++ b/Src/CLT/IO/ConsoleRead.swift @@ -0,0 +1,13 @@ +import Foundation + +public class ConsoleRead : Readable { + public func readInt() -> Int { + print("Choose column :") + if let input = readLine() { + if let number = Int(input) { + return number + } + } + return 0 + } +} diff --git a/Src/CLT/IO/Displayable.swift b/Src/CLT/IO/Displayable.swift new file mode 100644 index 0000000..c5561de --- /dev/null +++ b/Src/CLT/IO/Displayable.swift @@ -0,0 +1,6 @@ +import Foundation +import Model + +public protocol Displayable { + func displayBoard(board: Board) +} diff --git a/Src/CLT/IO/Readable.swift b/Src/CLT/IO/Readable.swift new file mode 100644 index 0000000..63b2873 --- /dev/null +++ b/Src/CLT/IO/Readable.swift @@ -0,0 +1,5 @@ +import Foundation + +public protocol Readable { + func readInt() -> Int +} diff --git a/Src/Model/Sources/Model/Board/Board.swift b/Src/Model/Sources/Model/Board/Board.swift index ac94a0f..ce9fc72 100644 --- a/Src/Model/Sources/Model/Board/Board.swift +++ b/Src/Model/Sources/Model/Board/Board.swift @@ -100,7 +100,7 @@ public struct Board : CustomStringConvertible { return .failed(reason: .negativeOrOutOfBound) } guard grid[row][column] == nil else{ - return .failed(reason: .alreadyTake) + return .failed(reason: .columnFull) } grid[row][column] = id return .ok @@ -121,7 +121,7 @@ public struct Board : CustomStringConvertible { return insertPiece(id: id, row: row, column: column) } } - return .failed(reason: .alreadyTake) + return .failed(reason: .columnFull) } /// Remove a piece from the grid diff --git a/Src/Model/Sources/Model/Board/BoardResult.swift b/Src/Model/Sources/Model/Board/BoardResult.swift index d45997c..abd596e 100644 --- a/Src/Model/Sources/Model/Board/BoardResult.swift +++ b/Src/Model/Sources/Model/Board/BoardResult.swift @@ -15,7 +15,6 @@ public enum BoardResult : Equatable { public enum FailedResult { case unknown case negativeOrOutOfBound - case alreadyTake case columnFull case boardFull } diff --git a/Src/Model/Sources/Model/Game/Game.swift b/Src/Model/Sources/Model/Game/Game.swift index a3fd8da..b005b47 100644 --- a/Src/Model/Sources/Model/Game/Game.swift +++ b/Src/Model/Sources/Model/Game/Game.swift @@ -20,8 +20,6 @@ public class Game { /// public func insertPiece(player: Player) { - var col = player.chooseColumn() - - board?.insertPiece(id: player.id, column: col) + } } diff --git a/Src/Model/Sources/Model/Rules/ClassicRules.swift b/Src/Model/Sources/Model/Rules/ClassicRules.swift index 3e9aff7..2e55510 100644 --- a/Src/Model/Sources/Model/Rules/ClassicRules.swift +++ b/Src/Model/Sources/Model/Rules/ClassicRules.swift @@ -11,13 +11,65 @@ public class ClassicRules : Rules { Board(withNbRows: Self.nbRows, withNbColumns: Self.nbColumns) ?? nil } + /// Check if game is over /// - public func isGameOver() -> (Bool, Int, GameResult) { - return (true, 2, .lose); + /// - Returns : true if game is over else false, coordinates of last piece, game result + public func isGameOver() -> (Bool, (Int, Int), GameResult) { + return (true, (1,2), .lose); } + /// Returns id of next palyer to play /// + /// The player who must play is the one who has the fewest tokens + /// + /// - Parameter board : board game + /// + /// - Returns: id of next palyer to play public func getNextPlayer(board: Board) -> Int { - return 9; + var countP1 = 0 + var countP2 = 0 + + for row in 0.. countP2 ? 2 : 1 + } + + /// Check if 4 pieces were aligned in vertical + /// + /// - Parameter board : board to examine + /// - Parameter coord : coordinates of last point + /// + /// - Returns : true if 4 pieces were aligned in vertical else false + private func checkVertical(board: Board, coord: (Int, Int)) -> Bool { + return true + } + + /// Check if 4 pieces were aligned in horizontal + /// + /// - Parameter board : board to examine + /// - Parameter coord : coordinates of last point + /// + /// - Returns : true if 4 pieces were aligned in horizontal else false + private func checkHorizontal(board: Board, coord: (Int, Int)) -> Bool { + return true + } + + /// Check if 4 pieces were aligned in diagonal + /// + /// - Parameter board : board to examine + /// - Parameter coord : coordinates of last point + /// + /// - Returns : true if 4 pieces were aligned in diagonal else false + private func checkDiagonal(board: Board, coord: (Int, Int)) -> Bool { + return true } } diff --git a/Src/Model/Sources/Model/Rules/Rules.swift b/Src/Model/Sources/Model/Rules/Rules.swift index 8ac6da3..14f69de 100644 --- a/Src/Model/Sources/Model/Rules/Rules.swift +++ b/Src/Model/Sources/Model/Rules/Rules.swift @@ -19,10 +19,10 @@ public protocol Rules { /// Create board func createBoard() -> Board? - /// Defines if game is over + /// Check if game is over /// - /// - Returns - func isGameOver() -> (Bool, Int, GameResult) + /// - Returns : true if game is over else false, coordinates of last piece, game result + func isGameOver() -> (Bool, (Int, Int), GameResult) /// Returns id of next palyer to play /// diff --git a/Src/Model/Tests/ModelTests/Board/BoardTests.swift b/Src/Model/Tests/ModelTests/Board/BoardTests.swift index 883af08..f6e934f 100644 --- a/Src/Model/Tests/ModelTests/Board/BoardTests.swift +++ b/Src/Model/Tests/ModelTests/Board/BoardTests.swift @@ -62,24 +62,22 @@ final class BoardTest: XCTestCase { } func testInsertPiece() { - func expect(grid : [[Int?]], idPlayer: Int, column: Int, boardResult : BoardResult, notNil: Bool) { + func expect(grid : [[Int?]], idPlayer: Int, column: Int, boardResult : BoardResult) { var board = Board(withGrid: grid) - if !notNil { - XCTAssertNil(board) - return - } - XCTAssertNotNil(board) XCTAssertEqual(board?.insertPiece(id: idPlayer, column: column), boardResult) } - let grid : [[Int?]] = Array.init(repeating: Array.init(repeating: nil, count: 3), count: 3) + let grid : [[Int?]] = [[1,2,nil],[nil,nil,nil],[nil,nil,nil]] + let gridColumnFull : [[Int?]] = [[1,2,nil],[1,nil,nil],[1,nil,nil]] - expect(grid: grid, idPlayer: 2, column: 0, boardResult: .ok, notNil: true) - expect(grid: grid, idPlayer: 2, column: 0, boardResult: .ok, notNil: true) - expect(grid: grid, idPlayer: 2, column: 0, boardResult: .ok, notNil: true) - //expect(grid: grid, idPlayer: 2, column: 0, boardResult: .failed(reason: <#T##FailedResult#>), notNil: true) + expect(grid: grid, idPlayer: 2, column: 0, boardResult: .ok) + expect(grid: grid, idPlayer: 2, column: 2, boardResult: .ok) + expect(grid: grid, idPlayer: 2, column: -2, boardResult: .failed(reason: .negativeOrOutOfBound)) + expect(grid: grid, idPlayer: 2, column: 7, boardResult: .failed(reason: .negativeOrOutOfBound)) + + expect(grid: gridColumnFull, idPlayer: 2, column: 0, boardResult: .failed(reason: .columnFull)) } diff --git a/Src/Model/Tests/ModelTests/Player/AITests.swift b/Src/Model/Tests/ModelTests/Player/AITests.swift index 805cb8c..4d5b29e 100644 --- a/Src/Model/Tests/ModelTests/Player/AITests.swift +++ b/Src/Model/Tests/ModelTests/Player/AITests.swift @@ -3,15 +3,7 @@ import Model final class AITests: XCTestCase { func testInit() { - func expect(nickname: String) { - let ai = AI() - - XCTAssertEqual(ai.nickname, nickname) - } - - expect(nickname: "yobreuil") - expect(nickname: "cebouhou") - expect(nickname: "macheval") + let ai = AI() + XCTAssertEqual(ai.nickname, "AI") } - } diff --git a/Src/Model/Tests/ModelTests/Rules/ClassicRulesTests.swift b/Src/Model/Tests/ModelTests/Rules/ClassicRulesTests.swift index e21a138..fadeb1e 100644 --- a/Src/Model/Tests/ModelTests/Rules/ClassicRulesTests.swift +++ b/Src/Model/Tests/ModelTests/Rules/ClassicRulesTests.swift @@ -8,5 +8,6 @@ final class ClassicRulesTests: XCTestCase { XCTAssertEqual(4, ClassicRules.nbAlignedPieces) XCTAssertEqual(3, ClassicRules.nbTrials) } - + + func }