diff --git a/DouShouQiConsole/DouShouQiConsole/main.swift b/DouShouQiConsole/DouShouQiConsole/main.swift index 40a5085..3f55375 100644 --- a/DouShouQiConsole/DouShouQiConsole/main.swift +++ b/DouShouQiConsole/DouShouQiConsole/main.swift @@ -62,3 +62,32 @@ if let board = Board(withGrid: initialBoardConfiguration) { } else { print("Erreur lors de l'initialisation du plateau de jeu.") } + +// Initialisez un Board avec cette configuration +if var board = Board(withGrid: initialBoardConfiguration) { + print("Plateau initial:") + print(board.description) // Affichez l'état initial du plateau + + // Testez countPieces(of:) + let player1PieceCount = board.countPieces(of: .player1) + print("Nombre de pièces pour le Joueur 1: \(player1PieceCount)") + + let player2PieceCount = board.countPieces(of: .player2) + print("Nombre de pièces pour le Joueur 2: \(player2PieceCount)") + + // Testez countPieces() + let (countPlayer1, countPlayer2) = board.countPieces() + print("Comptage total - Joueur 1: \(countPlayer1), Joueur 2: \(countPlayer2)") + + // Testez removePiece(atRow:andColumn:) + let removeResult = board.removePiece(atRow: 0, andColumn: 0) + print("Résultat de la suppression : \(removeResult)") + print(board.description) // Affichez le plateau après suppression + + // Testez insert(piece:atRow:andColumn:) + let insertResult = board.insert(piece: Piece(withOwner: .player1, andAnimal: .lion), atRow: 0, andColumn: 0) + print("Résultat de l'insertion : \(insertResult)") + print(board.description) // Affichez le plateau après insertion +} else { + print("Erreur lors de l'initialisation du plateau de jeu.") +} diff --git a/Model/Sources/Model/Board.swift b/Model/Sources/Model/Board.swift index f89fa3a..732c2f7 100644 --- a/Model/Sources/Model/Board.swift +++ b/Model/Sources/Model/Board.swift @@ -22,13 +22,49 @@ public struct Board { self.grid=grid } - func getCell(atRow row: Int, column: Int) -> Cell? { + public func getCell(atRow row: Int, column: Int) -> Cell? { guard row >= 0, row < nbRows, column >= 0, column < nbColumns else { return nil } return grid[row][column] } + public func countPieces(of owner: Owner) -> Int { + return grid.flatMap({ $0 }).filter({ $0.piece?.owner == owner }).count + } + + public func countPieces() -> (player1: Int, player2: Int) { + let player1Count = countPieces(of: .player1) + let player2Count = countPieces(of: .player2) + return (player1Count, player2Count) + } + + public mutating func insert(piece: Piece, atRow row: Int, andColumn column: Int) -> BoardResult { + guard row >= 0, row < nbRows, column >= 0, column < nbColumns else { + return .failed(reason: .outOfBounds) + } + + if grid[row][column].piece == nil { + grid[row][column].piece = piece + return .ok + } else { + return .failed(reason: .cellNotEmpty) + } + } + + public mutating func removePiece(atRow row: Int, andColumn column: Int) -> BoardResult { + guard row >= 0, row < nbRows, column >= 0, column < nbColumns else { + return .failed(reason: .outOfBounds) + } + + if grid[row][column].piece != nil { + grid[row][column].piece = nil + return .ok + } else { + return .failed(reason: .cellEmpty) + } + } + public var description: String { var boardDescription = "" for row in grid { diff --git a/Model/Sources/Model/BoardFailingReason.swift b/Model/Sources/Model/BoardFailingReason.swift index fff4c7d..bb2c99e 100644 --- a/Model/Sources/Model/BoardFailingReason.swift +++ b/Model/Sources/Model/BoardFailingReason.swift @@ -6,3 +6,10 @@ // import Foundation + +public enum BoardFailingReason { + case outOfBounds + case cellNotEmpty + case cellEmpty + case unknown +} diff --git a/Model/Sources/Model/BoardResult.swift b/Model/Sources/Model/BoardResult.swift index fff4c7d..b899575 100644 --- a/Model/Sources/Model/BoardResult.swift +++ b/Model/Sources/Model/BoardResult.swift @@ -6,3 +6,9 @@ // import Foundation + + +public enum BoardResult : Equatable { + case ok + case failed(reason: BoardFailingReason) +} diff --git a/Model/Tests/ModelTests/ModelTests.swift b/Model/Tests/ModelTests/ModelTests.swift index 41e49f0..2a9ce36 100644 --- a/Model/Tests/ModelTests/ModelTests.swift +++ b/Model/Tests/ModelTests/ModelTests.swift @@ -1,13 +1,244 @@ import XCTest @testable import Model +class BoardTests: XCTestCase { -/* -final class ModelTests: XCTestCase { - func testExample() throws { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct - // results. - XCTAssertEqual(Model().text, "Hello, World!") + // Initialisez un Board de test avec une configuration de test + var testBoard: Board! + + override func setUp() { + super.setUp() + // Initialisez un Board avec une configuration de test + testBoard = Board(withGrid: initialTestConfiguration) + } + + override func tearDown() { + // Nettoyez après chaque test si nécessaire + testBoard = nil + super.tearDown() + } + + // Testez l'initialisateur de Board + func testBoardInitializer() { + XCTAssertNotNil(testBoard) // Vérifiez que le Board a été initialisé avec succès + + // Vérifiez que la taille du plateau correspond à la configuration initiale + XCTAssertEqual(testBoard.nbRows, initialTestConfiguration.count) + XCTAssertEqual(testBoard.nbColumns, initialTestConfiguration[0].count) + + // Ajoutez d'autres vérifications si nécessaire pour vous assurer que le plateau a été initialisé correctement + } + + // Testez countPieces(of:) + func testCountPiecesOfPlayer() { + XCTAssertEqual(testBoard.countPieces(of: .player1), expectedPlayer1PieceCount) + XCTAssertEqual(testBoard.countPieces(of: .player2), expectedPlayer2PieceCount) + } + + // Testez countPieces() + func testCountTotalPieces() { + let (countPlayer1, countPlayer2) = testBoard.countPieces() + XCTAssertEqual(countPlayer1, expectedPlayer1PieceCount) + XCTAssertEqual(countPlayer2, expectedPlayer2PieceCount) + } + + // Testez removePiece(atRow:andColumn:) + func testRemovePiece() { + let initialCell = testBoard.getCell(atRow: 0, column: 0) + XCTAssertNotNil(initialCell?.piece) + let result = testBoard.removePiece(atRow: 0, andColumn: 0) + XCTAssertEqual(result, .ok) + + // Vérifiez que la pièce a été supprimée correctement + let removedCell = testBoard.getCell(atRow: 0, column: 0) + XCTAssertNil(removedCell?.piece) } + + // Testez insert(piece:atRow:andColumn:) + func testInsertPiece() { + // Supprimez toute pièce existante dans la case cible (si elle existe) + let initialCell = testBoard.getCell(atRow: 0, column: 0) + if initialCell?.piece != nil { + let removeResult = testBoard.removePiece(atRow: 0, andColumn: 0) + XCTAssertEqual(removeResult, .ok) + } + + // Insérez une nouvelle pièce dans la case + let insertResult = testBoard.insert(piece: Piece(withOwner: .player1, andAnimal: .lion), atRow: 0, andColumn: 0) + XCTAssertEqual(insertResult, .ok) + + // Vérifiez que la pièce a été insérée correctement + let cell = testBoard.getCell(atRow: 0, column: 0) + XCTAssertNotNil(cell?.piece) + XCTAssertEqual(cell?.piece?.owner, .player1) + XCTAssertEqual(cell?.piece?.animal, .lion) + } + + // Exemple de données de test pour la configuration initiale + let initialTestConfiguration: [[Cell]] = [ + // Ligne 1 + [Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .lion)), + Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .den), Cell(ofType: .trap), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .tiger))], + + // Ligne 2 + [Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .dog)), + Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .jungle), + Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .cat)), Cell(ofType: .jungle)], + + // Ligne 3 + [Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .rat)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .leopard)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .wolf)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .elephant))], + + // Lignes 4 à 7 (Eau et Jungle) + [Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), + Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)], + + [Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), + Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)], + + [Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), + Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)], + + [Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), + Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)], + + // Ligne 8 + [Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .elephant)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .wolf)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .leopard)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .rat))], + + // Ligne 9 + [Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .cat)), + Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .jungle), + Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .dog)), Cell(ofType: .jungle)], + + // Ligne 10 + [Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .tiger)), + Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .den), Cell(ofType: .trap), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .lion))] + ] + + let expectedPlayer1PieceCount = 8 // Le nombre attendu de pièces pour le joueur 1 + let expectedPlayer2PieceCount = 8 // Le nombre attendu de pièces pour le joueur 2 +} + +class BoardPerformanceTests: XCTestCase { + + // Initialisez un Board de test avec une configuration de test + var testBoard: Board! + + override func setUp() { + super.setUp() + // Initialisez un Board avec une configuration de test + testBoard = Board(withGrid: initialTestConfiguration) + } + + override func tearDown() { + // Nettoyez après chaque test si nécessaire + testBoard = nil + super.tearDown() + } + + // Test de performance pour countPieces(of:) + func testPerformanceCountPiecesOfPlayer() { + self.measure { + for _ in 0..<1000 { // Exécutez le test 1000 fois pour mesurer les performances + let _ = testBoard.countPieces(of: .player1) + } + } + } + + // Test de performance pour countPieces() + func testPerformanceCountTotalPieces() { + self.measure { + for _ in 0..<1000 { // Exécutez le test 1000 fois pour mesurer les performances + let _ = testBoard.countPieces() + } + } + } + + // Test de performance pour insert(piece:atRow:andColumn:) + func testPerformanceInsertPiece() { + let pieceToInsert = Piece(withOwner: .player1, andAnimal: .lion) + self.measure { + for _ in 0..<1000 { // Exécutez le test 1000 fois pour mesurer les performances + let _ = testBoard.insert(piece: pieceToInsert, atRow: 0, andColumn: 0) + // Nettoyez après chaque itération pour réinitialiser l'état du plateau + let _ = testBoard.removePiece(atRow: 0, andColumn: 0) + } + } + } + + // Test de performance pour removePiece(atRow:andColumn:) + func testPerformanceRemovePiece() { + let pieceToRemove = Piece(withOwner: .player1, andAnimal: .lion) + let _ = testBoard.insert(piece: pieceToRemove, atRow: 0, andColumn: 0) + self.measure { + for _ in 0..<1000 { // Exécutez le test 1000 fois pour mesurer les performances + let _ = testBoard.removePiece(atRow: 0, andColumn: 0) + // Réinsérez la pièce après chaque itération pour réinitialiser l'état du plateau + let _ = testBoard.insert(piece: pieceToRemove, atRow: 0, andColumn: 0) + } + } + } + + // Test de performance pour l'initialisateur de Board + func testPerformanceInitializeBoard() { + self.measure { + for _ in 0..<1000 { // Exécutez le test 1000 fois pour mesurer les performances + _ = Board(withGrid: initialTestConfiguration) + } + } + } + + // Exemple de données de test pour la configuration initiale + let initialTestConfiguration: [[Cell]] = [ + // Ligne 1 + [Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .lion)), + Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .den), Cell(ofType: .trap), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .tiger))], + + // Ligne 2 + [Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .dog)), + Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .jungle), + Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .cat)), Cell(ofType: .jungle)], + + // Ligne 3 + [Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .rat)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .leopard)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .wolf)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .elephant))], + + // Lignes 4 à 7 (Eau et Jungle) + [Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), + Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)], + + [Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), + Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)], + + [Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), + Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)], + + [Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), + Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)], + + // Ligne 8 + [Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .elephant)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .wolf)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .leopard)), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .rat))], + + // Ligne 9 + [Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .cat)), + Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .jungle), + Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .dog)), Cell(ofType: .jungle)], + + // Ligne 10 + [Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .tiger)), + Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .den), Cell(ofType: .trap), + Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .lion))] + ] } -*/