|
|
@ -8,36 +8,35 @@
|
|
|
|
import Foundation
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
|
|
|
|
struct VerySimpleRules: Rules {
|
|
|
|
struct VerySimpleRules: Rules {
|
|
|
|
|
|
|
|
|
|
|
|
var occurences = [Board: Int]()
|
|
|
|
var occurences = [Board: Int]()
|
|
|
|
var historic = [Move]()
|
|
|
|
var historic = [Move]()
|
|
|
|
|
|
|
|
|
|
|
|
static func createBoard() -> Board {
|
|
|
|
static func createBoard() -> Board {
|
|
|
|
var cells = [[Cell]]()
|
|
|
|
var cells = [[Cell]]()
|
|
|
|
|
|
|
|
|
|
|
|
// Configuration initiale du plateau
|
|
|
|
// Configuration initiale du plateau
|
|
|
|
let initialSetup: [Animal?] = [.lion, .tiger, .rat, .cat, .elephant]
|
|
|
|
let initialSetup: [Animal?] = [.lion, .tiger, .rat, .cat, .elephant]
|
|
|
|
let rows = 5
|
|
|
|
let rows = 5
|
|
|
|
let columns = 5
|
|
|
|
let columns = 5
|
|
|
|
|
|
|
|
|
|
|
|
for row in 0..<rows {
|
|
|
|
for row in 0..<rows {
|
|
|
|
var rowCells = [Cell]()
|
|
|
|
var rowCells = [Cell]()
|
|
|
|
for column in 0..<columns {
|
|
|
|
for column in 0..<columns {
|
|
|
|
let cellType: CellType = ((row == 0 || row == 4) && column == 2) ? .den : .jungle
|
|
|
|
let cellType: CellType = ((row == 0 || row == 4) && column == 2) ? .den : .jungle
|
|
|
|
let owner: Owner = row == 0 ? .player1 : (row == 4 ? .player2 : .noOne)
|
|
|
|
let owner: Owner = row == 0 ? .player1 : (row == 4 ? .player2 : .noOne)
|
|
|
|
var piece: Piece? = nil
|
|
|
|
var piece: Piece? = nil
|
|
|
|
|
|
|
|
|
|
|
|
if owner != .noOne && column < initialSetup.count {
|
|
|
|
if owner != .noOne && column < initialSetup.count {
|
|
|
|
if let animal = initialSetup[column] {
|
|
|
|
if let animal = initialSetup[column] {
|
|
|
|
piece = Piece(withOwner: owner, andAnimal: animal)
|
|
|
|
piece = Piece(withOwner: owner, andAnimal: animal)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rowCells.append(Cell(ofType: cellType, ownedBy: owner, withPiece: piece))
|
|
|
|
rowCells.append(Cell(cellType: cellType, initialOwner: owner, piece: piece))
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cells.append(rowCells)
|
|
|
|
cells.append(rowCells)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Board(withGrid: cells)!
|
|
|
|
return Board(withGrid: cells)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func getNextPlayer() -> Owner {
|
|
|
|
func getNextPlayer() -> Owner {
|
|
|
@ -50,7 +49,7 @@ struct VerySimpleRules: Rules {
|
|
|
|
guard b.nbRows == 5, b.nbColumns == 5 else {
|
|
|
|
guard b.nbRows == 5, b.nbColumns == 5 else {
|
|
|
|
throw InvalidBoardError.badDimensions(b.nbRows, b.nbColumns)
|
|
|
|
throw InvalidBoardError.badDimensions(b.nbRows, b.nbColumns)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Vérifier la conformité des cellules (e.g., types de cellules, pièces présentes)
|
|
|
|
// Vérifier la conformité des cellules (e.g., types de cellules, pièces présentes)
|
|
|
|
for row in 0..<b.nbRows {
|
|
|
|
for row in 0..<b.nbRows {
|
|
|
|
for col in 0..<b.nbColumns {
|
|
|
|
for col in 0..<b.nbColumns {
|
|
|
@ -63,13 +62,12 @@ struct VerySimpleRules: Rules {
|
|
|
|
} else if cell.cellType != .jungle {
|
|
|
|
} else if cell.cellType != .jungle {
|
|
|
|
throw InvalidBoardError.badCellType(cell.cellType, row, col)
|
|
|
|
throw InvalidBoardError.badCellType(cell.cellType, row, col)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Vérifier la conformité des pièces
|
|
|
|
// Vérifier la conformité des pièces
|
|
|
|
if let piece = cell.piece {
|
|
|
|
if let piece = cell.piece {
|
|
|
|
if piece.owner != .player1 && piece.owner != .player2 {
|
|
|
|
if piece.owner != .player1 && piece.owner != .player2 {
|
|
|
|
throw InvalidBoardError.pieceWithNoOwner(piece)
|
|
|
|
throw InvalidBoardError.pieceWithNoOwner(piece)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Autres vérifications de pièces peuvent être ajoutées ici
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -77,15 +75,16 @@ struct VerySimpleRules: Rules {
|
|
|
|
|
|
|
|
|
|
|
|
func getMoves(board: Board, owner: Owner) -> [Move] {
|
|
|
|
func getMoves(board: Board, owner: Owner) -> [Move] {
|
|
|
|
var moves = [Move]()
|
|
|
|
var moves = [Move]()
|
|
|
|
|
|
|
|
|
|
|
|
for row in 0..<board.nbRows {
|
|
|
|
for row in 0..<board.nbRows {
|
|
|
|
for col in 0..<board.nbColumns {
|
|
|
|
for col in 0..<board.nbColumns {
|
|
|
|
if let cell = board.grid[row][col], cell.piece?.owner == owner {
|
|
|
|
let cell = board.grid[row][col]
|
|
|
|
|
|
|
|
if cell.piece?.owner == owner {
|
|
|
|
moves.append(contentsOf: getMoves(board: board, owner: owner, row: row, column: col))
|
|
|
|
moves.append(contentsOf: getMoves(board: board, owner: owner, row: row, column: col))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return moves
|
|
|
|
return moves
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -94,53 +93,65 @@ struct VerySimpleRules: Rules {
|
|
|
|
|
|
|
|
|
|
|
|
// Directions: haut, bas, gauche, droite
|
|
|
|
// Directions: haut, bas, gauche, droite
|
|
|
|
let directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
|
|
|
|
let directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
|
|
|
|
|
|
|
|
|
|
|
|
for (dRow, dCol) in directions {
|
|
|
|
for (dRow, dCol) in directions {
|
|
|
|
let newRow = row + dRow
|
|
|
|
let newRow = row + dRow
|
|
|
|
let newCol = column + dCol
|
|
|
|
let newCol = column + dCol
|
|
|
|
|
|
|
|
|
|
|
|
if newRow >= 0, newRow < board.nbRows, newCol >= 0, newCol < board.nbColumns,
|
|
|
|
if newRow >= 0, newRow < board.nbRows, newCol >= 0, newCol < board.nbColumns {
|
|
|
|
let destinationCell = board.grid[newRow][newCol],
|
|
|
|
let destinationCell = board.grid[newRow][newCol]
|
|
|
|
destinationCell.piece?.owner != owner {
|
|
|
|
if destinationCell.piece?.owner != owner {
|
|
|
|
moves.append(Move(owner: owner, rowOrigin: row, columnOrigin: column, rowDestination: newRow, columnDestination: newCol))
|
|
|
|
moves.append(Move(owner: owner, rowOrigin: row, columnOrigin: column, rowDestination: newRow, columnDestination: newCol))
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return moves
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return moves
|
|
|
|
return moves
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func isMoveValid(board: Board, move: Move) -> Bool {
|
|
|
|
func isMoveValid(board: Board, move: Move) -> Bool {
|
|
|
|
// Vérifier si les coordonnées de destination sont valides
|
|
|
|
// Vérifier si les coordonnées de destination sont valides
|
|
|
|
if move.rowDestination < 0 || move.rowDestination >= board.nbRows ||
|
|
|
|
if move.rowDestination < 0 || move.rowDestination >= board.nbRows ||
|
|
|
|
move.columnDestination < 0 || move.columnDestination >= board.nbColumns {
|
|
|
|
move.columnDestination < 0 || move.columnDestination >= board.nbColumns {
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Vérifier si la case de destination est occupée par une pièce du même joueur
|
|
|
|
// 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 destinationCell = board.grid[move.rowDestination][move.columnDestination]
|
|
|
|
let piece = destinationCell.piece,
|
|
|
|
if let piece = destinationCell.piece, piece.owner == move.owner {
|
|
|
|
piece.owner == move.owner {
|
|
|
|
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Autres vérifications spécifiques au jeu peuvent être ajoutées ici
|
|
|
|
// Autres vérifications spécifiques au jeu peuvent être ajoutées ici
|
|
|
|
// ...
|
|
|
|
// ...
|
|
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func isMoveValid(board: Board, row: Int, column: Int, rowArrived: Int, columnArrived: Int) -> Bool {
|
|
|
|
func isMoveValid(board: Board, row: Int, column: Int, rowArrived: Int, columnArrived: Int) -> Bool {
|
|
|
|
<#code#>
|
|
|
|
let move = Move(owner: board.grid[row][column].piece?.owner ?? .noOne,
|
|
|
|
|
|
|
|
rowOrigin: row,
|
|
|
|
|
|
|
|
columnOrigin: column,
|
|
|
|
|
|
|
|
rowDestination: rowArrived,
|
|
|
|
|
|
|
|
columnDestination: columnArrived)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return isMoveValid(board: board, move: move)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func isGameOver(board: Board, lastMove: Move) -> (Bool, Result) {
|
|
|
|
func isGameOver(board: Board, lastMove: Move) -> (Bool, Result) {
|
|
|
|
// Vérifier si la tannière de l'adversaire a été atteinte
|
|
|
|
// Vérifier si la tannière de l'adversaire a été atteinte
|
|
|
|
let opponent = lastMove.owner == .player1 ? .player2 : .player1
|
|
|
|
var opponent: Owner
|
|
|
|
if let destinationCell = board.grid[lastMove.rowDestination][lastMove.columnDestination],
|
|
|
|
if lastMove.owner == .player1 {
|
|
|
|
destinationCell.cellType == .den, destinationCell.initialOwner == opponent {
|
|
|
|
opponent = .player2
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
opponent = .player1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let destinationCell = board.grid[lastMove.rowDestination][lastMove.columnDestination]
|
|
|
|
|
|
|
|
if destinationCell.cellType == .den, destinationCell.initialOwner == opponent {
|
|
|
|
return (true, .winner(lastMove.owner, .denReached))
|
|
|
|
return (true, .winner(lastMove.owner, .denReached))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Vérifier si l'adversaire n'a plus de pièces
|
|
|
|
// Vérifier si l'adversaire n'a plus de pièces
|
|
|
|
let hasOpponentPieces = board.grid.flatMap { $0 }.contains { cell in
|
|
|
|
let hasOpponentPieces = board.grid.flatMap { $0 }.contains { cell in
|
|
|
|
guard let piece = cell.piece else { return false }
|
|
|
|
guard let piece = cell.piece else { return false }
|
|
|
@ -149,19 +160,26 @@ struct VerySimpleRules: Rules {
|
|
|
|
if !hasOpponentPieces {
|
|
|
|
if !hasOpponentPieces {
|
|
|
|
return (true, .winner(lastMove.owner, .noMorePieces))
|
|
|
|
return (true, .winner(lastMove.owner, .noMorePieces))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Vérifier si l'adversaire ne peut plus bouger
|
|
|
|
// Vérifier si l'adversaire ne peut plus bouger
|
|
|
|
let opponentMoves = getMoves(board: board, owner: opponent)
|
|
|
|
let opponentMoves = getMoves(board: board, owner: opponent)
|
|
|
|
if opponentMoves.isEmpty {
|
|
|
|
if opponentMoves.isEmpty {
|
|
|
|
return (true, .winner(lastMove.owner, .noMovesLeft))
|
|
|
|
return (true, .winner(lastMove.owner, .noMovesLeft))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Si aucune condition de victoire n'est remplie, la partie n'est pas encore terminée
|
|
|
|
// Si aucune condition de victoire n'est remplie, la partie n'est pas encore terminée
|
|
|
|
return (false, .notFinished)
|
|
|
|
return (false, .notFinished)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func playedMove(move: Move, oldBoard: Board, newBoard: Board) {
|
|
|
|
func playedMove(move: Move, oldBoard: Board, newBoard: Board) {
|
|
|
|
<#code#>
|
|
|
|
// ToDo
|
|
|
|
|
|
|
|
// Ajouter le mouvement à l'historique
|
|
|
|
|
|
|
|
// historic.append(move)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Mise à jour du comptage des occurrences pour le nouveau plateau
|
|
|
|
|
|
|
|
// occurences[newBoard, default: 0] += 1
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|