diff --git a/DouShouQiConsole/DouShouQiConsole/main.swift b/DouShouQiConsole/DouShouQiConsole/main.swift
index 1fd4d47..1b7749b 100644
--- a/DouShouQiConsole/DouShouQiConsole/main.swift
+++ b/DouShouQiConsole/DouShouQiConsole/main.swift
@@ -91,3 +91,62 @@ if var board = Board(withGrid: initialBoardConfiguration) {
} else {
print("Erreur lors de l'initialisation du plateau de jeu.")
}
+
+
+// Création des règles et du plateau initial
+var rules = VerySimpleRules()
+var board = VerySimpleRules.createBoard()
+
+
+/*
+// Simulation du mouvement sur le plateau
+if let piece = oldBoard.grid[move.rowOrigin][move.columnOrigin].piece {
+ newBoard.grid[move.rowDestination][move.columnDestination].piece = piece
+ newBoard.grid[move.rowOrigin][move.columnOrigin].piece = nil
+}
+*/
+
+/*
+// Création des joueurs
+let humanPlayer = HumanPlayer(name: "Joueur Humain", id: .player1) { board, rules in
+ // Logique pour permettre à l'utilisateur de choisir un mouvement
+ print("Votre mouvement (format 'rowOrigin, columnOrigin, rowDestination, columnDestination') :")
+ if let input = readLine() {
+ let components = input.split(separator: ",").compactMap { Int($0.trimmingCharacters(in: .whitespacesAndNewlines)) }
+ if components.count == 4 {
+ return Move(owner: .player1, rowOrigin: components[0], columnOrigin: components[1], rowDestination: components[2], columnDestination: components[3])
+ }
+ }
+ return nil
+}
+
+let randomPlayer = RandomPlayer(withName: "Joueur IA", andId: .player2)
+
+ let human = humanPlayer, let random = randomPlayer else {
+ print("Erreur lors de la création des joueurs.")
+}
+
+while true {
+ // Afficher l'état actuel du plateau
+ print(board)
+
+ // Déterminer le joueur actuel
+ let currentPlayer = rules.getNextPlayer() == human.id ? human : random
+
+ // Le joueur actuel choisit un mouvement
+ if let move = currentPlayer.chooseMove(board: board, rules: rules), rules.isMoveValid(board: board, move: move) {
+ // Appliquer le mouvement et mettre à jour le plateau
+ rules.playedMove(move: move, oldBoard: board, newBoard: board)
+
+ // Vérifier si le jeu est terminé
+ let gameOverResult = rules.isGameOver(board: board, lastMove: move)
+ if gameOverResult.0 {
+ print("Le jeu est terminé. Résultat : \(gameOverResult.1)")
+ break
+ }
+ } else {
+ print("Mouvement invalide. Essayez de nouveau.")
+ }
+}
+
+*/
diff --git a/Model/.swiftpm/xcode/xcshareddata/xcschemes/ModelCov.xcscheme b/Model/.swiftpm/xcode/xcshareddata/xcschemes/ModelCov.xcscheme
new file mode 100644
index 0000000..a4b7bad
--- /dev/null
+++ b/Model/.swiftpm/xcode/xcshareddata/xcschemes/ModelCov.xcscheme
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Model/Sources/Model/Board.swift b/Model/Sources/Model/Board.swift
index 31ea126..c3afd2a 100644
--- a/Model/Sources/Model/Board.swift
+++ b/Model/Sources/Model/Board.swift
@@ -7,7 +7,7 @@
import Foundation
-public struct Board : CustomStringConvertible, Hashable, Equatable {
+public struct Board : Hashable, Equatable {
public let nbRows: Int
public let nbColumns: Int
public private(set) var grid: [[Cell]]
@@ -65,16 +65,7 @@ public struct Board : CustomStringConvertible, Hashable, Equatable {
}
}
- public var description: String {
- var boardDescription = ""
- for row in grid {
- for cell in row {
- boardDescription += cell.description + " "
- }
- boardDescription += "\n"
- }
- return boardDescription
- }
+
}
diff --git a/Model/Sources/Model/Interface/Rules.swift b/Model/Sources/Model/Interface/Rules.swift
index 44ded24..19ceba1 100644
--- a/Model/Sources/Model/Interface/Rules.swift
+++ b/Model/Sources/Model/Interface/Rules.swift
@@ -28,5 +28,5 @@ public protocol Rules {
func isGameOver( board: Board, lastMove: Move) -> (Bool, Result)
// permet de stocker le coût qui a été fait. (playedMove)
- func playedMove(move: Move, oldBoard: Board, newBoard: Board)
+ mutating func playedMove(move: Move, oldBoard: Board, newBoard: Board)
}
diff --git a/Model/Sources/Model/Move.swift b/Model/Sources/Model/Move.swift
index 80abf9d..48ef412 100644
--- a/Model/Sources/Model/Move.swift
+++ b/Model/Sources/Model/Move.swift
@@ -13,4 +13,17 @@ public struct Move {
public let columnOrigin: Int
public let rowDestination: Int
public let columnDestination: Int
+
+ public init(owner: Owner, rowOrigin: Int, columnOrigin: Int, rowDestination: Int, columnDestination: Int) {
+ self.owner = owner
+ self.rowOrigin = rowOrigin
+ self.columnOrigin = columnOrigin
+ self.rowDestination = rowDestination
+ self.columnDestination = columnDestination
+ }
+
+ public var description: String {
+ let description = "Move by \(owner): (\(rowOrigin) / \(columnOrigin)) to (\(rowDestination) / \(columnDestination))"
+ return description
+ }
}
diff --git a/Model/Sources/Model/RandomPlayer.swift b/Model/Sources/Model/RandomPlayer.swift
index cc256fe..28a19dc 100644
--- a/Model/Sources/Model/RandomPlayer.swift
+++ b/Model/Sources/Model/RandomPlayer.swift
@@ -9,6 +9,11 @@ import Foundation
public class RandomPlayer: Player {
+ public init?(withName name: String, andId id:Owner)
+ {
+ super.init(name: name, id: id)
+ }
+
public override func chooseMove(board: Board, rules: VerySimpleRules) -> Move? {
let validMoves = rules.getMoves(board: board, owner: self.id)
return validMoves.randomElement() // Sélectionne un mouvement aléatoire parmi les mouvements valides
diff --git a/Model/Sources/Model/VerySimpleRules.swift b/Model/Sources/Model/VerySimpleRules.swift
index 12f40ad..eae7be5 100644
--- a/Model/Sources/Model/VerySimpleRules.swift
+++ b/Model/Sources/Model/VerySimpleRules.swift
@@ -8,10 +8,15 @@
import Foundation
public struct VerySimpleRules: Rules {
-
+
public var occurences = [Board: Int]()
public var historic = [Move]()
+ public init() {
+ self.occurences = [Board: Int]()
+ self.historic = [Move]()
+ }
+
public static func createBoard() -> Board {
var cells = [[Cell]]()
@@ -123,9 +128,6 @@ public struct VerySimpleRules: Rules {
return false
}
- // Autres vérifications spécifiques au jeu peuvent être ajoutées ici
- // ...
-
return true
}
@@ -171,12 +173,9 @@ public struct VerySimpleRules: Rules {
return (false, .notFinished)
}
- public func playedMove(move: Move, oldBoard: Board, newBoard: Board) {
- // ToDo
+ public mutating func playedMove(move: Move, oldBoard: Board, newBoard: Board) {
// Ajouter le mouvement à l'historique
- // historic.append(move)
-
- // Mise à jour du comptage des occurrences pour le nouveau plateau
- // occurences[newBoard, default: 0] += 1
+ historic.append(move)
}
}
+
diff --git a/Model/Tests/ModelTests/PlayerTests.swift b/Model/Tests/ModelTests/PlayerTests.swift
new file mode 100644
index 0000000..53b2a9b
--- /dev/null
+++ b/Model/Tests/ModelTests/PlayerTests.swift
@@ -0,0 +1,92 @@
+//
+// File.swift
+//
+//
+// Created by Louis DUFOUR on 31/01/2024.
+//
+
+import Foundation
+import Model
+import XCTest
+
+/*
+// Mocks et Stubs
+class MockBoard: Board {
+ // Implémentez les méthodes nécessaires
+}
+
+class MockRules: VerySimpleRules {
+ var mockMoves: [Move] = []
+
+ func getMoves(board: Board, owner: Owner) -> [Move] {
+ return mockMoves
+ }
+}
+
+class MockMove: Move {
+ // Implémentez les détails nécessaires
+}
+
+// Tests
+class PlayerTests: XCTestCase {
+ func testPlayerInitialization() {
+ let player = Player(name: "TestPlayer", id: .player1)
+ XCTAssertNotNil(player)
+ XCTAssertEqual(player.name, "TestPlayer")
+ // Plus d'assertions pour id
+ }
+}
+
+class HumanPlayerTests: XCTestCase {
+ var mockBoard: MockBoard!
+ var mockRules: MockRules!
+ var mockMove: MockMove!
+
+ override func setUp() {
+ super.setUp()
+ mockBoard = MockBoard()
+ mockRules = MockRules()
+ mockMove = MockMove()
+ }
+
+ func testHumanPlayerInitialization() {
+ let humanPlayer = HumanPlayer(name: "Human", id: .player1, inputMethod: { _, _ in return self.mockMove })
+ XCTAssertNotNil(humanPlayer)
+ XCTAssertEqual(humanPlayer.name, "Human")
+ }
+
+ func testHumanPlayerChooseMove() {
+ let humanPlayer = HumanPlayer(name: "Human", id: .player1, inputMethod: { _, _ in return self.mockMove })
+ let move = humanPlayer.chooseMove(board: mockBoard, rules: mockRules)
+ XCTAssertEqual(move, mockMove)
+ }
+}
+
+class RandomPlayerTests: XCTestCase {
+ var mockBoard: MockBoard!
+ var mockRules: MockRules!
+ var mockMove: MockMove!
+
+ override func setUp() {
+ super.setUp()
+ mockBoard = MockBoard()
+ mockRules = MockRules()
+ mockMove = MockMove()
+ mockRules.mockMoves = [mockMove]
+ }
+
+
+ func testRandomPlayerInitialization() {
+ let randomPlayer = RandomPlayer(withName: "Random", andId: .player2)
+ XCTAssertNotNil(randomPlayer)
+ XCTAssertEqual(randomPlayer.name, "Random")
+ }
+
+ func testRandomPlayerChooseMove() {
+ let randomPlayer = RandomPlayer(withName: "Random", andId: .player2)
+ let move = randomPlayer.chooseMove(board: mockBoard, rules: mockRules)
+ XCTAssertNotNil(move)
+ }
+}*/
+
+
diff --git a/Model/Tests/ModelTests/VerySimpleRulesTests.swift b/Model/Tests/ModelTests/VerySimpleRulesTests.swift
index 90337c0..980acc5 100644
--- a/Model/Tests/ModelTests/VerySimpleRulesTests.swift
+++ b/Model/Tests/ModelTests/VerySimpleRulesTests.swift
@@ -1,6 +1,21 @@
import XCTest
@testable import Model
class VerySimpleRulesTests: XCTestCase {
+
+ var rules: VerySimpleRules!
+ var board: Board!
+
+ override func setUp() {
+ super.setUp()
+ rules = VerySimpleRules()
+ board = VerySimpleRules.createBoard()
+ }
+
+ override func tearDown() {
+ rules = nil
+ board = nil
+ super.tearDown()
+ }
func testCreateBoard() {
// Test que la fonction createBoard() retourne un plateau valide avec les dimensions attendues
@@ -18,7 +33,84 @@ class VerySimpleRulesTests: XCTestCase {
rules.historic.append(Move(owner: .player2, rowOrigin: 0, columnOrigin: 1, rowDestination: 0, columnDestination: 2))
XCTAssertEqual(rules.getNextPlayer(), .player1)
}
+
+ func testCheckBoardValid() {
+ // Assurez-vous que la méthode `checkBoard` ne lève pas d'exception pour un plateau valide
+ XCTAssertNoThrow(try VerySimpleRules.checkBoard(b: board))
+ }
+
+ func testCheckBoardInvalidDimensions() {
+ // Création d'un plateau avec des dimensions invalides (4x4 au lieu de 5x5)
+ var invalidCells = [[Cell]]()
+
+ for _ in 0..<4 {
+ var rowCells = [Cell]()
+ for _ in 0..<4 {
+ // Créez des cellules basiques, les détails dépendent de votre implémentation de Cell
+ let cell = Cell(ofType: .jungle, ownedBy: .noOne, withPiece: nil)
+ rowCells.append(cell)
+ }
+ invalidCells.append(rowCells)
+ }
+
+ let invalidBoard = Board(withGrid: invalidCells)!
+ XCTAssertThrowsError(try VerySimpleRules.checkBoard(b: invalidBoard))
+ }
+
+ func testGetMoves() {
+ // Supposons que pour une configuration de plateau spécifique, vous attendiez 3 mouvements possibles pour le joueur 1
+ let expectedMoveCountForPlayer1 = 3 // Remplacez 3 par le nombre correct basé sur votre jeu
+
+ // Test pour vérifier si getMoves retourne les bons mouvements pour le joueur 1
+ let movesForPlayer1 = rules.getMoves(board: board, owner: .player1)
+ // XCTAssertEqual(movesForPlayer1.count, expectedMoveCountForPlayer1)
+ }
+
+ func testIsMoveValid() {
+ // Test pour un mouvement valide
+ let validMove = Move(owner: .player1, rowOrigin: 0, columnOrigin: 0, rowDestination: 1, columnDestination: 0)
+ XCTAssertTrue(rules.isMoveValid(board: board, move: validMove))
+
+ // Test pour un mouvement invalide (par exemple, déplacement vers une case occupée par le même joueur)
+ let invalidMove = Move(owner: .player1, rowOrigin: 0, columnOrigin: 0, rowDestination: 0, columnDestination: 1)
+ XCTAssertFalse(rules.isMoveValid(board: board, move: invalidMove))
+ }
+
+ func testIsGameOver() {
+ // Assurez-vous que `board` est bien initialisé
+ guard let currentBoard = board else {
+ XCTFail("Board is not initialized")
+ return
+ }
+
+ // Créez un mouvement qui simule une fin de partie
+ let winningMove = Move(owner: .player1, rowOrigin: 3, columnOrigin: 2, rowDestination: 4, columnDestination: 2)
+
+ /*
+ // Appliquez ce mouvement au plateau
+ // Cette partie dépend de la façon dont votre jeu applique les mouvements
+ // Ici, un exemple générique où nous remplaçons simplement la pièce dans la cellule de destination
+ if let piece = currentBoard.grid[winningMove.rowOrigin][winningMove.columnOrigin].piece {
+ currentBoard.grid[winningMove.rowDestination][winningMove.columnDestination].piece = piece
+ currentBoard.grid[winningMove.rowOrigin][winningMove.columnOrigin].piece = nil
+ }
+ */
+
+ // Testez si `isGameOver` détecte correctement la fin de partie
+ let (isGameOver, result) = rules.isGameOver(board: currentBoard, lastMove: winningMove)
+
+ XCTAssertTrue(isGameOver)
+ // Vérifiez le résultat spécifique de la fin de partie
+ switch result {
+ case .winner(let winner, let winCondition):
+ XCTAssertEqual(winner, .player1)
+ XCTAssertEqual(winCondition, .denReached)
+ default:
+ XCTFail("Unexpected game over result")
+ }
+ }
+
static var allTests = [
("testCreateBoard", testCreateBoard),
("testGetNextPlayer", testGetNextPlayer),
diff --git a/ModelCov.xctestplan b/ModelCov.xctestplan
new file mode 100644
index 0000000..7fcde02
--- /dev/null
+++ b/ModelCov.xctestplan
@@ -0,0 +1,24 @@
+{
+ "configurations" : [
+ {
+ "id" : "117362A3-7E9A-409E-91DB-0965BE3D3808",
+ "name" : "Configuration 1",
+ "options" : {
+
+ }
+ }
+ ],
+ "defaultOptions" : {
+
+ },
+ "testTargets" : [
+ {
+ "target" : {
+ "containerPath" : "container:",
+ "identifier" : "ModelTests",
+ "name" : "ModelTests"
+ }
+ }
+ ],
+ "version" : 1
+}
diff --git a/WorkSpaceDouShouQi.xcworkspace/contents.xcworkspacedata b/WorkSpaceDouShouQi.xcworkspace/contents.xcworkspacedata
index e8da9c7..e87c729 100644
--- a/WorkSpaceDouShouQi.xcworkspace/contents.xcworkspacedata
+++ b/WorkSpaceDouShouQi.xcworkspace/contents.xcworkspacedata
@@ -10,4 +10,7 @@
+
+