Permalink
Browse files

Initial commit - at blog post three

  • Loading branch information...
Richard Turton Richard Turton
Richard Turton authored and Richard Turton committed Jun 9, 2016
0 parents commit b95d9b64753550e9e165abb8e987bc6c3dd1d991
@@ -0,0 +1,65 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xcuserstate
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
@@ -0,0 +1,30 @@
//: Playground - noun: a place where people can play
import UIKit
let board = Board(size: .FiveByTwelve)
let tile = Tile(shape: .O)
for boardSquare in board.squares() {
if board.canPositionTile(tile, atSquare: boardSquare) {
print("Can position at \(boardSquare)")
}
}
tile.rotate(true)
print("Rotated")
for boardSquare in board.squares() {
if board.canPositionTile(tile, atSquare: boardSquare) {
print("Can position at \(boardSquare)")
}
}
@@ -0,0 +1,43 @@
public class Board: PlayingGrid {
private (set) public var rows: [[Bool]]
public struct Size {
let height: Int
let width: Int
public static let SixByTen = Size(height: 6, width: 10)
public static let FiveByTwelve = Size(height: 5, width: 12)
public static let FourByFifteen = Size(height: 4, width: 15)
public static let ThreeByTwenty = Size(height: 3, width: 20)
}
public init(size: Size) {
// Extend by four "occupied" positions in every direction
let paddingHorizontal = [Bool].init(count: 4, repeatedValue: true)
let paddingVertical = [Bool].init(count: 8 + size.width, repeatedValue: true)
let fullPaddingVertical = [[Bool]].init(count: 4, repeatedValue: paddingVertical)
let emptyRow = [Bool].init(count: size.width, repeatedValue: false)
rows = fullPaddingVertical
for _ in 0..<size.height {
rows += [paddingHorizontal + emptyRow + paddingHorizontal]
}
rows += fullPaddingVertical
}
}
extension Board {
public func canPositionTile(tile: Tile, atSquare: Square) -> Bool {
for tileSquare in tile.squares() {
let boardSquare = tileSquare.offsetBy(atSquare)
if !squareWithinBoard(boardSquare) {
return false
}
if tileSquare.occupied == true && squareOccupied(boardSquare) {
return false
}
}
return true
}
}
@@ -0,0 +1,107 @@
public protocol PlayingGrid : CustomStringConvertible, CustomPlaygroundQuickLookable {
var rows: [[Bool]] { get }
subscript(row: Int) -> [Bool] { get }
}
extension Bool {
var gridCharacter: String {
return self ? "#" : "_"
}
}
extension PlayingGrid where Self: protocol<CustomStringConvertible, CustomPlaygroundQuickLookable> {
public var description: String {
let descriptions : [String] = rows.map { row in
row.reduce("") { string, gridValue in
string + gridValue.gridCharacter
}
}
return descriptions.joinWithSeparator("\n")
}
public func customPlaygroundQuickLook() -> PlaygroundQuickLook {
return PlaygroundQuickLook(reflecting: description)
}
}
public struct Square {
let row: Int
let column: Int
let occupied: Bool?
public init(row: Int, column: Int, occupied: Bool? = nil) {
self.row = row
self.column = column
self.occupied = occupied
}
func offsetBy(square: Square) -> Square {
return Square(row: self.row + square.row, column: self.column + square.column)
}
}
public class GridSquareGenerator: GeneratorType {
var currentRow: Int = 0
var currentColumn: Int = -1
let grid: PlayingGrid
public init(grid: PlayingGrid) {
self.grid = grid
}
public func next() -> Square? {
guard currentRow < grid.rows.count else { return nil }
currentColumn += 1
if currentColumn == grid[currentRow].count {
currentColumn = 0
currentRow += 1
}
if currentRow < grid.rows.count {
return Square(row: currentRow, column: currentColumn, occupied: grid[currentRow][currentColumn])
} else {
return nil
}
}
}
public class GridSquareSequence: SequenceType {
let grid: PlayingGrid
public init(grid: PlayingGrid) {
self.grid = grid
}
public func generate() -> GridSquareGenerator {
return GridSquareGenerator(grid: grid)
}
}
extension PlayingGrid {
public func squares() -> GridSquareSequence {
return GridSquareSequence(grid: self)
}
}
extension PlayingGrid {
public subscript(row: Int) -> [Bool] {
get {
return rows[row]
}
}
public func squareWithinBoard(square: Square) -> Bool {
return square.row < rows.count && square.column < rows[square.row].count
}
public func squareOccupied(square: Square) -> Bool {
return self[square.row][square.column]
}
}
Oops, something went wrong.

0 comments on commit b95d9b6

Please sign in to comment.