import XCTest @testable import Model final class FourInARowRulesTests: XCTestCase { private var rules: FourInARowRules! private var board: Board! override func setUpWithError() throws { try super.setUpWithError() guard let rules = FourInARowRules(columns: 3, rows: 3, minAligned: 3) else { XCTFail() return } self.rules = rules self.board = self.rules.createBoard() } func testEmptyHistory() { XCTAssertTrue(self.rules.history.isEmpty) } func testBoardIsValid() { XCTAssertTrue(self.rules.isValid(board: self.board)) } func testState() { XCTAssertEqual(self.rules.state, GameState.Playing(turn: .A)) } func testMovesAreValid() { for move in self.rules.validMoves(board: self.board) { rules.state = .Playing(turn: move.player) XCTAssertTrue(self.rules.isValid(board: board, move: move), "\(move)") } } func testMovesOfPlayerAreValid() throws { for player in PieceType.allCases { try self.setUpWithError() try self._testMovesOfPlayerAreValid(player: player) try self.tearDownWithError() } } private func _testMovesOfPlayerAreValid(player: PieceType) throws { for action in self.rules.validMoves(board: self.board, for_player: player) { rules.state = .Playing(turn: player) XCTAssertTrue(self.rules.isValid(board: board, move: Move(player: player, action: action)), "\(action)") } } func testOnMoveDone() { let coord = Coords(1, board.rows - 1) board[coord] = Piece(type: .A) let move = Move(player: .A, action: .InsertOnSide(side: .Top, offset: 1)) self.rules.onMoveDone(move: move, board: self.board) XCTAssertEqual(self.rules.state, GameState.Playing(turn: .B)) XCTAssertEqual(self.rules.history.last, move) } func testOnMoveDoneDraw() { board[0, 0] = Piece(type: .A) board[1, 0] = Piece(type: .A) board[2, 0] = Piece(type: .B) board[0, 1] = Piece(type: .B) board[1, 1] = Piece(type: .B) board[2, 1] = Piece(type: .A) board[0, 2] = Piece(type: .A) board[1, 2] = Piece(type: .A) board[2, 2] = Piece(type: .B) XCTAssertTrue(rules.isValid(board: board)) let move = Move(player: .B, action: .InsertOnSide(side: .Top, offset: 2)) self.rules.onMoveDone(move: move, board: board) XCTAssertEqual(rules.state, GameState.Finished(winner: nil)) } func testOnMoveDoneWin() { board[0, 0] = Piece(type: .A) board[1, 0] = Piece(type: .A) board[2, 0] = Piece(type: .A) // board[0, 1] = Piece(type: .B) board[1, 1] = Piece(type: .B) board[2, 1] = Piece(type: .A) board[0, 2] = Piece(type: .A) board[1, 2] = Piece(type: .A) board[2, 2] = Piece(type: .B) XCTAssertTrue(rules.isValid(board: board)) let move = Move(player: .A, action: .InsertOnSide(side: .Top, offset: 2)) self.rules.onMoveDone(move: move, board: board) XCTAssertEqual(rules.state, GameState.Finished(winner: .A)) } func testCountMaxRow() throws { for (coords, expected) in [ (Coords(1, 0), 3), (Coords(0, 1), 2), (Coords(0, 2), 2), (Coords(1, 1), 3), (Coords(2, 2), 3), (Coords(2, 1), 2), ] { try self.setUpWithError() // AAA // BAB // BBA board[0, 0] = Piece(type: .A) board[1, 0] = Piece(type: .A) board[2, 0] = Piece(type: .A) board[0, 1] = Piece(type: .B) board[1, 1] = Piece(type: .A) board[2, 1] = Piece(type: .B) board[0, 2] = Piece(type: .B) board[1, 2] = Piece(type: .B) board[2, 2] = Piece(type: .A) self._testCountMaxRow(coords: coords, expected: expected) try self.tearDownWithError() } } private func _testCountMaxRow(coords: Coords, expected: Int) { XCTAssertEqual(FourInARowRules.countMaxRow(center: coords, board: board), expected, "\(coords)") } }