Stuck on a DeckOfCards class - swift

I'm working on a poker app. I have 2 questions,,,
1) Just started working on a DeckOfCards class to deal with the deck. I keep getting an error ("Expected Declaration") on one of the for loops. It worked on playgrounds but not in the project (not as a class though). How do I fix this?
2) Is it ok to have the cards represented this way (2 character strings in an array)?
import Foundation
class DeckOfCards {
var newDeck = ["A♠️", "2♠️", "3♠️", "4♠️", "5♠️",...."K♠️",
"A♥️", "2♥️", "3♥️", "4♥️", "5♥️",...."K♥️",
"A♣️", "2♣️", "3♣️", "4♣️", "5♣️",...."K♣️",
"A♦️", "2♦️", "3♦️", "4♦️", "5♦️",...."K♦️"]
var deck = [String]()
var randomNumber = 0
init() {
deck = []
}
for _ in 1...52 { // ERROR ON THIS LINE ("Expected Declaration")
randomNumber = Int(arc4random_uniform(UInt32(newDeck.count)))
deck.append(newDeck.removeAtIndex(randomNumber))
}
}

It is because you simply cannot have code hang like this within a class definition. You need to put it in a func. e.g.
func shuffleDeck() -> [String] {
var deck = [String]()
for _ in 1...52 {
randomNumber = Int(arc4random_uniform(UInt32(newDeck.count)))
deck.append(newDeck.removeAtIndex(randomNumber))
}
return deck
}
To answer your second part of the question, you are better off to use enum to represent the cards. Here is a good example: Add a method to Card that creates a full deck of cards, with one card of each combination of rank and suit

Related

Swift - Declare nested variable names using dot

I'll keep it short. I'm trying to accomplish the following:
class Media {
var likes.count : Int? = 0
}
Obviously the complier throws me an error:
Consecutive declarations on a line must be separated by ';'
Is there a way to work around this? I know that i can eventually do some kind of String Replace using Mirror(reflecting:object) but i'd like to keep it efficient. Would love any help. Thanks.
UPDATE:
I wasn't clear enough, sorry. The issue is that the complier won't let me use . inside the variable declaration name.
The issue is that the complier won't let me use . inside the variable declaration name.
Exactly, a property name in Swift cannot contain the . character.
A possible approach
Now, if you want to be able to write something like this
let media = Media()
media.likes.count = 1
then you need to define your class like shown below
class Media {
class Likes {
var count = 0
}
var likes = Likes()
}
or
class Likes {
var count = 0
}
class Media {
var likes = Likes()
}
A few suggestions
PLEASE don't use implicitly unwrapped optionals like this one
var likes.count : Int! = 0
They are like a gun ready to fire and crash your entire app!
And finally the class keyword begins with a lowercase character: class not Class.
I recommend using a Struct. A Struct is basically the same as a class that is referenced by value. So you can have as many Structs as you want with their own nested variables and functions, just like a class! And the best part is, you never have to use the Struct as a functional piece of code, just as something to namespace your variables in. I do this frequently with a Constants swift file.
struct Constants {
struct MainMenu {
static var height:CGFloat = 420
static var width:CGFloat = 240
static var backgroundColor:UIColor = .red
}
struct MainViewController {
static var toolBarHeight:CGFloat = 49
static var backgroundColor:UIColor = .blue
}
}
Usage:
func getRemainingHeight() ->CGFloat {
let viewHeight = self.view.bounds.size.height
let menuHeight = Constants.MainMenu.height
let toolBarHeight = Constants.MainViewController.toolBarHeight
return viewHeight - (menuHeight + toolBarHeight)
}

Simple observable struct with RxSwift?

I'm trying to come up with a simple observable object in Swift and thought to use RxSwift. I couldn't find a simple example to do something like this:
protocol PropertyObservable {
typealias PropertyType
var propertyChanged: Event<(PropertyType, Any)> { get }
}
class Car: PropertyObservable {
typealias PropertyType = CarProperty
let propertyChanged = Event<(CarProperty, Any)>()
dynamic var miles: Int = 0 {
didSet {
propertyChanged.raise(.Miles, oldValue as Any)
}
}
dynamic var name: String = "Turbo" {
didSet {
propertyChanged.raise(.Name, oldValue as Any)
}
}
}
The above is pure Swift solution for observables from this blog post; I really like how it's a protocol-based solution and not invasive. In my case, I have an object in my project where each property is set asynchronously under the hood (bluetooth device). So I need to observe/subscribe to the changes instead of getting/setting the properties in real-time.
I keep hearing RxSwift will do just that and more. However, I can't find a simple example to match above and beginning to think RxSwift is overkill for my need? Thanks for any help.
Easiest way to quickly make this observable with RxSwift would probably be to use the RxSwift class Variable (all code here is untested off the top of my head):
import RxSwift
class Car {
var miles = Variable<Int>(0)
var name = Variable<String>("Turbo")
}
This enables you to observe the values by subscribing to them:
let disposeBag = DisposeBag()
let car = Car
car.name.asObservable()
.subscribeNext { name in print("Car name changed to \(name)") }
.addToDisposeBag(disposeBag) // Make sure the subscription disappears at some point.
Now you've lost the old value in each event. There are of course numerous ways to solve this, the RxSwifty way would probably be to add a scan operation to your element sequence, which works a lot like reduce does on a normal Array:
car.name.asObservable()
.scan(seed: ("", car.name.value)) { (lastEvent, newElement) in
let (_, oldElement) = lastEvent
return (oldElement, newElement)
}
.subscribeNext { (old, new) in print("Car name changed from \(old) to \(new)") }
.addToDisposeBag(disposeBag)

Swift SpriteKit use struct instead of class to render sprites

I have been updating my game recently to use more value types. I am still not 100% confident with weak and unowned in some cases so I went the struct way to avoid strong reference cycles. As per apples newer keynotes it seems value types are they way to go for the most part anyway.
I have never seen an example where structs are used to render sprites in a spriteKit game so I wonder what the drawbacks are.
I understand that they are copied and not referenced but for my usage it seems to work.
So basically is there something I need to watch out for when doing this
struct Flag {
let post: SKSpriteNode
let flag: SKSpriteNode
init(postImage: String, flagImage: String) {
post = SKSpriteNode(imageNamed: postImage)
// other set ups for post sprite
flag = SKSpriteNode(imageNamed: flagImage)
// other set ups for flag sprite
post.addChild(flag)
}
func animate() {
// code to animate flag
}
}
Than in my SKScenes I simply add them as usual
let flag = Flag(postImage: "FlagPostImage", flagImage: "FlagImage")
flag.post.position = ...
addChild(flag.post)
flag.animate()
Now even if I create multiple flags in the same scene I seem to have no problems with this way.
I am just curious because I have never really seen an example like this so I wonder if I am missing something, like performance drawbacks etc.
Thanks for any help.
Personally I avoid creating Structs that contain Classes. Because Structs copy, each and every copy that get's passed around your app will increase the reference count of the Classes. This makes it harder to manage them instead of easier.
It is also useful to take a look at how UIKit uses Structs. A UIView is an object but has many defining properties that are Structs. For example it's frame.
Drop the code below in a playground to see some effects of this behaviour.
The protocol is just to get some meaningful feedback form the playground.
protocol IDLookable : CustomPlaygroundQuickLookable {
var id : Int { get set }
}
extension IDLookable {
func customPlaygroundQuickLook() -> PlaygroundQuickLook {
return PlaygroundQuickLook.AttributedString(NSAttributedString(string: "\(self.dynamicType) with id : \(self.id)"))
}
}
class MyClass : IDLookable {
var id : Int = 0
init(id : Int) {
self.id = id
}
}
struct MyContainerStruct : IDLookable {
var id : Int = 0
var object : MyClass
init(id : Int, object:MyClass) {
self.id = id
self.object = object
}
}
class Scope {
// ref count = 1
var object = MyClass(id: 11)
var structContainer : MyContainerStruct
init() {
// ref count = 2
structContainer = MyContainerStruct(id: 222, object: object)
messWithAClassInAStruct()
}
func messWithAClassInAStruct() {
// ref count = 3
var structContainerTwo = structContainer
structContainerTwo.id = 333
structContainerTwo.object // 11
// altering the object in one struct will obvously update all references
structContainerTwo.object.id = 1
structContainer.object // 1
structContainerTwo.object // 1
}
}
let test = Scope()
One pattern that does make it easy to work with Reference Types in Value Types is to store them as weak optionals in the Value Types. This means that something will need to have a strong reference but chances are that some Class will be responsible for creating the Structs this is a good place to keep that strong reference.
struct MyContainerStruct : IDLookable {
var id : Int = 0
weak var object : MyClass?
init(id : Int, object:MyClass) {
self.id = id
self.object = object
}
}
class Scope {
// ref count = 1
var object = MyClass(id: 11)
var structContainer : MyContainerStruct
init() {
// ref count = 1
structContainer = MyContainerStruct(id: 222, object: object)
messWithAClassInAStruct()
}
func messWithAClassInAStruct() {
// ref count = 1
var structContainerTwo = structContainer
structContainerTwo.id = 333
structContainerTwo.object // 11
}
}
let test = Scope()

Differences between "static var" and "var" in Swift

What is the main difference between "static var" and "var" in Swift? Can someone explain this difference to me, possibly with a little example?
static var belongs to type itself while var belongs to instance (specific value that is of specific type) of type. For example:
struct Car {
static var numberOfWheels = 4
var plateNumber: String
}
Car.numberOfWheels = 3
let myCar = Car(plateNumber: "123456")
All cars has same amount of wheels. An you change it on type Car itself.
In order to change plate number you need to have instance of Car. For example, myCar.
I'll give you a very nice Swifty example based on this post. Though this is a bit more sophisticated.
Imagine you have a project in which you have 15 collectionViews in your app. For each you have to set the cellIdentifier & nibName. Do you really want to rewrite all code for your that 15 times?
There is a very POP solution to your problem:
Let's help ourselves by writing a protocol which returns a string version of our ClassName
protocol ReusableView: class {
static var defaultReuseIdentifier: String { get }
}
extension ReusableView where Self: UIView {
static var defaultReuseIdentifier: String {
return String(Self)
}
}
extension BookCell : ReusableView{
}
The same for the nibName of each custom cell you have created:
protocol NibLoadableView: class {
static var nibName: String { get }
}
extension NibLoadableView where Self: UIView {
static var nibName: String {
return String(Self)
}
}
extension BookCell: NibLoadableView {
}
so now where ever I need nibName I would just do
BookCell.nibName
And where ever I need cellIdentifier I would just do:
BookCell.defaultReuseIdentifier
Now specifically to your question. Do you think we need to change the cellIdentifier per each new instance of BookCell?! No! All cells of BookCell will have the same identifier. It's not something that would change per instance. As a result it's been made static
While I did answer your question, the solution to reducing the number of lines for the 15 collectionViews can still be significantly improved so do see the blog post linked.
That blog post has actually been turned into a video by NatashaTheRobot
A static var is property variable on a struct versus an instance of the struct. Note that static var can exist for an enum too.
Example:
struct MyStruct {
static var foo:Int = 0
var bar:Int
}
println("MyStruct.foo = \(MyStruct.foo)") // Prints out 0
MyStruct.foo = 10
println("MyStruct.foo = \(MyStruct.foo)") // Prints out 10
var myStructInstance = MyStruct(bar:12)
// bar is not
// println("MyStruct.bar = \(MyStruct.bar)")
println("myStructInstance = \(myStructInstance.bar)") // Prints out 12
Notice the difference? bar is defined on an instance of the struct. Whereas foo is defined on the struct itself.

My first swift hello world application, build error when trying access a class

So this is my hello world application with swift. Also not used to XCode. So, might be a silly mistake here.
I just have one class Deck.swift
class Deck {
let decks : Integer = 0
init () {
decks = 1
}
init (amountOfDecks : Integer){
decks = amountOfDecks
}
func getAmountOfCards() -> Integer {
return 0
}
}
Then I'm trying to run a unit test that look like this
import XCTest
import helloWorldv2
class helloWorldv2Tests: XCTestCase {
override func setUp() {
super.setUp()
}
override func tearDown() {
super.tearDown()
}
func testDeckConstructor() {
var deck = Deck(amountOfDecks: 2)
XCTAssert(true, "Pass")
}
func testExample() {
// This is an example of a functional test case.
XCTAssert(true, "Pass")
}
}
If I comment out the line var deck = Deck(amountOfDecks: 2) then it builds fine. If that line is included I get build failed.
Anyone know what I'm doing wrong here?
If you want to modify deck param you have to declare it like this
var decks : Int = 0
If you put let your variable is read only after first assignment.
Whilst #jaumard is correct in saying that it is var rather than let that you should be using, you should use "Int" as the type, not "Integer" (which is a protocol, not a type). You get away with it because both are superfluous because of type inference...
var decks = 0
is quite sufficient, or
var decks: Int = 0
if you want to be verbose.
See this answer.
No need to turn your let constant into a var.
Simply don't provide a default value when declaring it.
let decks : Int
Your = 0 already initializes your constant, and than you're trying to change it in init, which is not allowed for constants.