Add(Tp3): Création des class et méthode échantillions

pull/4/head
Louis DUFOUR 10 months ago
parent fc29cc4698
commit e5a5b4f6dd

@ -8,8 +8,8 @@
/* Begin PBXBuildFile section */
167C5A152B57F0BC006FB682 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 167C5A142B57F0BC006FB682 /* main.swift */; };
16CE03F62B57F58E00A85305 /* Extension in Frameworks */ = {isa = PBXBuildFile; productRef = 16CE03F52B57F58E00A85305 /* Extension */; };
16CE03F82B57F59200A85305 /* Model in Frameworks */ = {isa = PBXBuildFile; productRef = 16CE03F72B57F59200A85305 /* Model */; };
16EE5AFB2B5E6FC500A15871 /* Model in Frameworks */ = {isa = PBXBuildFile; productRef = 16EE5AFA2B5E6FC500A15871 /* Model */; };
16EE5AFD2B5E6FC800A15871 /* Extension in Frameworks */ = {isa = PBXBuildFile; productRef = 16EE5AFC2B5E6FC800A15871 /* Extension */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -34,8 +34,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
16CE03F82B57F59200A85305 /* Model in Frameworks */,
16CE03F62B57F58E00A85305 /* Extension in Frameworks */,
16EE5AFD2B5E6FC800A15871 /* Extension in Frameworks */,
16EE5AFB2B5E6FC500A15871 /* Model in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -91,8 +91,8 @@
);
name = DouShouQiConsole;
packageProductDependencies = (
16CE03F52B57F58E00A85305 /* Extension */,
16CE03F72B57F59200A85305 /* Model */,
16EE5AFA2B5E6FC500A15871 /* Model */,
16EE5AFC2B5E6FC800A15871 /* Extension */,
);
productName = DouShouQiConsole;
productReference = 167C5A112B57F0BC006FB682 /* DouShouQiConsole */;
@ -298,13 +298,13 @@
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
16CE03F52B57F58E00A85305 /* Extension */ = {
16EE5AFA2B5E6FC500A15871 /* Model */ = {
isa = XCSwiftPackageProductDependency;
productName = Extension;
productName = Model;
};
16CE03F72B57F59200A85305 /* Model */ = {
16EE5AFC2B5E6FC800A15871 /* Extension */ = {
isa = XCSwiftPackageProductDependency;
productName = Model;
productName = Extension;
};
/* End XCSwiftPackageProductDependency section */
};

@ -22,3 +22,5 @@ public extension Animal {
}
}
}

@ -7,7 +7,7 @@
import Foundation
public struct Board : CustomStringConvertible {
public struct Board : CustomStringConvertible, Hashable, Equatable {
public let nbRows: Int
public let nbColumns: Int
public private(set) var grid: [[Cell]]

@ -7,7 +7,7 @@
import Foundation
public struct Cell : CustomStringConvertible {
public struct Cell : CustomStringConvertible, Hashable, Equatable {
public let cellType: CellType
public var initialOwner: Owner
public var piece: Piece?
@ -21,6 +21,13 @@ public struct Cell : CustomStringConvertible {
public var description: String {
return "Cell(type: (cellType), owner: (initialOwner), piece: (pieceDescription))"
}
public func hash(into hasher: inout Hasher) {
hasher.combine(cellType)
hasher.combine(initialOwner)
// 'Piece?' est déjà 'Hashable' grâce à la conformité automatique de Swift pour les types optionnels.
hasher.combine(piece)
}
}

@ -0,0 +1,12 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 22/01/2024.
//
import Foundation
enum GameError: Error {
case invalidMove
}

@ -0,0 +1,16 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 22/01/2024.
//
import Foundation
enum InvalidBoardError: Error {
case badDimensions(Int, Int)
case badCellType(CellType, Int, Int)
case multipleOccurencesOfSamePiece(Piece)
case pieceWithNoOwner(Piece)
case pieceNotAllowedOnThisCell(Piece, Cell)
}

@ -0,0 +1,14 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 22/01/2024.
//
import Foundation
enum Result {
case notFinished
case even
case winner(Owner, WinningReason)
}

@ -0,0 +1,15 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 22/01/2024.
//
import Foundation
enum WinningReason {
case denReached
case noMorePieces
case noMovesLeft
case tooManyOccurences
}

@ -0,0 +1,22 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 22/01/2024.
//
import Foundation
protocol Rules {
var occurences: [Board: Int] { get set }
var historic: [Move] { get set }
func createBoard() -> Board
func checkBoard( b: Board) throws
func getNextPlayer() -> Owner
func getMoves( board: Board, owner: Owner) -> [Move]
func getMoves( board: Board, owner: Owner, row: Int, column: Int) -> [Move]
func isMoveValid( board: Board, move: Move) -> Bool
func isGameOver( board: Board, lastMove: Move) -> (Bool, Result)
func playedMove( move: Move, oldBoard: Board, newBoard: Board)
}

@ -0,0 +1,16 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 22/01/2024.
//
import Foundation
public struct Move {
let owner: Owner
let rowOrigin: Int
let columnOrigin: Int
let rowDestination: Int
let columnDestination: Int
}

@ -7,7 +7,7 @@
import Foundation
public struct Piece : CustomStringConvertible{
public struct Piece : CustomStringConvertible, Equatable, Hashable{
public let owner: Owner
public let animal: Animal

@ -0,0 +1,160 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 22/01/2024.
//
import Foundation
struct VerySimpleRules: Rules {
var occurences = [Board: Int]()
var historic = [Move]()
func createBoard() -> Board {
var cells = [[Cell]]()
// Configuration initiale du plateau
let initialSetup: [Animal?] = [.lion, .tiger, .rat, .cat, .elephant]
let rows = 5
let columns = 5
for row in 0..<rows {
var rowCells = [Cell]()
for column in 0..<columns {
let cellType: CellType = ((row == 0 || row == 4) && column == 2) ? .den : .jungle
let owner: Owner = row == 0 ? .player1 : (row == 4 ? .player2 : .noOne)
var piece: Piece? = nil
if owner != .noOne && column < initialSetup.count {
if let animal = initialSetup[column] {
piece = Piece(owner: owner, animal: animal)
}
}
rowCells.append(Cell(cellType: cellType, initialOwner: owner, piece: piece))
}
cells.append(rowCells)
}
return Board(grid: cells)
}
func checkBoard(_ b: Board) throws {
// Vérifier les dimensions du plateau
guard b.nbRows == 5, b.nbColumns == 5 else {
throw InvalidBoardError.badDimensions(b.nbRows, b.nbColumns)
}
// Vérifier la conformité des cellules (e.g., types de cellules, pièces présentes)
for row in 0..<b.nbRows {
for col in 0..<b.nbColumns {
let cell = b.grid[row][col]
// Vérifier le type de la cellule
if row == 0 || row == 4 {
if col == 2 && cell.cellType != .den {
throw InvalidBoardError.badCellType(cell.cellType, row, col)
}
} else if cell.cellType != .jungle {
throw InvalidBoardError.badCellType(cell.cellType, row, col)
}
// Vérifier la conformité des pièces
if let piece = cell.piece {
if piece.owner != .player1 && piece.owner != .player2 {
throw InvalidBoardError.pieceWithNoOwner(piece)
}
// Autres vérifications de pièces peuvent être ajoutées ici
}
}
}
}
func getNextPlayer() -> Owner {
// Implémentation basée sur l'historique des coups
return historic.last?.owner == .player1 ? .player2 : .player1
}
func getMoves(_ board: Board, _ owner: Owner) -> [Move] {
var moves = [Move]()
for row in 0..<board.nbRows {
for col in 0..<board.nbColumns {
if let cell = board.grid[row][col], cell.piece?.owner == owner {
moves.append(contentsOf: getMoves(board, owner, row, col))
}
}
}
return moves
}
func getMoves(_ board: Board, _ owner: Owner, _ row: Int, _ column: Int) -> [Move] {
var moves = [Move]()
// Directions: haut, bas, gauche, droite
let directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for (dRow, dCol) in directions {
let newRow = row + dRow
let newCol = column + dCol
if newRow >= 0, newRow < board.nbRows, newCol >= 0, newCol < board.nbColumns,
let destinationCell = board.grid[newRow][newCol],
destinationCell.piece?.owner != owner {
moves.append(Move(owner: owner, rowOrigin: row, columnOrigin: column, rowDestination: newRow, columnDestination: newCol))
}
}
return moves
}
func isMoveValid(_ board: Board, _ move: Move) -> Bool {
// Vérifier si les coordonnées de destination sont valides
if move.rowDestination < 0 || move.rowDestination >= board.nbRows ||
move.columnDestination < 0 || move.columnDestination >= board.nbColumns {
return false
}
// Vérifier si la case de destination est occupée par une pièce du même joueur
if let destinationCell = board.grid[move.rowDestination][move.columnDestination],
let piece = destinationCell.piece,
piece.owner == move.owner {
return false
}
// Autres vérifications spécifiques au jeu peuvent être ajoutées ici
// ...
return true
}
func isGameOver(_ board: Board, _ lastMove: Move) -> (Bool, Result) {
// Vérifier si la tannière de l'adversaire a été atteinte
let opponent = lastMove.owner == .player1 ? .player2 : .player1
if let destinationCell = board.grid[lastMove.rowDestination][lastMove.columnDestination],
destinationCell.cellType == .den, destinationCell.initialOwner == opponent {
return (true, .winner(lastMove.owner, .denReached))
}
// Vérifier si l'adversaire n'a plus de pièces
let hasOpponentPieces = board.grid.flatMap { $0 }.contains { cell in
guard let piece = cell.piece else { return false }
return piece.owner == opponent
}
if !hasOpponentPieces {
return (true, .winner(lastMove.owner, .noMorePieces))
}
// Vérifier si l'adversaire ne peut plus bouger
let opponentMoves = getMoves(board, opponent)
if opponentMoves.isEmpty {
return (true, .winner(lastMove.owner, .noMovesLeft))
}
// Si aucune condition de victoire n'est remplie, la partie n'est pas encore terminée
return (false, .notFinished)
}
}
Loading…
Cancel
Save