parent
eef5a45899
commit
02bdfb8830
@ -1,46 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
|
|
||||||
public struct BasicDefaultsNoDiag : IRules {
|
|
||||||
var minNbRows: Int
|
|
||||||
|
|
||||||
var maxNbRows: Int
|
|
||||||
|
|
||||||
var minNbCols: Int
|
|
||||||
|
|
||||||
var maxNbCols: Int
|
|
||||||
|
|
||||||
var nbChipsToAlign: Int
|
|
||||||
|
|
||||||
func isGameOver(byPlayer playerId: Int, ontGrid grid: [[Int?]]) -> (isOver: Bool, hasWinner: Bool, victoryTiles: [(Int?, Int?)]) {
|
|
||||||
|
|
||||||
var tiles : [(Int?, Int?)] = Array(repeating: (nil, nil), count: nbChipsToAlign)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
game over?
|
|
||||||
winner exists?
|
|
||||||
return (true, true, tiles)
|
|
||||||
else
|
|
||||||
return (true, false, tiles) (all tiles at nil)
|
|
||||||
else
|
|
||||||
return (false, false, tiles) (all tiles at nil)
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (isOver: false, hasWinner: false, victoryTiles: tiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
init?(withMinNbRows minNbRows: Int = 0,
|
|
||||||
withMaxNbRows maxNbRows: Int = 15,
|
|
||||||
withMaxNbCols minNbCols: Int = 0,
|
|
||||||
withMaxNbCols maxNbCols: Int = 15,
|
|
||||||
withNbChipsToAlign nbChipsToAlign: Int = 4) {
|
|
||||||
self.minNbRows = minNbRows
|
|
||||||
self.maxNbRows = maxNbRows
|
|
||||||
self.minNbCols = minNbCols
|
|
||||||
self.maxNbCols = maxNbCols
|
|
||||||
self.nbChipsToAlign = nbChipsToAlign
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,108 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
public struct BasicDefaultsNoDiag : IRules {
|
||||||
|
var minNbRows: Int
|
||||||
|
var maxNbRows: Int
|
||||||
|
var minNbCols: Int
|
||||||
|
var maxNbCols: Int
|
||||||
|
var nbChipsToAlign: Int
|
||||||
|
|
||||||
|
func isGameOver(byPlayer playerId: Int, onGrid grid: [[Int?]]) -> (isOver: Bool, hasWinner: Bool, victoryTiles: [(Int, Int)]?) {
|
||||||
|
|
||||||
|
// first check if board is full
|
||||||
|
var isFull = true
|
||||||
|
for row in grid {
|
||||||
|
for tile in row {
|
||||||
|
if tile == nil {
|
||||||
|
isFull = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var victoryTiles : [(Int, Int)] = Array(repeating: (0, 0), count: nbChipsToAlign)
|
||||||
|
|
||||||
|
// assuming that the board is square, we could add a check for that in IRules if we want to leave it open for extension
|
||||||
|
let nbCols = grid[0].count
|
||||||
|
let nbRows = grid.count
|
||||||
|
|
||||||
|
for i in 0..<nbRows {
|
||||||
|
for j in 0..<nbCols {
|
||||||
|
// check if there is room to the right
|
||||||
|
if nbCols - j >= nbChipsToAlign && grid[i][j] != nil && grid[i][j] == playerId {
|
||||||
|
// check for victory
|
||||||
|
if checkAligned(byPlayer: playerId, onGrid: grid, fromRow: i, andCol: j, going: directions.right) == nbChipsToAlign {
|
||||||
|
for x in 0..<nbChipsToAlign {
|
||||||
|
// row i, origin is (i, j), goes to the right
|
||||||
|
victoryTiles[x] = (i, j + x)
|
||||||
|
}
|
||||||
|
return (isOver: true, hasWinner: true, victoryTiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if there is room lower down
|
||||||
|
if nbRows - i >= nbChipsToAlign && grid[i][j] != nil && grid[i][j] == playerId {
|
||||||
|
// check for victory
|
||||||
|
if checkAligned(byPlayer: playerId, onGrid: grid, fromRow: i, andCol: j, going: directions.down) == nbChipsToAlign {
|
||||||
|
for x in 0..<nbChipsToAlign {
|
||||||
|
// column j, origin is (i, j), goes down
|
||||||
|
victoryTiles[x] = (i + x, j)
|
||||||
|
}
|
||||||
|
return (isOver: true, hasWinner: true, victoryTiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
winner exists?
|
||||||
|
return (true, true, tiles)
|
||||||
|
else is full ?
|
||||||
|
return (true, false, nil)
|
||||||
|
else
|
||||||
|
return (false, false, nil)
|
||||||
|
*/
|
||||||
|
return (isFull, hasWinner: false, nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
private func checkAligned(byPlayer playerId: Int,
|
||||||
|
onGrid grid: [[Int?]],
|
||||||
|
fromRow i: Int,
|
||||||
|
andCol j: Int,
|
||||||
|
going direction: directions) -> Int {
|
||||||
|
if let tile = grid[i][j] {
|
||||||
|
if tile == playerId {
|
||||||
|
if direction == directions.right {
|
||||||
|
return 1 + checkAligned(byPlayer: playerId, onGrid: grid, fromRow: i, andCol: j + 1, going: direction)
|
||||||
|
} else if direction == directions.down {
|
||||||
|
return 1 + checkAligned(byPlayer: playerId, onGrid: grid, fromRow: i + 1, andCol: j, going: direction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum directions {
|
||||||
|
case right
|
||||||
|
case down
|
||||||
|
}
|
||||||
|
|
||||||
|
init?(withMinNbRows minNbRows: Int = 0,
|
||||||
|
withMaxNbRows maxNbRows: Int = 15,
|
||||||
|
withMaxNbCols minNbCols: Int = 0,
|
||||||
|
withMaxNbCols maxNbCols: Int = 15,
|
||||||
|
withNbChipsToAlign nbChipsToAlign: Int = 4) {
|
||||||
|
|
||||||
|
guard (nbChipsToAlign >= 2
|
||||||
|
&& (
|
||||||
|
nbChipsToAlign < maxNbCols || nbChipsToAlign < maxNbRows
|
||||||
|
)) else { return nil }
|
||||||
|
|
||||||
|
self.minNbRows = minNbRows
|
||||||
|
self.maxNbRows = maxNbRows
|
||||||
|
self.minNbCols = minNbCols
|
||||||
|
self.maxNbCols = maxNbCols
|
||||||
|
self.nbChipsToAlign = nbChipsToAlign
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import XCTest
|
||||||
|
import connect4_lib
|
||||||
|
|
||||||
|
final class BasicDefaultNoDiagTest: XCTestCase {
|
||||||
|
func testInit() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIsGameOver() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue