diff --git a/Sources/CommandConsole b/Sources/CommandConsole
deleted file mode 160000
index bd4c7ff..0000000
--- a/Sources/CommandConsole
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit bd4c7ffd777bbfdebec09917d66c818c6ed4f873
diff --git a/Sources/HelloCLT/HelloCLT.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Sources/HelloCLT/HelloCLT.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/Sources/HelloCLT/HelloCLT.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/Sources/HelloCLT/HelloCLT.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Sources/HelloCLT/HelloCLT.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Sources/HelloCLT/HelloCLT.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Sources/HelloCLT/HelloCLT/main.swift b/Sources/HelloCLT/HelloCLT/main.swift
index ce0a84d..5479654 100644
--- a/Sources/HelloCLT/HelloCLT/main.swift
+++ b/Sources/HelloCLT/HelloCLT/main.swift
@@ -1,14 +1,30 @@
//
// main.swift
-// HelloCLT
+// MainJeux
//
-// Created by Marc Chevaldonné on 03/05/2022.
+// Created by etudiant on 09/02/2023.
//
-import HelloLibrary
-
import Foundation
-let helloStruct = HelloStruct()
-print(helloStruct.text)
+import MyJeux
+
+let lecteur = Lecteur()
+let afficheur = Afficheur()
+var b = Board()
+
+if let board = b {
+ let player1 = Human(nom: "Arafa", playedOn: board, readOn: lecteur)
+ let player2 = IA(nom: "Najlae", playedOn: board)
+ let rule = ClassicRules(withBoard: board)
+ var game = Game(withBoard: board, playedBy: [player1, player2], withRules: rule!, writeOn: afficheur)
+ var winner : Player?
+ while winner == nil && rule!.isGameOver()
+ {
+ winner = game?.tour()
+ }
+
+ afficheur.afficherLigne(message: "Le gagnant est \(winner?.nom)")
+}
+
diff --git a/Sources/HelloLibrary/Sources/HelloLibrary/Afficheur.swift b/Sources/HelloLibrary/Sources/HelloLibrary/Afficheur.swift
new file mode 100644
index 0000000..1c145c4
--- /dev/null
+++ b/Sources/HelloLibrary/Sources/HelloLibrary/Afficheur.swift
@@ -0,0 +1,15 @@
+//
+// File.swift
+//
+//
+// Created by etudiant on 09/02/2023.
+//
+
+import Foundation
+public class Afficheur {
+ public init() {}
+ //cette Fonction affiche une ligne de message
+ public func afficherLigne(message msg: String){
+ print(msg)
+ }
+}
diff --git a/Sources/HelloLibrary/Sources/HelloLibrary/Board.swift b/Sources/HelloLibrary/Sources/HelloLibrary/Board.swift
new file mode 100644
index 0000000..6e5d131
--- /dev/null
+++ b/Sources/HelloLibrary/Sources/HelloLibrary/Board.swift
@@ -0,0 +1,160 @@
+//
+// File.swift
+//
+//
+// Created by etudiant on 09/02/2023.
+//
+
+import Foundation
+public struct Board: CustomStringConvertible {
+ // La grille du tableau qui peut contenir des valeurs nues (nil) ou des entiers (1 ou 2)
+ var grid: [[Int?]];
+ // Le nombre de lignes dans la grille
+ let nbRows: Int;
+ // Le nombre de colonnes dans la grille
+ let nbColumns: Int;
+ // Une table de correspondance qui mappe les entiers (1 et 2) aux valeurs de chaînes "O" et "X"
+ private static let descriptionMapper: [Int?:String] = [nil:" ", 1:"O", 2:"X"];
+ // Initialiseur qui permet de créer une grille avec le nombre de lignes et de colonnes données
+ public init?(n1: Int = 4, n2: Int = 5) {
+ // Si n1 ou n2 sont inférieurs ou égaux à 0, retournez nil
+ if n1 <= 0 || n2 <= 0 {
+ return nil
+ }
+ // Définit le nombre de lignes et de colonnes
+ self.nbRows = n1
+ self.nbColumns = n2
+ // Initialise la grille avec des valeurs nues (nil)
+ self.grid = Array(repeating: Array(repeating: nil, count: n2), count: n1)
+ }
+
+ public init?(withGrid grid : [[Int?]]){
+ // Récupère les tailles de chaque colonne dans la grille donnée
+ let sizes = grid.map{ return $0.count }
+ // Vérifie que toutes les tailles correspondent à la taille de la première colonne
+ let result = sizes.allSatisfy {
+ $0 == grid[0].count
+ }
+ // Si toutes les tailles ne correspondent pas, retournez nil
+ guard result else {
+ return nil
+ }
+ // Définit le nombre de lignes et de colonnes en fonction de la grille donnée
+ nbRows = grid.count
+ nbColumns = grid[0].count
+ // Utilise la grille donnée pour initialiser la grille
+ self.grid=grid
+ }
+
+
+ public var description: String {
+ // déclaration de la variable de sortie string qui sera retournée
+ var string = String()
+ // déclaration de la variable de sortie string qui sera retournée
+ for row in grid {
+ // ajout d'un séparateur de ligne pour séparer les lignes
+ string.append("| ")
+ // boucle pour parcourir les cellules dans la ligne actuelle
+ for cell in row {
+ // ajout de la description de la cellule dans la chaîne string. Si la cellule est vide, un espace vide est ajouté
+ string.append("\(String(describing: Board.descriptionMapper[cell] ?? " "))")
+ // ajout d'un séparateur de colonne pour séparer les cellules
+ string.append(" | ")
+ }
+ // ajout d'un saut de ligne pour passer à la ligne suivante
+ string.append("\n")
+ }
+ // ajout d'un séparateur de ligne pour séparer les lignes de la grille
+ string.append("|")
+ for _ in 0...grid.count{
+ string.append("---|")
+ }
+ // ajout de l'index de colonne en dessous de la grille
+ string.append("\n")
+
+ string.append("|")
+ for i in 0...grid.count{
+ string.append(" \(i) |")
+ }
+ // retourne la chaîne string construite
+ return string
+ }
+
+ private func isFull() -> Bool {
+ // boucle pour parcourir les colonnes
+ for column in 0...nbColumns{
+ // si la colonne n'est pas pleine, retourne false
+ if !isColumnFull(column: column) {
+ return false
+ }
+ }
+ // si toutes les colonnes sont pleines, retourne true
+ return true
+ }
+
+ private func isColumnFull(column: Int) -> Bool{
+ for row in 0.. BoardResult {
+ // vérifie si la ligne et la colonne sont dans les limites de la grille
+ guard row >= 0 && row < nbRows && column >= 0 && column < nbColumns else {
+ // retourne une erreur si les coordonnées sont en dehors de la grille
+ return .failed(.outOfBound)
+ }
+ // vérifie si la cellule est déjà remplie
+ guard grid[row][column] == nil else {
+ return .failed(.unknown)
+ }
+
+ grid[row][column] = id
+ return .ok
+ }
+ // Fonction pour insérer une pièce dans une colonne particulière
+ public mutating func insertPiece(id:Int, column:Int) -> BoardResult {
+ // Initialiser le résultat comme étant inconnu
+ var result = BoardResult.unknown
+ // Boucle à travers les lignes dans l'ordre inverse
+ for row in (0.. BoardResult {
+ guard row >= 0 && row < nbRows && column >= 0 && column < nbColumns else {
+ return .failed(.outOfBound)
+ }
+
+ grid[row][column] = nil
+ return .ok
+ }
+
+ public mutating func clearGrid(){
+ for r in 0..= Minnbrcoln && board.nbRows >= MinnbrRow else {
+ return nil
+ }
+ self.board = board
+ }
+ // Fonction pour déterminer si une pièce a été insérée dans une colonne donnée
+ // et si elle a formé une combinaison gagnante.
+ public func isValid(column: Int) -> Int {
+ let grid = board.grid
+ var y = 0;
+ var id = 0
+ // Appel de la fonction pour obtenir la dernière ligne et l'ID de la dernière pièce insérée dans cette colonne
+ (y, id) = gettheLast(column: column)
+ // Variables pour stocker le score actuel et la valeur de retour
+ var score = 0
+
+ // Définir les bornes pour la vérification des lignes, des colonnes et des diagonales
+ var minX = column - 3
+ if minX < 0 {
+ minX = 0
+ }
+ var maxX = column + 3
+ if maxX >= board.nbColumns {
+ maxX = board.nbColumns - 1
+ }
+ var minY = y - 3
+ if minY < 0 {
+ minY = 0
+ }
+ var maxY = y + 3
+ if maxY >= board.nbRows {
+ maxY = board.nbRows - 1
+ }
+
+ // Vérification de la ligne horizontale
+ for i in minX...maxX {
+ if grid[y][i] == id {
+ score += 1
+ } else {
+ score = 0
+ }
+ }
+ if score >= 4 { return id }
+
+ // Vérification de la colonne verticale
+ for i in minY...maxY {
+ if grid[i][column] == id {
+ score += 1
+ } else {
+ score = 0
+ }
+ }
+ if score >= 4 { return id }
+
+ // Vérification de la diagonale allant du nord-ouest au sud-est
+ var minCoord = min(minX, minY)
+ var maxCoord = min(maxX, maxY)
+ for i in minCoord...maxCoord {
+ if grid[i][i] == id {
+ score += 1
+ } else {
+ score = 0
+ }
+ }
+ if score >= 4 { return id }
+
+ // Vérification de la diagonale allant du nord-est au sud-ouest
+ minCoord = min(maxX, minY)
+ maxCoord = min(minX, maxY)
+ for i in minCoord...maxCoord {
+ if grid[i][i] == id {
+ score += 1
+ } else {
+ score = 0
+ }
+ }
+ if score >= 4 { return id }
+ return 0
+ }
+ // Cette fonction privée `gettheLast` trouve la dernière case remplie dans une colonne donnée.
+ private func gettheLast(column: Int) -> (Int, Int) {
+ let grid = board.grid
+ var y = 0;
+ var id = 0
+ // Boucle sur toutes les lignes de la grille.
+ for i in 0.. Bool {
+ isOver = true
+ for i in 0.. Player?{
+ // On récupère le joueur actuel.
+ let player = players[numero]
+ // On initialise le résultat de l'insertion de la pièce sur le plateau.
+ var result = BoardResult.unknown
+ var choice = 0
+ // Tant que la pièce ne peut pas être insérée sur le plateau, on demande au joueur où il souhaite insérer la pièce.
+ while( result != BoardResult.ok){
+ afficheur.afficherLigne(message: "\nJoueur \(player.nom), ou veut tu inserer le jeton:) ?")
+ choice = player.playInColumn()
+ afficheur.afficherLigne(message: "Le nombre choisi est \(choice).")
+ result = board.insertPiece(id: numero + 1, column: choice)
+ }
+ // On vérifie si un joueur a gagné la partie.
+ let winnerId = rule.isValid(column: choice)
+ // Si un joueur a gagné, on affiche un message pour annoncer le gagnant et on retourne le joueur gagnant.
+ if winnerId != 0 {
+ afficheur.afficherLigne(message: "\(players[winnerId].nom) a gagné !")
+ return players[winnerId]
+ }
+ joueurSuivant();
+ afficheur.afficherLigne(message: board.description)
+ return nil
+ }
+
+ public mutating func joueurSuivant() {
+ numero = (numero + 1) % players.count
+ }
+}
diff --git a/Sources/HelloLibrary/Sources/HelloLibrary/Human.swift b/Sources/HelloLibrary/Sources/HelloLibrary/Human.swift
new file mode 100644
index 0000000..7479e29
--- /dev/null
+++ b/Sources/HelloLibrary/Sources/HelloLibrary/Human.swift
@@ -0,0 +1,31 @@
+//
+// File.swift
+//
+//
+// Created by etudiant on 09/02/2023.
+//
+
+
+import Foundation
+
+// Définition de la classe "Human" qui conforme au protocole "Player"
+public class Human : Player {
+ // Propriété : "nom" de type String, avec un getter et un setter
+ public var nom: String
+ // Propriété : "board" de type Board, avec un getter et un setter
+ public var board: Board
+ private var lecteur: Lecteur
+
+ // Initialisation avec trois paramètres "nom", "board" et "lecteur"
+ public init(nom nom: String, playedOn board: Board, readOn lecteur: Lecteur){
+ self.nom = nom
+ self.board = board
+ self.lecteur = lecteur
+ }
+
+ public func playInColumn() -> Int {
+ lecteur.lireInt()
+ }
+
+
+}
diff --git a/Sources/HelloLibrary/Sources/HelloLibrary/IA.swift b/Sources/HelloLibrary/Sources/HelloLibrary/IA.swift
new file mode 100644
index 0000000..c2b5583
--- /dev/null
+++ b/Sources/HelloLibrary/Sources/HelloLibrary/IA.swift
@@ -0,0 +1,26 @@
+//
+// File.swift
+//
+//
+// Created by etudiant on 09/02/2023.
+//
+
+import Foundation
+// Définition de la classe "IA" qui conforme au protocole "Player"
+public class IA: Player {
+ // Propriété : "nom" de type String, avec un getter et un setter
+ public var nom: String
+ // Propriété : "board" de type Board, avec un getter et un setter
+ public var board: Board
+ // Initialisation avec deux paramètres "nom" et "board"
+ public init(nom nom: String, playedOn board: Board){
+ self.nom = nom
+ self.board = board
+ }
+ // Fonction : "playInColumn" qui retourne un entier aléatoire compris entre 0 et "nbColumns"
+ public func playInColumn() -> Int {
+ return Int.random(in: 0..<(board.nbColumns))
+ }
+
+
+}
diff --git a/Sources/HelloLibrary/Sources/HelloLibrary/Lecteur.swift b/Sources/HelloLibrary/Sources/HelloLibrary/Lecteur.swift
new file mode 100644
index 0000000..64d4472
--- /dev/null
+++ b/Sources/HelloLibrary/Sources/HelloLibrary/Lecteur.swift
@@ -0,0 +1,29 @@
+//
+// File.swift
+//
+//
+// Created by etudiant on 09/02/2023.
+//
+
+import Foundation
+public class Lecteur {
+ public init() {
+
+ }
+ // Lit une entrée entière de l'utilisateur et la retourne.
+ public func lireInt() -> Int{
+ // Tente de lire une ligne de l'entrée de l'utilisateur.
+ if let value = readLine() {
+ // Convertit la chaîne en entier et la retourne. Si la conversion échoue, retourne -1.
+ return Int(value) ?? -1
+ } else {
+ // Si la lecture de l'entrée échoue, retourne -1.
+ return -1
+ }
+ }
+ // Lit une entrée de ligne de l'utilisateur et la retourne sous forme de chaîne.
+ public func lireLigne() -> String? {
+ // Lit une ligne de l'entrée de l'utilisateur et la retourne sous forme de chaîne.
+ return readLine()
+ }
+}
diff --git a/Sources/HelloLibrary/Sources/HelloLibrary/HelloStruct.swift b/Sources/HelloLibrary/Sources/HelloLibrary/MyJeux.swift
similarity index 74%
rename from Sources/HelloLibrary/Sources/HelloLibrary/HelloStruct.swift
rename to Sources/HelloLibrary/Sources/HelloLibrary/MyJeux.swift
index 9ebdb96..11b514d 100644
--- a/Sources/HelloLibrary/Sources/HelloLibrary/HelloStruct.swift
+++ b/Sources/HelloLibrary/Sources/HelloLibrary/MyJeux.swift
@@ -1,4 +1,4 @@
-public struct HelloStruct {
+public struct MyJeux {
public private(set) var text = "Hello, World!"
public init() {
diff --git a/Sources/HelloLibrary/Sources/HelloLibrary/Player.swift b/Sources/HelloLibrary/Sources/HelloLibrary/Player.swift
new file mode 100644
index 0000000..054b5d5
--- /dev/null
+++ b/Sources/HelloLibrary/Sources/HelloLibrary/Player.swift
@@ -0,0 +1,22 @@
+//
+// File.swift
+//
+//
+// Created by etudiant on 09/02/2023.
+//
+
+// Import the Foundation library
+import Foundation
+
+// Define a protocol "Player"
+public protocol Player {
+
+ // Property: "nom" of type String, with both getter and setter
+ var nom: String { get set }
+
+ // Property: "board" of type Board, with both getter and setter
+ var board: Board { get set }
+
+ // Function: "playInColumn" returns an Int
+ func playInColumn() -> Int
+}
diff --git a/Sources/HelloLibrary/Sources/HelloLibrary/Rule.swift b/Sources/HelloLibrary/Sources/HelloLibrary/Rule.swift
new file mode 100644
index 0000000..0ec614c
--- /dev/null
+++ b/Sources/HelloLibrary/Sources/HelloLibrary/Rule.swift
@@ -0,0 +1,15 @@
+//
+// File.swift
+//
+//
+// Created by etudiant on 09/02/2023.
+//
+
+
+import Foundation
+
+// Pour avoir une collection de règles,la création d'une règle qui étend ce protocol, et qui contiendra une liste de rules permet de savoir les priorités des règles.
+public protocol Rule {
+ func isValid(column: Int) -> Int
+ func isGameOver() -> Bool
+}
diff --git a/Sources/HelloLibrary/Tests/HelloLibraryTests/HelloStructTests.swift b/Sources/HelloLibrary/Tests/HelloLibraryTests/HelloStructTests.swift
deleted file mode 100644
index 13ca6f5..0000000
--- a/Sources/HelloLibrary/Tests/HelloLibraryTests/HelloStructTests.swift
+++ /dev/null
@@ -1,11 +0,0 @@
-import XCTest
-@testable import HelloLibrary
-
-final class HelloStructTests: 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(HelloStruct().text, "Hello, World!")
- }
-}
diff --git a/Sources/HelloLibrary/Tests/HelloLibraryTests/MyJeuxTests.swift b/Sources/HelloLibrary/Tests/HelloLibraryTests/MyJeuxTests.swift
new file mode 100644
index 0000000..5d41212
--- /dev/null
+++ b/Sources/HelloLibrary/Tests/HelloLibraryTests/MyJeuxTests.swift
@@ -0,0 +1,40 @@
+import XCTest
+@testable import MyJeux
+
+final class MyJeuxTests: XCTestCase {
+
+ func manipulation() {
+ var board = Board(n1: 4, n2: 4)
+ board?.insertPiece(id: 1, column: 2)
+ XCTAssertEqual(1, board?.grid[3][2])
+ board?.removePiece(row: 3, column: 2)
+ XCTAssertNil(board?.grid[3][2])
+ }
+ func clean(){
+ var board = Board(withGrid: [[1,0,1],[0,1,0],[1,0,1]])
+ if var b = board {
+ b.clearGrid()
+ for r in 0..