Permalink
Browse files

Initial commit - at blog post three

  • Loading branch information...
0 parents commit b95d9b64753550e9e165abb8e987bc6c3dd1d991 Richard Turton committed Jun 9, 2016
@@ -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.