diff --git a/Connect4/connect4_cli/connect4_cli/main.swift b/Connect4/connect4_cli/connect4_cli/main.swift index 5bcc87a..45874ee 100644 --- a/Connect4/connect4_cli/connect4_cli/main.swift +++ b/Connect4/connect4_cli/connect4_cli/main.swift @@ -11,60 +11,43 @@ public func scan() -> Int { return res! } -var chosenCol: Int? -var wasPlayed = false -var status: (isOver: Bool, result: Result) = (false, .notOver) -var currentId: Int -var currentPlayer: Player -let p1id = 1, p2id = 2 -let p1name = "Alice", p2name = "Bob the bot" +var status: (isOver: Bool, result: Result) +print("nothing yet") +if let rules = BasicDefaultsNoDiag() { + print("rules") -if let rules = BasicDefaultsNoDiag(withMinNbRows: 3, - withMaxNbRows: 5, - withMinNbCols: 3, - withMaxNbCols: 5, - withNbChipsToAlign: 3) { - - if var board = Board(withRows: 3, - andWithCols: 3) { - - if let me = Human(withId: p1id, - withName: p1name, + if let board = Board() { + print("board") + + if let human = Human(withId: 1, + withName: "Geraldine Humanman", usingScanner: scan) { - - if let them = Bot(withId: p2id, - withName: p2name) { - - print(board) // 1st turn - while(!(status.isOver)) { - - currentId = rules.getNextPlayer(fromGrid: board.grid, - withPlayer1Id: p1id, - withPlayer2Id: p2id) - currentPlayer = { - if(me.id == currentId) { return me } - else { return them } - }() - if let chosenCol = currentPlayer.chooseColumn(inBoard: board, - withRules: rules) { - if(board.insertChip(from: currentId, - atCol: chosenCol)) { - print(board) - status = rules.isGameOver(byPlayer: currentId, - onGrid: board.grid) + print("human") + + if let bot = Bot(withId: 2, + withName: "Botty McBotFace") { + print("bot") + + if let game = Game(withScanner : scan, + withBoard: board, + withRules: rules, + withPlayer1: human, + withPlayer2: bot) { + print("game") + + status = game.isOver + print(game.boardString) // 1st turn + while(!(status.isOver)) { + if game.play() { + print(game.boardString) + status = game.isOver } } - } - - print("Game over") - switch(status.result) { - case .won(let playerId, let victoryTiles): - print("Player \(playerId) won!") - print(board.displayVictory(fromTiles: victoryTiles)) - default: break; // nothing + + print(game.gameOverString) + } } - } } } diff --git a/Connect4/connect4_lib/Sources/connect4_lib/boards/Board.swift b/Connect4/connect4_lib/Sources/connect4_lib/boards/Board.swift index 67868d8..571183d 100644 --- a/Connect4/connect4_lib/Sources/connect4_lib/boards/Board.swift +++ b/Connect4/connect4_lib/Sources/connect4_lib/boards/Board.swift @@ -51,13 +51,14 @@ public struct Board : CustomStringConvertible { && 0 <= col && col < nbCols } - static let descriptionMapper : [Int? : String] = [nil : "-", 1 : "X", 2: "O"] + static let descriptionMapper : [Int? : String] = [nil : "□", 1 : "X", 2: "O"] public var description: String { var string = String() for row in _grid { for tile in row { string.append("\(String(describing: Board.descriptionMapper[tile] ?? "@"))") + string.append(" ") } string.append("\n") } @@ -71,7 +72,7 @@ public struct Board : CustomStringConvertible { var string = String() for row in tmpGrid { - for tile in row { string.append(tile == nil ? "@" : "$") } + for tile in row { string.append(tile == nil ? "□ " : "$ ") } string.append("\n") } return string diff --git a/Connect4/connect4_lib/Sources/connect4_lib/games/Game.swift b/Connect4/connect4_lib/Sources/connect4_lib/games/Game.swift index 013781c..b27c70a 100644 --- a/Connect4/connect4_lib/Sources/connect4_lib/games/Game.swift +++ b/Connect4/connect4_lib/Sources/connect4_lib/games/Game.swift @@ -2,12 +2,12 @@ import Foundation public class Game { private let scanner: () -> Int private let displayBoard: () -> String - private let board: Board + private var board: Board private let rules: IRules private let player1: Player private let player2: Player - init(withScanner scanner: @escaping () -> Int, + public init?(withScanner scanner: @escaping () -> Int, withBoard board: Board, withRules rules: IRules, withPlayer1 player1: Player, @@ -16,9 +16,54 @@ public class Game { self.displayBoard = { () -> String in return board.description } + guard(rules.isValid(board)) else { return nil } self.board = board self.rules = rules self.player1 = player1 self.player2 = player2 } + + public var isOver: (isOver: Bool, result: Result) { + return rules.isGameOver(byPlayer: getCurrentPlayerId(), + onGrid: board.grid) + } + + public var boardString: String { + return board.description + } + + public var gameOverString: String { + var string = "Game over" + + switch(isOver.result) { + case .won(let playerId, let victoryTiles): + string.append("\nPlayer \(playerId) won!\n") + string.append(board.displayVictory(fromTiles: victoryTiles)) + default: break; // nothing + } + + return string + } + + public func play() -> Bool { + + let currentPlayer = { + if(rules.getNextPlayer(fromGrid: board.grid, + withPlayer1Id: player1.id, + withPlayer2Id: player2.id) == player1.id) { return player1 } else { return player2 } + }() + + if let chosenCol = currentPlayer.chooseColumn(inBoard: board, + withRules: rules) { + return board.insertChip(from: currentPlayer.id, atCol: chosenCol) + } + return false + } + + private func getCurrentPlayerId() -> Int { + if(rules.getNextPlayer(fromGrid: board.grid, + withPlayer1Id: player1.id, + withPlayer2Id: player2.id) == player1.id) { return player2.id } else { return player1.id } + } + }