From ffd9a831ec2a869ca43da89fb2c76de88aa62dd3 Mon Sep 17 00:00:00 2001 From: cruisediary Date: Tue, 20 Dec 2016 17:30:51 +0900 Subject: [PATCH 1/2] chore(swift3): default migration from Xcode --- swift-2048.xcodeproj/project.pbxproj | 8 +- swift-2048/AppDelegate.swift | 12 +- swift-2048/AppearanceProvider.swift | 14 +- swift-2048/Models/AuxiliaryModels.swift | 38 ++-- swift-2048/Models/GameModel.swift | 138 ++++++------- swift-2048/NumberTileGame.swift | 62 +++--- swift-2048/ViewController.swift | 4 +- swift-2048/Views/AccessoryViews.swift | 6 +- swift-2048/Views/GameboardView.swift | 92 ++++----- swift-2048/Views/TileView.swift | 6 +- swift-2048Tests/ModelTests.swift | 252 ++++++++++++------------ 11 files changed, 319 insertions(+), 313 deletions(-) diff --git a/swift-2048.xcodeproj/project.pbxproj b/swift-2048.xcodeproj/project.pbxproj index 5e13253e..3f5f41c5 100644 --- a/swift-2048.xcodeproj/project.pbxproj +++ b/swift-2048.xcodeproj/project.pbxproj @@ -17,7 +17,7 @@ 1AE8BEF2193EF1C7007592BA /* AppearanceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE8BEF1193EF1C7007592BA /* AppearanceProvider.swift */; }; 1AE8BEF4193EF260007592BA /* NumberTileGame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE8BEF3193EF260007592BA /* NumberTileGame.swift */; }; 1AE8BEF6193EF4B6007592BA /* TileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE8BEF5193EF4B6007592BA /* TileView.swift */; }; - 1AEF46D01BAE736400119D81 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1AEF46CF1BAE736400119D81 /* Launch Screen.storyboard */; settings = {ASSET_TAGS = (); }; }; + 1AEF46D01BAE736400119D81 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1AEF46CF1BAE736400119D81 /* Launch Screen.storyboard */; }; 1AF8F0B619403AA400A7049E /* AccessoryViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF8F0B519403AA400A7049E /* AccessoryViews.swift */; }; 1AF8F0B81941841000A7049E /* AuxiliaryModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF8F0B71941841000A7049E /* AuxiliaryModels.swift */; }; /* End PBXBuildFile section */ @@ -207,9 +207,11 @@ TargetAttributes = { 1AC563DC193DCE6000402286 = { CreatedOnToolsVersion = 6.0; + LastSwiftMigration = 0820; }; 1AC563EE193DCE6000402286 = { CreatedOnToolsVersion = 6.0; + LastSwiftMigration = 0820; TestTargetID = 1AC563DC193DCE6000402286; }; }; @@ -394,6 +396,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "f3nghuang.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -406,6 +409,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "f3nghuang.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -426,6 +430,7 @@ METAL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "f3nghuang.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUNDLE_LOADER)"; }; name = Debug; @@ -443,6 +448,7 @@ METAL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "f3nghuang.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUNDLE_LOADER)"; }; name = Release; diff --git a/swift-2048/AppDelegate.swift b/swift-2048/AppDelegate.swift index 97b9c15c..2475ec9b 100644 --- a/swift-2048/AppDelegate.swift +++ b/swift-2048/AppDelegate.swift @@ -13,29 +13,29 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { return true } - func applicationWillResignActive(application: UIApplication) { + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - func applicationDidEnterBackground(application: UIApplication) { + func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - func applicationWillEnterForeground(application: UIApplication) { + func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - func applicationDidBecomeActive(application: UIApplication) { + func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - func applicationWillTerminate(application: UIApplication) { + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } } diff --git a/swift-2048/AppearanceProvider.swift b/swift-2048/AppearanceProvider.swift index fbaf6d1c..98d81fa1 100644 --- a/swift-2048/AppearanceProvider.swift +++ b/swift-2048/AppearanceProvider.swift @@ -9,15 +9,15 @@ import UIKit protocol AppearanceProviderProtocol: class { - func tileColor(value: Int) -> UIColor - func numberColor(value: Int) -> UIColor + func tileColor(_ value: Int) -> UIColor + func numberColor(_ value: Int) -> UIColor func fontForNumbers() -> UIFont } class AppearanceProvider: AppearanceProviderProtocol { // Provide a tile color for a given value - func tileColor(value: Int) -> UIColor { + func tileColor(_ value: Int) -> UIColor { switch value { case 2: return UIColor(red: 238.0/255.0, green: 228.0/255.0, blue: 218.0/255.0, alpha: 1.0) @@ -34,17 +34,17 @@ class AppearanceProvider: AppearanceProviderProtocol { case 128, 256, 512, 1024, 2048: return UIColor(red: 237.0/255.0, green: 207.0/255.0, blue: 114.0/255.0, alpha: 1.0) default: - return UIColor.whiteColor() + return UIColor.white } } // Provide a numeral color for a given value - func numberColor(value: Int) -> UIColor { + func numberColor(_ value: Int) -> UIColor { switch value { case 2, 4: return UIColor(red: 119.0/255.0, green: 110.0/255.0, blue: 101.0/255.0, alpha: 1.0) default: - return UIColor.whiteColor() + return UIColor.white } } @@ -53,6 +53,6 @@ class AppearanceProvider: AppearanceProviderProtocol { if let font = UIFont(name: "HelveticaNeue-Bold", size: 20) { return font } - return UIFont.systemFontOfSize(20) + return UIFont.systemFont(ofSize: 20) } } diff --git a/swift-2048/Models/AuxiliaryModels.swift b/swift-2048/Models/AuxiliaryModels.swift index d7b04d3d..226fc6df 100644 --- a/swift-2048/Models/AuxiliaryModels.swift +++ b/swift-2048/Models/AuxiliaryModels.swift @@ -10,7 +10,7 @@ import Foundation /// An enum representing directions supported by the game model. enum MoveDirection { - case Up, Down, Left, Right + case up, down, left, right } /// An enum representing a movement command issued by the view controller as the result of the user swiping. @@ -22,40 +22,40 @@ struct MoveCommand { /// An enum representing a 'move order'. This is a data structure the game model uses to inform the view controller /// which tiles on the gameboard should be moved and/or combined. enum MoveOrder { - case SingleMoveOrder(source: Int, destination: Int, value: Int, wasMerge: Bool) - case DoubleMoveOrder(firstSource: Int, secondSource: Int, destination: Int, value: Int) + case singleMoveOrder(source: Int, destination: Int, value: Int, wasMerge: Bool) + case doubleMoveOrder(firstSource: Int, secondSource: Int, destination: Int, value: Int) } /// An enum representing either an empty space or a tile upon the board. enum TileObject { - case Empty - case Tile(Int) + case empty + case tile(Int) } /// An enum representing an intermediate result used by the game logic when figuring out how the board should change as /// the result of a move. ActionTokens are transformed into MoveOrders before being sent to the delegate. enum ActionToken { - case NoAction(source: Int, value: Int) - case Move(source: Int, value: Int) - case SingleCombine(source: Int, value: Int) - case DoubleCombine(source: Int, second: Int, value: Int) + case noAction(source: Int, value: Int) + case move(source: Int, value: Int) + case singleCombine(source: Int, value: Int) + case doubleCombine(source: Int, second: Int, value: Int) // Get the 'value', regardless of the specific type func getValue() -> Int { switch self { - case let .NoAction(_, v): return v - case let .Move(_, v): return v - case let .SingleCombine(_, v): return v - case let .DoubleCombine(_, _, v): return v + case let .noAction(_, v): return v + case let .move(_, v): return v + case let .singleCombine(_, v): return v + case let .doubleCombine(_, _, v): return v } } // Get the 'source', regardless of the specific type func getSource() -> Int { switch self { - case let .NoAction(s, _): return s - case let .Move(s, _): return s - case let .SingleCombine(s, _): return s - case let .DoubleCombine(s, _, _): return s + case let .noAction(s, _): return s + case let .move(s, _): return s + case let .singleCombine(s, _): return s + case let .doubleCombine(s, _, _): return s } } } @@ -68,7 +68,7 @@ struct SquareGameboard { init(dimension d: Int, initialValue: T) { dimension = d - boardArray = [T](count:d*d, repeatedValue:initialValue) + boardArray = [T](repeating: initialValue, count: d*d) } subscript(row: Int, col: Int) -> T { @@ -85,7 +85,7 @@ struct SquareGameboard { } // We mark this function as 'mutating' since it changes its 'parent' struct. - mutating func setAll(item: T) { + mutating func setAll(_ item: T) { for i in 0.. ()) { + func queueMove(_ direction: MoveDirection, completion: @escaping (Bool) -> ()) { guard queue.count <= maxCommands else { // Queue is wedged. This should actually never happen in practice. return } queue.append(MoveCommand(direction: direction, completion: completion)) - if !timer.valid { + if !timer.isValid { // Timer isn't running, so fire the event immediately timerFired(timer) } @@ -72,7 +72,7 @@ class GameModel : NSObject { /// Inform the game model that the move delay timer fired. Once the timer fires, the game model tries to execute a /// single move that changes the game state. - func timerFired(_: NSTimer) { + func timerFired(_: Timer) { if queue.count == 0 { return } @@ -80,7 +80,7 @@ class GameModel : NSObject { var changed = false while queue.count > 0 { let command = queue[0] - queue.removeAtIndex(0) + queue.remove(at: 0) changed = performMove(command.direction) command.completion(changed) if changed { @@ -89,10 +89,10 @@ class GameModel : NSObject { } } if changed { - timer = NSTimer.scheduledTimerWithTimeInterval(queueDelay, + timer = Timer.scheduledTimer(timeInterval: queueDelay, target: self, selector: - Selector("timerFired:"), + #selector(GameModel.timerFired(_:)), userInfo: nil, repeats: false) } @@ -101,16 +101,16 @@ class GameModel : NSObject { //------------------------------------------------------------------------------------------------------------------// /// Insert a tile with a given value at a position upon the gameboard. - func insertTile(position: (Int, Int), value: Int) { + func insertTile(_ position: (Int, Int), value: Int) { let (x, y) = position - if case .Empty = gameboard[x, y] { - gameboard[x, y] = TileObject.Tile(value) + if case .empty = gameboard[x, y] { + gameboard[x, y] = TileObject.tile(value) delegate.insertTile(position, value: value) } } /// Insert a tile with a given value at a random open position upon the gameboard. - func insertTileAtRandomLocation(value: Int) { + func insertTileAtRandomLocation(_ value: Int) { let openSpots = gameboardEmptySpots() if openSpots.isEmpty { // No more open spots; don't even bother @@ -127,7 +127,7 @@ class GameModel : NSObject { var buffer : [(Int, Int)] = [] for i in 0.. Bool { + func tileBelowHasSameValue(_ location: (Int, Int), _ value: Int) -> Bool { let (x, y) = location guard y != dimension - 1 else { return false } - if case let .Tile(v) = gameboard[x, y+1] { + if case let .tile(v) = gameboard[x, y+1] { return v == value } return false } - func tileToRightHasSameValue(location: (Int, Int), _ value: Int) -> Bool { + func tileToRightHasSameValue(_ location: (Int, Int), _ value: Int) -> Bool { let (x, y) = location guard x != dimension - 1 else { return false } - if case let .Tile(v) = gameboard[x+1, y] { + if case let .tile(v) = gameboard[x+1, y] { return v == value } return false @@ -169,9 +169,9 @@ class GameModel : NSObject { for i in 0..= threshold { + if case let .tile(v) = gameboard[i, j], v >= threshold { return (true, (i, j)) } } @@ -196,18 +196,18 @@ class GameModel : NSObject { //------------------------------------------------------------------------------------------------------------------// // Perform all calculations and update state for a single move. - func performMove(direction: MoveDirection) -> Bool { + func performMove(_ direction: MoveDirection) -> Bool { // Prepare the generator closure. This closure differs in behavior depending on the direction of the move. It is // used by the method to generate a list of tiles which should be modified. Depending on the direction this list // may represent a single row or a single column, in either direction. let coordinateGenerator: (Int) -> [(Int, Int)] = { (iteration: Int) -> [(Int, Int)] in - var buffer = Array<(Int, Int)>(count:self.dimension, repeatedValue: (0, 0)) + var buffer = Array<(Int, Int)>(repeating: (0, 0), count: self.dimension) for i in 0.. [ActionToken] { + func condense(_ group: [TileObject]) -> [ActionToken] { var tokenBuffer = [ActionToken]() - for (idx, tile) in group.enumerate() { + for (idx, tile) in group.enumerated() { // Go through all the tiles in 'group'. When we see a tile 'out of place', create a corresponding ActionToken. switch tile { - case let .Tile(value) where tokenBuffer.count == idx: - tokenBuffer.append(ActionToken.NoAction(source: idx, value: value)) - case let .Tile(value): - tokenBuffer.append(ActionToken.Move(source: idx, value: value)) + case let .tile(value) where tokenBuffer.count == idx: + tokenBuffer.append(ActionToken.noAction(source: idx, value: value)) + case let .tile(value): + tokenBuffer.append(ActionToken.move(source: idx, value: value)) default: break } @@ -278,7 +278,7 @@ class GameModel : NSObject { return tokenBuffer; } - class func quiescentTileStillQuiescent(inputPosition: Int, outputLength: Int, originalPosition: Int) -> Bool { + class func quiescentTileStillQuiescent(_ inputPosition: Int, outputLength: Int, originalPosition: Int) -> Bool { // Return whether or not a 'NoAction' token still represents an unmoved tile return (inputPosition == outputLength) && (originalPosition == inputPosition) } @@ -286,23 +286,23 @@ class GameModel : NSObject { /// When computing the effects of a move upon a row of tiles, calculate and return an updated list of ActionTokens /// corresponding to any merges that should take place. This method collapses adjacent tiles of equal value, but each /// tile can take part in at most one collapse per move. For example, |[1][1][1][2][2]| will become |[2][1][4]|. - func collapse(group: [ActionToken]) -> [ActionToken] { + func collapse(_ group: [ActionToken]) -> [ActionToken] { var tokenBuffer = [ActionToken]() var skipNext = false - for (idx, token) in group.enumerate() { + for (idx, token) in group.enumerated() { if skipNext { // Prior iteration handled a merge. So skip this iteration. skipNext = false continue } switch token { - case .SingleCombine: + case .singleCombine: assert(false, "Cannot have single combine token in input") - case .DoubleCombine: + case .doubleCombine: assert(false, "Cannot have double combine token in input") - case let .NoAction(s, v) + case let .noAction(s, v) where (idx < group.count-1 && v == group[idx+1].getValue() && GameModel.quiescentTileStillQuiescent(idx, outputLength: tokenBuffer.count, originalPosition: s)): @@ -311,7 +311,7 @@ class GameModel : NSObject { let next = group[idx+1] let nv = v + group[idx+1].getValue() skipNext = true - tokenBuffer.append(ActionToken.SingleCombine(source: next.getSource(), value: nv)) + tokenBuffer.append(ActionToken.singleCombine(source: next.getSource(), value: nv)) case let t where (idx < group.count-1 && t.getValue() == group[idx+1].getValue()): // This tile has moved, and matches the next tile. This is a double merge // (The tile may either have moved prevously, or the tile might have moved as a result of a previous merge) @@ -319,16 +319,16 @@ class GameModel : NSObject { let next = group[idx+1] let nv = t.getValue() + group[idx+1].getValue() skipNext = true - tokenBuffer.append(ActionToken.DoubleCombine(source: t.getSource(), second: next.getSource(), value: nv)) - case let .NoAction(s, v) where !GameModel.quiescentTileStillQuiescent(idx, outputLength: tokenBuffer.count, originalPosition: s): + tokenBuffer.append(ActionToken.doubleCombine(source: t.getSource(), second: next.getSource(), value: nv)) + case let .noAction(s, v) where !GameModel.quiescentTileStillQuiescent(idx, outputLength: tokenBuffer.count, originalPosition: s): // A tile that didn't move before has moved (first cond.), or there was a previous merge (second cond.) - tokenBuffer.append(ActionToken.Move(source: s, value: v)) - case let .NoAction(s, v): + tokenBuffer.append(ActionToken.move(source: s, value: v)) + case let .noAction(s, v): // A tile that didn't move before still hasn't moved - tokenBuffer.append(ActionToken.NoAction(source: s, value: v)) - case let .Move(s, v): + tokenBuffer.append(ActionToken.noAction(source: s, value: v)) + case let .move(s, v): // Propagate a move - tokenBuffer.append(ActionToken.Move(source: s, value: v)) + tokenBuffer.append(ActionToken.move(source: s, value: v)) default: // Don't do anything break @@ -339,16 +339,16 @@ class GameModel : NSObject { /// When computing the effects of a move upon a row of tiles, take a list of ActionTokens prepared by the condense() /// and convert() methods and convert them into MoveOrders that can be fed back to the delegate. - func convert(group: [ActionToken]) -> [MoveOrder] { + func convert(_ group: [ActionToken]) -> [MoveOrder] { var moveBuffer = [MoveOrder]() - for (idx, t) in group.enumerate() { + for (idx, t) in group.enumerated() { switch t { - case let .Move(s, v): - moveBuffer.append(MoveOrder.SingleMoveOrder(source: s, destination: idx, value: v, wasMerge: false)) - case let .SingleCombine(s, v): - moveBuffer.append(MoveOrder.SingleMoveOrder(source: s, destination: idx, value: v, wasMerge: true)) - case let .DoubleCombine(s1, s2, v): - moveBuffer.append(MoveOrder.DoubleMoveOrder(firstSource: s1, secondSource: s2, destination: idx, value: v)) + case let .move(s, v): + moveBuffer.append(MoveOrder.singleMoveOrder(source: s, destination: idx, value: v, wasMerge: false)) + case let .singleCombine(s, v): + moveBuffer.append(MoveOrder.singleMoveOrder(source: s, destination: idx, value: v, wasMerge: true)) + case let .doubleCombine(s1, s2, v): + moveBuffer.append(MoveOrder.doubleMoveOrder(firstSource: s1, secondSource: s2, destination: idx, value: v)) default: // Don't do anything break @@ -358,7 +358,7 @@ class GameModel : NSObject { } /// Given an array of TileObjects, perform a collapse and create an array of move orders. - func merge(group: [TileObject]) -> [MoveOrder] { + func merge(_ group: [TileObject]) -> [MoveOrder] { // Calculation takes place in three steps: // 1. Calculate the moves necessary to produce the same tiles, but without any interstital space. // 2. Take the above, and calculate the moves necessary to collapse adjacent tiles of equal value. diff --git a/swift-2048/NumberTileGame.swift b/swift-2048/NumberTileGame.swift index 09a9e272..1427cade 100644 --- a/swift-2048/NumberTileGame.swift +++ b/swift-2048/NumberTileGame.swift @@ -40,7 +40,7 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { threshold = t > 8 ? t : 8 super.init(nibName: nil, bundle: nil) model = GameModel(dimension: dimension, threshold: threshold, delegate: self) - view.backgroundColor = UIColor.whiteColor() + view.backgroundColor = UIColor.white setupSwipeControls() } @@ -49,24 +49,24 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { } func setupSwipeControls() { - let upSwipe = UISwipeGestureRecognizer(target: self, action: Selector("up:")) + let upSwipe = UISwipeGestureRecognizer(target: self, action: #selector(NumberTileGameViewController.upCommand(_:))) upSwipe.numberOfTouchesRequired = 1 - upSwipe.direction = UISwipeGestureRecognizerDirection.Up + upSwipe.direction = UISwipeGestureRecognizerDirection.up view.addGestureRecognizer(upSwipe) - let downSwipe = UISwipeGestureRecognizer(target: self, action: Selector("down:")) + let downSwipe = UISwipeGestureRecognizer(target: self, action: #selector(NumberTileGameViewController.downCommand(_:))) downSwipe.numberOfTouchesRequired = 1 - downSwipe.direction = UISwipeGestureRecognizerDirection.Down + downSwipe.direction = UISwipeGestureRecognizerDirection.down view.addGestureRecognizer(downSwipe) - let leftSwipe = UISwipeGestureRecognizer(target: self, action: Selector("left:")) + let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(NumberTileGameViewController.leftCommand(_:))) leftSwipe.numberOfTouchesRequired = 1 - leftSwipe.direction = UISwipeGestureRecognizerDirection.Left + leftSwipe.direction = UISwipeGestureRecognizerDirection.left view.addGestureRecognizer(leftSwipe) - let rightSwipe = UISwipeGestureRecognizer(target: self, action: Selector("right:")) + let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(NumberTileGameViewController.rightCommand(_:))) rightSwipe.numberOfTouchesRequired = 1 - rightSwipe.direction = UISwipeGestureRecognizerDirection.Right + rightSwipe.direction = UISwipeGestureRecognizerDirection.right view.addGestureRecognizer(rightSwipe) } @@ -92,17 +92,17 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { let vcWidth = view.bounds.size.width // This nested function provides the x-position for a component view - func xPositionToCenterView(v: UIView) -> CGFloat { + func xPositionToCenterView(_ v: UIView) -> CGFloat { let viewWidth = v.bounds.size.width let tentativeX = 0.5*(vcWidth - viewWidth) return tentativeX >= 0 ? tentativeX : 0 } // This nested function provides the y-position for a component view - func yPositionForViewAtPosition(order: Int, views: [UIView]) -> CGFloat { + func yPositionForViewAtPosition(_ order: Int, views: [UIView]) -> CGFloat { assert(views.count > 0) assert(order >= 0 && order < views.count) // let viewHeight = views[order].bounds.size.height - let totalHeight = CGFloat(views.count - 1)*viewPadding + views.map({ $0.bounds.size.height }).reduce(verticalViewOffset, combine: { $0 + $1 }) + let totalHeight = CGFloat(views.count - 1)*viewPadding + views.map({ $0.bounds.size.height }).reduce(verticalViewOffset, { $0 + $1 }) let viewsTop = 0.5*(vcHeight - totalHeight) >= 0 ? 0.5*(vcHeight - totalHeight) : 0 // Not sure how to slice an array yet @@ -114,9 +114,9 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { } // Create the score view - let scoreView = ScoreView(backgroundColor: UIColor.blackColor(), - textColor: UIColor.whiteColor(), - font: UIFont(name: "HelveticaNeue-Bold", size: 16.0) ?? UIFont.systemFontOfSize(16.0), + let scoreView = ScoreView(backgroundColor: UIColor.black, + textColor: UIColor.white, + font: UIFont(name: "HelveticaNeue-Bold", size: 16.0) ?? UIFont.systemFont(ofSize: 16.0), radius: 6) scoreView.score = 0 @@ -128,8 +128,8 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { tileWidth: width, tilePadding: padding, cornerRadius: 6, - backgroundColor: UIColor.blackColor(), - foregroundColor: UIColor.darkGrayColor()) + backgroundColor: UIColor.black, + foregroundColor: UIColor.darkGray) // Set up the frames let views = [scoreView, gameboard] @@ -167,7 +167,7 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { let alertView = UIAlertView() alertView.title = "Victory" alertView.message = "You won!" - alertView.addButtonWithTitle("Cancel") + alertView.addButton(withTitle: "Cancel") alertView.show() // TODO: At this point we should stall the game until the user taps 'New Game' (which hasn't been implemented yet) return @@ -184,17 +184,17 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { let alertView = UIAlertView() alertView.title = "Defeat" alertView.message = "You lost..." - alertView.addButtonWithTitle("Cancel") + alertView.addButton(withTitle: "Cancel") alertView.show() } } // Commands @objc(up:) - func upCommand(r: UIGestureRecognizer!) { + func upCommand(_ r: UIGestureRecognizer!) { assert(model != nil) let m = model! - m.queueMove(MoveDirection.Up, + m.queueMove(MoveDirection.up, completion: { (changed: Bool) -> () in if changed { self.followUp() @@ -203,10 +203,10 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { } @objc(down:) - func downCommand(r: UIGestureRecognizer!) { + func downCommand(_ r: UIGestureRecognizer!) { assert(model != nil) let m = model! - m.queueMove(MoveDirection.Down, + m.queueMove(MoveDirection.down, completion: { (changed: Bool) -> () in if changed { self.followUp() @@ -215,10 +215,10 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { } @objc(left:) - func leftCommand(r: UIGestureRecognizer!) { + func leftCommand(_ r: UIGestureRecognizer!) { assert(model != nil) let m = model! - m.queueMove(MoveDirection.Left, + m.queueMove(MoveDirection.left, completion: { (changed: Bool) -> () in if changed { self.followUp() @@ -227,10 +227,10 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { } @objc(right:) - func rightCommand(r: UIGestureRecognizer!) { + func rightCommand(_ r: UIGestureRecognizer!) { assert(model != nil) let m = model! - m.queueMove(MoveDirection.Right, + m.queueMove(MoveDirection.right, completion: { (changed: Bool) -> () in if changed { self.followUp() @@ -239,7 +239,7 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { } // Protocol - func scoreChanged(score: Int) { + func scoreChanged(_ score: Int) { if scoreView == nil { return } @@ -247,19 +247,19 @@ class NumberTileGameViewController : UIViewController, GameModelProtocol { s.scoreChanged(newScore: score) } - func moveOneTile(from: (Int, Int), to: (Int, Int), value: Int) { + func moveOneTile(_ from: (Int, Int), to: (Int, Int), value: Int) { assert(board != nil) let b = board! b.moveOneTile(from, to: to, value: value) } - func moveTwoTiles(from: ((Int, Int), (Int, Int)), to: (Int, Int), value: Int) { + func moveTwoTiles(_ from: ((Int, Int), (Int, Int)), to: (Int, Int), value: Int) { assert(board != nil) let b = board! b.moveTwoTiles(from, to: to, value: value) } - func insertTile(location: (Int, Int), value: Int) { + func insertTile(_ location: (Int, Int), value: Int) { assert(board != nil) let b = board! b.insertTile(location, value: value) diff --git a/swift-2048/ViewController.swift b/swift-2048/ViewController.swift index 3c334626..7a835655 100644 --- a/swift-2048/ViewController.swift +++ b/swift-2048/ViewController.swift @@ -14,9 +14,9 @@ class ViewController: UIViewController { super.viewDidLoad() } - @IBAction func startGameButtonTapped(sender : UIButton) { + @IBAction func startGameButtonTapped(_ sender : UIButton) { let game = NumberTileGameViewController(dimension: 4, threshold: 2048) - self.presentViewController(game, animated: true, completion: nil) + self.present(game, animated: true, completion: nil) } } diff --git a/swift-2048/Views/AccessoryViews.swift b/swift-2048/Views/AccessoryViews.swift index e5ee71bc..1af45fea 100644 --- a/swift-2048/Views/AccessoryViews.swift +++ b/swift-2048/Views/AccessoryViews.swift @@ -20,12 +20,12 @@ class ScoreView : UIView, ScoreViewProtocol { } } - let defaultFrame = CGRectMake(0, 0, 140, 40) + let defaultFrame = CGRect(x: 0, y: 0, width: 140, height: 40) var label: UILabel init(backgroundColor bgcolor: UIColor, textColor tcolor: UIColor, font: UIFont, radius r: CGFloat) { label = UILabel(frame: defaultFrame) - label.textAlignment = NSTextAlignment.Center + label.textAlignment = NSTextAlignment.center super.init(frame: defaultFrame) backgroundColor = bgcolor label.textColor = tcolor @@ -45,6 +45,6 @@ class ScoreView : UIView, ScoreViewProtocol { // A simple view that displays several buttons for controlling the app class ControlView { - let defaultFrame = CGRectMake(0, 0, 140, 40) + let defaultFrame = CGRect(x: 0, y: 0, width: 140, height: 40) // TODO: Implement me } diff --git a/swift-2048/Views/GameboardView.swift b/swift-2048/Views/GameboardView.swift index 4dd92985..d82a1433 100644 --- a/swift-2048/Views/GameboardView.swift +++ b/swift-2048/Views/GameboardView.swift @@ -13,21 +13,21 @@ class GameboardView : UIView { var tileWidth: CGFloat var tilePadding: CGFloat var cornerRadius: CGFloat - var tiles: Dictionary + var tiles: Dictionary let provider = AppearanceProvider() let tilePopStartScale: CGFloat = 0.1 let tilePopMaxScale: CGFloat = 1.1 - let tilePopDelay: NSTimeInterval = 0.05 - let tileExpandTime: NSTimeInterval = 0.18 - let tileContractTime: NSTimeInterval = 0.08 + let tilePopDelay: TimeInterval = 0.05 + let tileExpandTime: TimeInterval = 0.18 + let tileContractTime: TimeInterval = 0.08 let tileMergeStartScale: CGFloat = 1.0 - let tileMergeExpandTime: NSTimeInterval = 0.08 - let tileMergeContractTime: NSTimeInterval = 0.08 + let tileMergeExpandTime: TimeInterval = 0.08 + let tileMergeContractTime: TimeInterval = 0.08 - let perSquareSlideDuration: NSTimeInterval = 0.08 + let perSquareSlideDuration: TimeInterval = 0.08 init(dimension d: Int, tileWidth width: CGFloat, tilePadding padding: CGFloat, cornerRadius radius: CGFloat, backgroundColor: UIColor, foregroundColor: UIColor) { assert(d > 0) @@ -37,7 +37,7 @@ class GameboardView : UIView { cornerRadius = radius tiles = Dictionary() let sideLength = padding + CGFloat(dimension)*(width + padding) - super.init(frame: CGRectMake(0, 0, sideLength, sideLength)) + super.init(frame: CGRect(x: 0, y: 0, width: sideLength, height: sideLength)) layer.cornerRadius = radius setupBackground(backgroundColor: backgroundColor, tileColor: foregroundColor) } @@ -50,11 +50,11 @@ class GameboardView : UIView { for (_, tile) in tiles { tile.removeFromSuperview() } - tiles.removeAll(keepCapacity: true) + tiles.removeAll(keepingCapacity: true) } /// Return whether a given position is valid. Used for bounds checking. - func positionIsValid(pos: (Int, Int)) -> Bool { + func positionIsValid(_ pos: (Int, Int)) -> Bool { let (x, y) = pos return (x >= 0 && x < dimension && y >= 0 && y < dimension) } @@ -68,7 +68,7 @@ class GameboardView : UIView { yCursor = tilePadding for _ in 0..= 2) ? cornerRadius - 2 : 0 - let tile = TileView(position: CGPointMake(x, y), width: tileWidth, value: value, radius: r, delegate: provider) - tile.layer.setAffineTransform(CGAffineTransformMakeScale(tilePopStartScale, tilePopStartScale)) + let tile = TileView(position: CGPoint(x: x, y: y), width: tileWidth, value: value, radius: r, delegate: provider) + tile.layer.setAffineTransform(CGAffineTransform(scaleX: tilePopStartScale, y: tilePopStartScale)) addSubview(tile) - bringSubviewToFront(tile) - tiles[NSIndexPath(forRow: row, inSection: col)] = tile + bringSubview(toFront: tile) + tiles[IndexPath(row: row, section: col)] = tile // Add to board - UIView.animateWithDuration(tileExpandTime, delay: tilePopDelay, options: UIViewAnimationOptions.TransitionNone, + UIView.animate(withDuration: tileExpandTime, delay: tilePopDelay, options: UIViewAnimationOptions(), animations: { // Make the tile 'pop' - tile.layer.setAffineTransform(CGAffineTransformMakeScale(self.tilePopMaxScale, self.tilePopMaxScale)) + tile.layer.setAffineTransform(CGAffineTransform(scaleX: self.tilePopMaxScale, y: self.tilePopMaxScale)) }, completion: { finished in // Shrink the tile after it 'pops' - UIView.animateWithDuration(self.tileContractTime, animations: { () -> Void in - tile.layer.setAffineTransform(CGAffineTransformIdentity) + UIView.animate(withDuration: self.tileContractTime, animations: { () -> Void in + tile.layer.setAffineTransform(CGAffineTransform.identity) }) }) } /// Update the gameboard by moving a single tile from one location to another. If the move is going to collapse two /// tiles into a new tile, the tile will 'pop' after moving to its new location. - func moveOneTile(from: (Int, Int), to: (Int, Int), value: Int) { + func moveOneTile(_ from: (Int, Int), to: (Int, Int), value: Int) { assert(positionIsValid(from) && positionIsValid(to)) let (fromRow, fromCol) = from let (toRow, toCol) = to - let fromKey = NSIndexPath(forRow: fromRow, inSection: fromCol) - let toKey = NSIndexPath(forRow: toRow, inSection: toCol) + let fromKey = IndexPath(row: fromRow, section: fromCol) + let toKey = IndexPath(row: toRow, section: toCol) // Get the tiles guard let tile = tiles[fromKey] else { @@ -127,14 +127,14 @@ class GameboardView : UIView { finalFrame.origin.y = tilePadding + CGFloat(toRow)*(tileWidth + tilePadding) // Update board state - tiles.removeValueForKey(fromKey) + tiles.removeValue(forKey: fromKey) tiles[toKey] = tile // Animate let shouldPop = endTile != nil - UIView.animateWithDuration(perSquareSlideDuration, + UIView.animate(withDuration: perSquareSlideDuration, delay: 0.0, - options: UIViewAnimationOptions.BeginFromCurrentState, + options: UIViewAnimationOptions.beginFromCurrentState, animations: { // Slide tile tile.frame = finalFrame @@ -145,31 +145,31 @@ class GameboardView : UIView { if !shouldPop || !finished { return } - tile.layer.setAffineTransform(CGAffineTransformMakeScale(self.tileMergeStartScale, self.tileMergeStartScale)) + tile.layer.setAffineTransform(CGAffineTransform(scaleX: self.tileMergeStartScale, y: self.tileMergeStartScale)) // Pop tile - UIView.animateWithDuration(self.tileMergeExpandTime, + UIView.animate(withDuration: self.tileMergeExpandTime, animations: { - tile.layer.setAffineTransform(CGAffineTransformMakeScale(self.tilePopMaxScale, self.tilePopMaxScale)) + tile.layer.setAffineTransform(CGAffineTransform(scaleX: self.tilePopMaxScale, y: self.tilePopMaxScale)) }, completion: { finished in // Contract tile to original size - UIView.animateWithDuration(self.tileMergeContractTime) { - tile.layer.setAffineTransform(CGAffineTransformIdentity) - } + UIView.animate(withDuration: self.tileMergeContractTime, animations: { + tile.layer.setAffineTransform(CGAffineTransform.identity) + }) }) }) } /// Update the gameboard by moving two tiles from their original locations to a common destination. This action always /// represents tile collapse, and the combined tile 'pops' after both tiles move into position. - func moveTwoTiles(from: ((Int, Int), (Int, Int)), to: (Int, Int), value: Int) { + func moveTwoTiles(_ from: ((Int, Int), (Int, Int)), to: (Int, Int), value: Int) { assert(positionIsValid(from.0) && positionIsValid(from.1) && positionIsValid(to)) let (fromRowA, fromColA) = from.0 let (fromRowB, fromColB) = from.1 let (toRow, toCol) = to - let fromKeyA = NSIndexPath(forRow: fromRowA, inSection: fromColA) - let fromKeyB = NSIndexPath(forRow: fromRowB, inSection: fromColB) - let toKey = NSIndexPath(forRow: toRow, inSection: toCol) + let fromKeyA = IndexPath(row: fromRowA, section: fromColA) + let fromKeyB = IndexPath(row: fromRowB, section: fromColB) + let toKey = IndexPath(row: toRow, section: toCol) guard let tileA = tiles[fromKeyA] else { assert(false, "placeholder error") @@ -186,13 +186,13 @@ class GameboardView : UIView { // Update the state let oldTile = tiles[toKey] // TODO: make sure this doesn't cause issues oldTile?.removeFromSuperview() - tiles.removeValueForKey(fromKeyA) - tiles.removeValueForKey(fromKeyB) + tiles.removeValue(forKey: fromKeyA) + tiles.removeValue(forKey: fromKeyB) tiles[toKey] = tileA - UIView.animateWithDuration(perSquareSlideDuration, + UIView.animate(withDuration: perSquareSlideDuration, delay: 0.0, - options: UIViewAnimationOptions.BeginFromCurrentState, + options: UIViewAnimationOptions.beginFromCurrentState, animations: { // Slide tiles tileA.frame = finalFrame @@ -204,17 +204,17 @@ class GameboardView : UIView { if !finished { return } - tileA.layer.setAffineTransform(CGAffineTransformMakeScale(self.tileMergeStartScale, self.tileMergeStartScale)) + tileA.layer.setAffineTransform(CGAffineTransform(scaleX: self.tileMergeStartScale, y: self.tileMergeStartScale)) // Pop tile - UIView.animateWithDuration(self.tileMergeExpandTime, + UIView.animate(withDuration: self.tileMergeExpandTime, animations: { - tileA.layer.setAffineTransform(CGAffineTransformMakeScale(self.tilePopMaxScale, self.tilePopMaxScale)) + tileA.layer.setAffineTransform(CGAffineTransform(scaleX: self.tilePopMaxScale, y: self.tilePopMaxScale)) }, completion: { finished in // Contract tile to original size - UIView.animateWithDuration(self.tileMergeContractTime) { - tileA.layer.setAffineTransform(CGAffineTransformIdentity) - } + UIView.animate(withDuration: self.tileMergeContractTime, animations: { + tileA.layer.setAffineTransform(CGAffineTransform.identity) + }) }) }) } diff --git a/swift-2048/Views/TileView.swift b/swift-2048/Views/TileView.swift index 535acd43..44e37241 100644 --- a/swift-2048/Views/TileView.swift +++ b/swift-2048/Views/TileView.swift @@ -27,12 +27,12 @@ class TileView : UIView { init(position: CGPoint, width: CGFloat, value: Int, radius: CGFloat, delegate d: AppearanceProviderProtocol) { delegate = d - numberLabel = UILabel(frame: CGRectMake(0, 0, width, width)) - numberLabel.textAlignment = NSTextAlignment.Center + numberLabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: width)) + numberLabel.textAlignment = NSTextAlignment.center numberLabel.minimumScaleFactor = 0.5 numberLabel.font = delegate.fontForNumbers() - super.init(frame: CGRectMake(position.x, position.y, width, width)) + super.init(frame: CGRect(x: position.x, y: position.y, width: width, height: width)) addSubview(numberLabel) layer.cornerRadius = radius diff --git a/swift-2048Tests/ModelTests.swift b/swift-2048Tests/ModelTests.swift index 0bf253d3..22314cf4 100644 --- a/swift-2048Tests/ModelTests.swift +++ b/swift-2048Tests/ModelTests.swift @@ -22,35 +22,35 @@ class ModelTests: XCTestCase, GameModelProtocol { } // Would be better to just make the merge and associated methods static. - func scoreChanged(score: Int) { } - func moveOneTile(from: (Int, Int), to: (Int, Int), value: Int) { } - func moveTwoTiles(from: ((Int, Int), (Int, Int)), to: (Int, Int), value: Int) { } - func insertTile(location: (Int, Int), value: Int) { } + func scoreChanged(_ score: Int) { } + func moveOneTile(_ from: (Int, Int), to: (Int, Int), value: Int) { } + func moveTwoTiles(_ from: ((Int, Int), (Int, Int)), to: (Int, Int), value: Int) { } + func insertTile(_ location: (Int, Int), value: Int) { } // --------- TEST CONDENSE --------- // func testCondense1() { let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - var group = [TileObject.Tile(1), - TileObject.Tile(2), - TileObject.Tile(4), - TileObject.Tile(8), - TileObject.Tile(1)] + var group = [TileObject.tile(1), + TileObject.tile(2), + TileObject.tile(4), + TileObject.tile(8), + TileObject.tile(1)] XCTAssert(group.count == 5, "Group should have 5 members before anything happens") let output = m.condense(group) // Check the output XCTAssert(output.count == 5, "Output should have 5 merge tiles") - for (idx, object) in output.enumerate() { + for (idx, object) in output.enumerated() { let c = group[idx] switch c { - case .Empty: + case .empty: // This shouldn't happen; all of the tiles in 'group' should be real tiles XCTFail("Input was bad!") - case let .Tile(desiredV): + case let .tile(desiredV): // Now we can check the values switch object { - case let .NoAction(s, v) where (s == idx && v == desiredV): + case let .noAction(s, v) where (s == idx && v == desiredV): continue default: XCTFail("Output \(idx) had the wrong type, value, or source") @@ -61,24 +61,24 @@ class ModelTests: XCTestCase, GameModelProtocol { func testCondense1b() { let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(1), - TileObject.Empty, - TileObject.Tile(4), - TileObject.Empty, - TileObject.Tile(1)] + let group = [TileObject.tile(1), + TileObject.empty, + TileObject.tile(4), + TileObject.empty, + TileObject.tile(1)] XCTAssert(group.count == 5, "Group should have 5 members before anything happens") let output = m.condense(group) // Check the output XCTAssert(output.count == 3, "Output should have 3 merge tiles") - for (idx, _) in output.enumerate() { + for (idx, _) in output.enumerated() { let c = output[idx] switch c { - case .SingleCombine: + case .singleCombine: XCTFail("Output \(idx) was a single combine merge tile, but condense should never produce those!") - case .DoubleCombine: + case .doubleCombine: XCTFail("Output \(idx) was a double combine merge tile, but condense should never produce those!") - case let .NoAction(s, v): + case let .noAction(s, v): if (idx == 0) { if (s != 0 || v != 1 ) { XCTFail("Output \(idx) was a no action merge tile, but the source or value were wrong!") @@ -87,7 +87,7 @@ class ModelTests: XCTestCase, GameModelProtocol { else { XCTFail("Output \(idx) was a no action merge tile, but shouldn't have been!") } - case let .Move(s, v): + case let .move(s, v): if (idx == 1) { if (s != 2 || v != 4) { XCTFail("Output \(idx) was a move merge tile, but the source or value was wrong.") @@ -107,25 +107,25 @@ class ModelTests: XCTestCase, GameModelProtocol { func testCondense1c() { let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(1), - TileObject.Tile(4), - TileObject.Empty, - TileObject.Empty, - TileObject.Tile(1), - TileObject.Empty] + let group = [TileObject.tile(1), + TileObject.tile(4), + TileObject.empty, + TileObject.empty, + TileObject.tile(1), + TileObject.empty] XCTAssert(group.count == 6, "Group should have 6 members before anything happens") let output = m.condense(group) // Check the output XCTAssert(output.count == 3, "Output should have 3 merge tiles") - for (idx, _) in output.enumerate() { + for (idx, _) in output.enumerated() { let c = output[idx] switch c { - case .SingleCombine: + case .singleCombine: XCTFail("Output \(idx) was a single combine merge tile, but condense should never produce those!") - case .DoubleCombine: + case .doubleCombine: XCTFail("Output \(idx) was a double combine merge tile, but condense should never produce those!") - case let .NoAction(s, v): + case let .noAction(s, v): if (idx == 0) { if (s != 0 || v != 1 ) { XCTFail("Output \(idx) was a no action merge tile, but the source or value were wrong!") @@ -139,7 +139,7 @@ class ModelTests: XCTestCase, GameModelProtocol { else { XCTFail("Output \(idx) was a no action merge tile, but shouldn't have been!") } - case let .Move(s, v): + case let .move(s, v): if (idx == 2) { if (s != 4 || v != 1) { XCTFail("Output \(idx) was a move merge tile, but the source or value was wrong.") @@ -154,29 +154,29 @@ class ModelTests: XCTestCase, GameModelProtocol { func testCondense1d() { let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Empty, - TileObject.Empty, - TileObject.Tile(1), - TileObject.Tile(4), - TileObject.Empty, - TileObject.Empty, - TileObject.Tile(1), - TileObject.Empty] + let group = [TileObject.empty, + TileObject.empty, + TileObject.tile(1), + TileObject.tile(4), + TileObject.empty, + TileObject.empty, + TileObject.tile(1), + TileObject.empty] XCTAssert(group.count == 8, "Group should have 8 members before anything happens") let output = m.condense(group) // Check the output XCTAssert(output.count == 3, "Output should have 3 merge tiles") - for (idx, _) in output.enumerate() { + for (idx, _) in output.enumerated() { let c = output[idx] switch c { - case .SingleCombine: + case .singleCombine: XCTFail("Output \(idx) was a single combine merge tile, but condense should never produce those!") - case .DoubleCombine: + case .doubleCombine: XCTFail("Output \(idx) was a double combine merge tile, but condense should never produce those!") - case .NoAction: + case .noAction: XCTFail("Output \(idx) was a no action merge tile, but shouldn't have been!") - case let .Move(s, v): + case let .move(s, v): if (idx == 0) { XCTAssert(s == 2 && v == 1, "Output \(idx) was a move merge tile, but the source or value was wrong.") } @@ -195,11 +195,11 @@ class ModelTests: XCTestCase, GameModelProtocol { func testCondense4() { let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(2), - TileObject.Tile(2), - TileObject.Tile(16), - TileObject.Empty, - TileObject.Tile(1)] + let group = [TileObject.tile(2), + TileObject.tile(2), + TileObject.tile(16), + TileObject.empty, + TileObject.tile(1)] let output = m.condense(group) XCTAssert(output.count == 4, "Output had \(output.count) merge tiles, should have had 4") } @@ -208,10 +208,10 @@ class ModelTests: XCTestCase, GameModelProtocol { func testCollapse1() { let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [ActionToken.NoAction(source: 0, value: 4), - ActionToken.NoAction(source: 1, value: 2), - ActionToken.NoAction(source: 2, value: 4), - ActionToken.NoAction(source: 3, value: 2)] + let group = [ActionToken.noAction(source: 0, value: 4), + ActionToken.noAction(source: 1, value: 2), + ActionToken.noAction(source: 2, value: 4), + ActionToken.noAction(source: 3, value: 2)] let output = m.collapse(group) XCTAssert(output.count == 4, "Output should have had 4 items, but had \(output.count) items") } @@ -225,11 +225,11 @@ class ModelTests: XCTestCase, GameModelProtocol { func testMerge1() { // Scenario: no movement at all let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(1), - TileObject.Tile(2), - TileObject.Tile(4), - TileObject.Tile(8), - TileObject.Tile(1)] + let group = [TileObject.tile(1), + TileObject.tile(2), + TileObject.tile(4), + TileObject.tile(8), + TileObject.tile(1)] XCTAssert(group.count == 5, "Group should have 5 members before anything happens") let orders = m.merge(group) XCTAssert(orders.count == 0, "No move orders should have happened, but output had \(orders.count) items") @@ -238,17 +238,17 @@ class ModelTests: XCTestCase, GameModelProtocol { func testMerge2() { // Scenario: some moves let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(1), - TileObject.Empty, - TileObject.Tile(4), - TileObject.Empty, - TileObject.Tile(1)] + let group = [TileObject.tile(1), + TileObject.empty, + TileObject.tile(4), + TileObject.empty, + TileObject.tile(1)] let orders = m.merge(group) XCTAssert(orders.count == 2, "There should have been 2 orders. Got \(orders.count) instead") // Verify orders - for (idx, order) in orders.enumerate() { + for (idx, order) in orders.enumerated() { switch order { - case let .SingleMoveOrder(s, d, v, _): + case let .singleMoveOrder(s, d, v, _): if (idx == 0) { XCTAssert(s == 2, "Got a single move order at \(idx), but source was wrong. Got \(s) instead of 2") XCTAssert(d == 1, "Got a single move order at \(idx), but destination was wrong. Got \(d) instead of 1") @@ -262,7 +262,7 @@ class ModelTests: XCTestCase, GameModelProtocol { else { XCTFail("Got a single move order at \(idx), but there shouldn't have been one") } - case .DoubleMoveOrder: + case .doubleMoveOrder: XCTFail("No double move orders are valid for this test") } } @@ -271,17 +271,17 @@ class ModelTests: XCTestCase, GameModelProtocol { func testMerge3() { // Scenario: no moves, one merge at end let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(1), - TileObject.Tile(2), - TileObject.Tile(4), - TileObject.Tile(1), - TileObject.Tile(1)] + let group = [TileObject.tile(1), + TileObject.tile(2), + TileObject.tile(4), + TileObject.tile(1), + TileObject.tile(1)] let orders = m.merge(group) XCTAssert(orders.count == 1, "There should have been 1 order. Got \(orders.count) instead") // Verify orders - for (idx, order) in orders.enumerate() { + for (idx, order) in orders.enumerated() { switch order { - case let .SingleMoveOrder(s, d, v, _): + case let .singleMoveOrder(s, d, v, _): if (idx == 0) { XCTAssert(s == 4, "Got a single move order at \(idx), but source was wrong. Got \(s) instead of 4") XCTAssert(d == 3, "Got a single move order at \(idx), but destination was wrong. Got \(d) instead of 3") @@ -290,7 +290,7 @@ class ModelTests: XCTestCase, GameModelProtocol { else { XCTFail("Got a single move order at \(idx), but there shouldn't have been one") } - case .DoubleMoveOrder: + case .doubleMoveOrder: XCTFail("No double move orders are valid for this test") } } @@ -299,17 +299,17 @@ class ModelTests: XCTestCase, GameModelProtocol { func testMerge4() { // Scenario: one move, one merge let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(2), - TileObject.Tile(2), - TileObject.Tile(16), - TileObject.Empty, - TileObject.Tile(1)] + let group = [TileObject.tile(2), + TileObject.tile(2), + TileObject.tile(16), + TileObject.empty, + TileObject.tile(1)] let orders = m.merge(group) XCTAssert(orders.count == 3, "There should have been 3 orders. Got \(orders.count) instead") // Verify orders - for (idx, order) in orders.enumerate() { + for (idx, order) in orders.enumerated() { switch order { - case let .SingleMoveOrder(s, d, v, _): + case let .singleMoveOrder(s, d, v, _): if (idx == 0) { XCTAssert(s == 1, "Got a single move order at \(idx), but source was wrong. Got \(s) instead of 1") XCTAssert(d == 0, "Got a single move order at \(idx), but destination was wrong. Got \(d) instead of 0") @@ -328,7 +328,7 @@ class ModelTests: XCTestCase, GameModelProtocol { else { XCTFail("Got a single move order at \(idx), but there shouldn't have been one") } - case .DoubleMoveOrder: + case .doubleMoveOrder: XCTFail("No double move orders are valid for this test") } } @@ -337,17 +337,17 @@ class ModelTests: XCTestCase, GameModelProtocol { func testMerge5() { // Scenario: multi-merge with 3 equal tiles involved let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(2), - TileObject.Tile(2), - TileObject.Tile(2), - TileObject.Empty, - TileObject.Empty] + let group = [TileObject.tile(2), + TileObject.tile(2), + TileObject.tile(2), + TileObject.empty, + TileObject.empty] let orders = m.merge(group) XCTAssert(orders.count == 2, "There should have been 2 orders. Got \(orders.count) instead") // Verify orders - for (idx, order) in orders.enumerate() { + for (idx, order) in orders.enumerated() { switch order { - case let .SingleMoveOrder(s, d, v, _): + case let .singleMoveOrder(s, d, v, _): if (idx == 0) { XCTAssert(s == 1, "Got a single move order at \(idx), but source was wrong. Got \(s) instead of 1") XCTAssert(d == 0, "Got a single move order at \(idx), but destination was wrong. Got \(d) instead of 0") @@ -361,7 +361,7 @@ class ModelTests: XCTestCase, GameModelProtocol { else { XCTFail("Got a single move order at \(idx), but there shouldn't have been one") } - case .DoubleMoveOrder: + case .doubleMoveOrder: XCTFail("No double move orders are valid for this test") } } @@ -370,17 +370,17 @@ class ModelTests: XCTestCase, GameModelProtocol { func testMerge6() { // Scenario: multiple merges let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(2), - TileObject.Tile(2), - TileObject.Tile(2), - TileObject.Tile(16), - TileObject.Tile(16)] + let group = [TileObject.tile(2), + TileObject.tile(2), + TileObject.tile(2), + TileObject.tile(16), + TileObject.tile(16)] let orders = m.merge(group) XCTAssert(orders.count == 3, "There should have been 3 orders. Got \(orders.count) instead") // Verify orders - for (idx, order) in orders.enumerate() { + for (idx, order) in orders.enumerated() { switch order { - case let .SingleMoveOrder(s, d, v, _): + case let .singleMoveOrder(s, d, v, _): if (idx == 0) { XCTAssert(s == 1, "Got a single move order at \(idx), but source was wrong. Got \(s) instead of 1") XCTAssert(d == 0, "Got a single move order at \(idx), but destination was wrong. Got \(d) instead of 0") @@ -394,7 +394,7 @@ class ModelTests: XCTestCase, GameModelProtocol { else { XCTFail("Got a single move order at \(idx), but there shouldn't have been one") } - case let .DoubleMoveOrder(s1, s2, d, v): + case let .doubleMoveOrder(s1, s2, d, v): if (idx == 2) { XCTAssert(s1 == 3, "Got a double move order at \(idx), but source 1 was wrong. Got \(s1) instead of 3") XCTAssert(s2 == 4, "Got a double move order at \(idx), but source 2 was wrong. Got \(s2) instead of 4") @@ -411,19 +411,19 @@ class ModelTests: XCTestCase, GameModelProtocol { func testMerge7() { // Scenario: multiple spaces and merges let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Empty, - TileObject.Tile(2), - TileObject.Tile(2), - TileObject.Tile(16), - TileObject.Tile(16)] + let group = [TileObject.empty, + TileObject.tile(2), + TileObject.tile(2), + TileObject.tile(16), + TileObject.tile(16)] let orders = m.merge(group) XCTAssert(orders.count == 2, "There should have been 2 orders. Got \(orders.count) instead") // Verify orders - for (idx, order) in orders.enumerate() { + for (idx, order) in orders.enumerated() { switch order { - case .SingleMoveOrder: + case .singleMoveOrder: XCTFail("No single move orders are valid for this test") - case let .DoubleMoveOrder(s1, s2, d, v): + case let .doubleMoveOrder(s1, s2, d, v): if (idx == 0) { XCTAssert(s1 == 1, "Got a double move order at \(idx), but source 1 was wrong. Got \(s1) instead of 1") XCTAssert(s2 == 2, "Got a double move order at \(idx), but source 2 was wrong. Got \(s2) instead of 2") @@ -446,17 +446,17 @@ class ModelTests: XCTestCase, GameModelProtocol { func testMerge8() { // Scenario: multiple spaces and merges let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Tile(4), - TileObject.Empty, - TileObject.Tile(4), - TileObject.Tile(32), - TileObject.Tile(32)] + let group = [TileObject.tile(4), + TileObject.empty, + TileObject.tile(4), + TileObject.tile(32), + TileObject.tile(32)] let orders = m.merge(group) XCTAssert(orders.count == 2, "There should have been 2 orders. Got \(orders.count) instead") // Verify orders - for (idx, order) in orders.enumerate() { + for (idx, order) in orders.enumerated() { switch order { - case let .SingleMoveOrder(s, d, v, _): + case let .singleMoveOrder(s, d, v, _): if (idx == 0) { XCTAssert(s == 2, "Got a single move order at \(idx), but source was wrong. Got \(s) instead of 2") XCTAssert(d == 0, "Got a single move order at \(idx), but destination was wrong. Got \(d) instead of 0") @@ -465,7 +465,7 @@ class ModelTests: XCTestCase, GameModelProtocol { else { XCTFail("Got a single move order at \(idx), but there shouldn't have been one") } - case let .DoubleMoveOrder(s1, s2, d, v): + case let .doubleMoveOrder(s1, s2, d, v): if (idx == 1) { XCTAssert(s1 == 3, "Got a double move order at \(idx), but source 1 was wrong. Got \(s1) instead of 3") XCTAssert(s2 == 4, "Got a double move order at \(idx), but source 2 was wrong. Got \(s2) instead of 4") @@ -482,17 +482,17 @@ class ModelTests: XCTestCase, GameModelProtocol { func testMerge9() { // Scenario: multiple moves with leading space let m = GameModel(dimension: 5, threshold: 2048, delegate: self) - let group = [TileObject.Empty, - TileObject.Empty, - TileObject.Tile(4), - TileObject.Empty, - TileObject.Tile(32)] + let group = [TileObject.empty, + TileObject.empty, + TileObject.tile(4), + TileObject.empty, + TileObject.tile(32)] let orders = m.merge(group) XCTAssert(orders.count == 2, "There should have been 2 orders. Got \(orders.count) instead") // Verify orders - for (idx, order) in orders.enumerate() { + for (idx, order) in orders.enumerated() { switch order { - case let .SingleMoveOrder(s, d, v, _): + case let .singleMoveOrder(s, d, v, _): if (idx == 0) { XCTAssert(s == 2, "Got a single move order at \(idx), but source was wrong. Got \(s) instead of 2") XCTAssert(d == 0, "Got a single move order at \(idx), but destination was wrong. Got \(d) instead of 0") @@ -506,10 +506,10 @@ class ModelTests: XCTestCase, GameModelProtocol { else { XCTFail("Got a single move order at \(idx), but there shouldn't have been one") } - case .DoubleMoveOrder: + case .doubleMoveOrder: XCTFail("No double move orders are valid for this test") } } } -} \ No newline at end of file +} From 556324a3bb6afd6e2263d890c9e8c7cd15092c3d Mon Sep 17 00:00:00 2001 From: cruisediary Date: Tue, 20 Dec 2016 17:36:08 +0900 Subject: [PATCH 2/2] Updating readme (swift3 and Xcode8) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 222d9d93..5a802188 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ If you want to check out a more advanced Swift project, please take a look at ** Instructions ------------ -You will need Xcode 7 to run the project. Run it in the simulator or on an actual device. +You will need Xcode 8 to run the project. Run it in the simulator or on an actual device. Tap the button to play the game. Swipe to move the tiles.