diff --git a/Connect4.xcworkspace/contents.xcworkspacedata b/Connect4.xcworkspace/contents.xcworkspacedata
index 2c5a92b..b2758ea 100644
--- a/Connect4.xcworkspace/contents.xcworkspacedata
+++ b/Connect4.xcworkspace/contents.xcworkspacedata
@@ -5,6 +5,6 @@
location = "group:Model">
+ location = "group:Connect4_CLI/Connect4_CLI.xcodeproj">
diff --git a/Connect4_CLI/Connect4_CLI.xcodeproj/project.pbxproj b/Connect4_CLI/Connect4_CLI.xcodeproj/project.pbxproj
index 5f240b3..7a7536a 100644
--- a/Connect4_CLI/Connect4_CLI.xcodeproj/project.pbxproj
+++ b/Connect4_CLI/Connect4_CLI.xcodeproj/project.pbxproj
@@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
90BAEDC82D34F75500C6B480 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90BAEDC72D34F75500C6B480 /* main.swift */; };
+ 90C8428D2D50D02200DDFF08 /* Model in Frameworks */ = {isa = PBXBuildFile; productRef = 90C8428C2D50D02200DDFF08 /* Model */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -25,7 +26,6 @@
/* Begin PBXFileReference section */
90BAEDC42D34F75500C6B480 /* Connect4_CLI */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Connect4_CLI; sourceTree = BUILT_PRODUCTS_DIR; };
90BAEDC72D34F75500C6B480 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
- 90BAEDCE2D34F78600C6B480 /* Model */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Model; path = ../Model; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -33,6 +33,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 90C8428D2D50D02200DDFF08 /* Model in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -42,9 +43,9 @@
90BAEDBB2D34F75500C6B480 = {
isa = PBXGroup;
children = (
- 90BAEDCE2D34F78600C6B480 /* Model */,
90BAEDC62D34F75500C6B480 /* Connect4_CLI */,
90BAEDC52D34F75500C6B480 /* Products */,
+ 90C8428B2D50D02200DDFF08 /* Frameworks */,
);
sourceTree = "";
};
@@ -64,6 +65,13 @@
path = Connect4_CLI;
sourceTree = "";
};
+ 90C8428B2D50D02200DDFF08 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -80,6 +88,9 @@
dependencies = (
);
name = Connect4_CLI;
+ packageProductDependencies = (
+ 90C8428C2D50D02200DDFF08 /* Model */,
+ );
productName = Connect4_CLI;
productReference = 90BAEDC42D34F75500C6B480 /* Connect4_CLI */;
productType = "com.apple.product-type.tool";
@@ -282,6 +293,13 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ 90C8428C2D50D02200DDFF08 /* Model */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = Model;
+ };
+/* End XCSwiftPackageProductDependency section */
};
rootObject = 90BAEDBC2D34F75500C6B480 /* Project object */;
}
diff --git a/Connect4_CLI/Connect4_CLI/main.swift b/Connect4_CLI/Connect4_CLI/main.swift
index 80cdedc..711b143 100644
--- a/Connect4_CLI/Connect4_CLI/main.swift
+++ b/Connect4_CLI/Connect4_CLI/main.swift
@@ -6,6 +6,30 @@
//
import Foundation
+import Model
-print("Hello, World!")
+print("Connect4")
+func read(question: String) -> String {
+ print(question)
+ let answer = readLine()
+ if let answer {
+ return answer
+ } else {
+ return ""
+ }
+}
+
+var board = Board(rowsNb: 6, columnsNb: 7)
+var rules = Connect4Rules(piecesToAlign: 4)
+var player1: Player = HumanPlayer(rules: rules, color: .red, name: "player1", CLI: read)
+var player2: Player = HumanPlayer(rules: rules, color: .yellow, name: "player2", CLI: read)
+
+while rules.isGameOver(board: board).0 != true {
+ var move = player1.play()
+ while rules.possibleMoves(board: board).contains(move) != true {
+ print("Move invalide en choisir un autre")
+ move = player1.play()
+ }
+ board[move.row, move.column] = player1.color
+}
diff --git a/Model/Sources/Model/Board.swift b/Model/Sources/Model/Board.swift
index 8fb3e58..67e07e4 100644
--- a/Model/Sources/Model/Board.swift
+++ b/Model/Sources/Model/Board.swift
@@ -18,7 +18,7 @@ public struct Board {
grid = Array(repeating: Array(repeating: Token.empty, count: columnsNb), count: rowsNb)
}
- subscript(row: Int, column: Int) -> Token {
+ public subscript(row: Int, column: Int) -> Token {
get {
guard row >= 0 && row < rowNb && column >= 0 && column < columnNb else {
fatalError("Out of board")
diff --git a/Model/Sources/Model/Connect4Rules.swift b/Model/Sources/Model/Connect4Rules.swift
index 8fb70f8..11f0c70 100644
--- a/Model/Sources/Model/Connect4Rules.swift
+++ b/Model/Sources/Model/Connect4Rules.swift
@@ -96,14 +96,14 @@ public struct Connect4Rules : Rules {
return true
}
- func possibleMoves(board: Board) -> [(row: Int, column: Int)] {
- var possibleMoves: [(Int, Int)] = []
+ public func possibleMoves(board: Board) -> [Move] {
+ var possibleMoves: [Move] = []
for column in 0.. String)?
+ private var CLI: ((String) -> String)?
// Initialisation avec la closure CLI
- init(CLI: @escaping (String) -> String) {
+ public init(rules: Rules, color: Token, name: String, CLI: @escaping (String) -> String) {
self.CLI = CLI
- super.init()
+ super.init(rules: rules, color: color, name: name)
}
- override func play() -> (row: Int, column: Int) {
+ public override func play() -> Move {
// Demande la colonne à l'utilisateur
let columnInput = CLI!("Entrez le numéro de la colonne : ")
guard let column = Int(columnInput) else {
@@ -27,6 +27,6 @@ class HumanPlayer : Player {
guard let row = Int(rowInput) else {
fatalError("Entrée invalide pour la ligne.")
}
- return (row, column)
+ return Move(row: row, column: column)
}
}
diff --git a/Model/Sources/Model/Player/Player.swift b/Model/Sources/Model/Player/Player.swift
index e5a8162..c051a71 100644
--- a/Model/Sources/Model/Player/Player.swift
+++ b/Model/Sources/Model/Player/Player.swift
@@ -6,16 +6,16 @@
//
import Foundation
-class Player {
+public class Player {
var name: String
- var color: Token
+ public let color: Token
var rules: Rules
- init(rules: Rules, color: Token, name: String){
+ public init(rules: Rules, color: Token, name: String){
self.name = name
self.color = color
self.rules = rules
}
- func play() -> (row: Int, column: Int){
+ public func play() -> Move {
fatalError("Must override in subclass")
}
}
diff --git a/Model/Sources/Model/Player/RandomPlayer.swift b/Model/Sources/Model/Player/RandomPlayer.swift
index f72e756..afa14af 100644
--- a/Model/Sources/Model/Player/RandomPlayer.swift
+++ b/Model/Sources/Model/Player/RandomPlayer.swift
@@ -7,7 +7,7 @@
import Foundation
class RandomPlayer : AIPlayer {
- override func play() -> (row: Int, column: Int) {
- return (0, 0)
+ override func play() -> Move {
+ return Move(row: 0, column: 0)
}
}
diff --git a/Model/Sources/Model/Rules.swift b/Model/Sources/Model/Rules.swift
index f48b4d2..8465292 100644
--- a/Model/Sources/Model/Rules.swift
+++ b/Model/Sources/Model/Rules.swift
@@ -6,9 +6,10 @@
//
import Foundation
-protocol Rules {
+
+public protocol Rules {
func add(board: inout Board, position pos: (row: Int, column: Int), token: Token) -> Bool
func isGameOver(board: Board) -> (result: Bool, winner: Token)
- func possibleMoves(board: Board) -> [(row: Int, column: Int)]
+ func possibleMoves(board: Board) -> [Move]
}
diff --git a/Model/Sources/Model/TicTacToeRules.swift b/Model/Sources/Model/TicTacToeRules.swift
index 4a9fb06..28040b4 100644
--- a/Model/Sources/Model/TicTacToeRules.swift
+++ b/Model/Sources/Model/TicTacToeRules.swift
@@ -8,13 +8,13 @@
import Foundation
public struct TicTacToeRules: Rules {
- func possibleMoves(board: Board) -> [(row: Int, column: Int)] {
- var possibleMoves: [(Int, Int)] = []
+ public func possibleMoves(board: Board) -> [Move] {
+ var possibleMoves: [Move] = []
for column in 0.. Bool {
+ public func add(board: inout Board, position pos: (row: Int, column: Int), token: Token) -> Bool {
if board[pos.0, pos.1] == .empty {
board[pos.0, pos.1] = token
return true
@@ -30,7 +30,7 @@ public struct TicTacToeRules: Rules {
return false
}
- func isGameOver(board: Board) -> (result: Bool, winner: Token) {
+ public func isGameOver(board: Board) -> (result: Bool, winner: Token) {
// Need to be complete
// TODO
return (false, Token.empty)