• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[SWIFT]Nie działa wyświetlanie aktualnej liczby ludności miasta

VPS Starter Arubacloud
+1 głos
194 wizyt
pytanie zadane 11 lutego 2017 w Android, Swift, Symbian przez Piotrinformatyk Początkujący (340 p.)
edycja 11 lutego 2017 przez Piotrinformatyk

Witam :)

Jestem dość początkujący. Uczę się z książki (już miesiąc-półtora miesiąca): "Programowanie w języku Swift. Big Nerd Ranch Guide" autorów Matthew Mathias, John Gallagher i skończyłem rozdział o strukturach i klasach. Za zadanie miałem poprawić kod, aby liczba ludności nie spadała poniżej 0 i gdy liczba zabitych ludzi będzie większa niż aktualna liczba ludności w mieście to aby wyświetlało, że populacja wynosi 0. W drugim zadaniu natomiast mam dodać wampiry i ich użyć. Niestety jak korzystam z wampirów to liczba ludności zawsze wychodzi 100. Próbowałem wielu rzeczy, ale albo są błędy, których nie dało się niestety rozwiązać albo nie daje to porządanego skutku. Chcę, aby po każdym ataku pokazywało ile ludzi pozostało po ataku wampira (tak jakby zawsze 1 wampir atakuje) a najlepiej, żeby wraz z atakiem coraz większej ilości wampirów i zombie coraz szybciej ubywało ludzi, czyli chcę coś ponad zadaniem zrobić. Niestety pomysłów już nie mam. Próbuję korzystać z dokumentacji, ale na razie słabo mi idzie korzystanie z niej. Ktoś mi pomoże? Nakieruje mnie lub wskaże mi gdzie czegoś brakuje? Może jakiegoś sposobu nie zauważyłem i nadal nie widzę.

import Foundation

class Monster {
    var town: Town?
    var name: String
    
    init(names: String = "Monster") {
        name = names
    }
    
    func terrorizeTown() {
        if town != nil {
            print("\(name) terrorizes the city")
        }
        else if Town().population == 0 {
            print("\(name) ceases to terrorize the city")
        }
        else {
            attackTheZombie.terrorizeTown()
            print("\(name) jet not found the city to terrorize.")
            }
    }
}
import Foundation

struct Town {
    var population = 100
    var numberOfStopLights = 4
    
    func printPopulation() {
        print("Population: \(population), number intersections with light signaling: \(numberOfStopLights)")
    }
    
    mutating func changePopulation(amout: Int) {
        if population > 0 {
        population += amout
        }
        else if population < amout {
            print("Populations isn't in the city")
        }
    }
}
import Foundation

class Zombie: Monster {
    
    
    override init (names: String = "Zombie") {
        super.init(names: "Zombie")
    }
    
    final override func terrorizeTown() {
        if Town().population > 0 {
           town?.changePopulation(amout: -10)
            print(Town().population)
            super.terrorizeTown()
        }
        else if Town().population < 0 {
                print("Populations is  0.")
            }
    }
}
import Foundation

class Vampire: Monster {
    var vampires: [String] = []
    var newVampires = [
        "Marcin",
        "Ewa",
        "Daniel",
        "Paweł",
        "Daniel",
        "Adam"
    ]
    
    override init (names: String = "Vampire") {
        super.init(names: "Vampire")
    }
    
    override func terrorizeTown() {
        if Town().population > 0 {
           
            for number in newVampires {
                vampires.append(number)
                print(vampires)
                print(vampires.count)
                print(Town().population)
        
            }
        }
        else if Town().population == 0 {
            print("Populations: \(Town().population)")
        }
    }   
}
import Foundation

var myTown = Town()

myTown.printPopulation()


let attackTheZombie = Zombie()
attackTheZombie.town = myTown
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()

attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()
attackTheZombie.terrorizeTown()
attackTheZombie.town?.printPopulation()

myTown.printPopulation()

let  attackTheVampire = Vampire()
attackTheVampire.town = myTown
attackTheVampire.terrorizeTown()
attackTheVampire.town?.printPopulation()
attackTheVampire.terrorizeTown()
attackTheVampire.town?.printPopulation()
attackTheVampire.terrorizeTown()
attackTheVampire.town?.printPopulation()
attackTheVampire.terrorizeTown()
attackTheVampire.town?.printPopulation()

 

1 odpowiedź

0 głosów
odpowiedź 28 lutego 2017 przez Raymond.Z Obywatel (1,800 p.)

Cześć.

Ogólnie na pierwszy rzut oka, no jest parę błędów, ale to zapraszam już do dyskusji w komentarzach albo prywatnie to tam powiem trochę więcej.

Zacznijmy od tego, że nigdzie w klasie Vampire w metodzie terrorizeTown() nie ma instrukcji, która by była odpowiedzialna za zmniejszanie populacji miasta, dlatego też ta ilość cały czas wynosi 100.

Druga sprawa to, że przy dziedziczeniu, nadpisując metody powinniśmy wywoływać ów metodę klasy nadrzędnej poprzez słowo kluczowe super. Tak jak jest to zrobione w klasie Zombie (super.terrorizeTown()), dlaczego? No często w takich metodach w klasach nadrzędnych mogą się znajdować jakieś ważne instrukcje, które wpływają na poprawność działania jakichś mechanizmów, więc rozsądnie będzie je wywołać, zwłaszcza, że nie zawsze jesteśmy pewni co tam się znajduję. Ostrożność tą polecam szczególnie zachować przy tworzeniu widoków i nadpisywania jakichś zdefiniowanych już metod.

A co do uzależnienia odejmowanej ilości populacji od ilości wampirów i zombie to dobrze by było zrobić jakąś klasę, która by odpowiadała za zdarzenia w mieście, czy jest atakowane przez co, zawierające jakąś tablicę typu [Monster], gdzie w zależności od ilości potworów w mieście byłaby ta wartość odpowiednio odejmowana.

To wszystko jeśli chodzi o pytania, jeszcze tak dodam od siebie, że widziałem, że często tworzysz nowe obiekty typu Town pisząc Town() i nie jest to do końca dobre zwłaszcza przy porównywaniu. Chcesz porównywać wartości do konkretnego miasta, a nie nowo utworzonego.

Pozdrawiam i życzę dalszej owocnej nauki :-)

komentarz 1 marca 2017 przez Piotrinformatyk Początkujący (340 p.)

Trochę czasu minęło. W tym czasie przeszedłem dalej i już kod lepiej działa. Obecnie jestem na protokołach. Zrobiłem oba zadania, w tym łatwiejszą wersję i próbuję zrobić trudniejszą, czyli wyrównanie tabelki i  tylko pierwszy wiersz jest wyrównany, natomiast z pozostałymi mam nadal problem  Niestety nie do końca działa, ale najpierw kod pokaże kod :) 

var myTown = Town(region: "West", population: 1000, stopLights: 6)

var mayor = Mayor()

let attackTheZombie: Zombie? = Zombie(limp: false, fallingApart: false, town: myTown, monsterName: "Fred")
attackTheZombie?.town = myTown

let  attackTheVampire: Vampire? = Vampire(town: myTown, monsterName: "Drakula")
attackTheVampire?.town = myTown

print("Size the city: \(myTown.townSize)")

attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()

//attackTheZombie.victimPool = 500
//print("Pool of victims: \(attackTheZombie.victimPool)")
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
attackTheZombie?.terrorizeTown()
//print("Pool of victims: \(attackTheZombie.victimPool)")

attackTheVampire?.terrorizeTown()
attackTheVampire?.terrorizeTown()
attackTheVampire?.terrorizeTown()
attackTheVampire?.terrorizeTown()


//attackTheZombie.victimPool = 500
//print("Pool of victims: \(attackTheZombie.victimPool)")

var convenientZombie = Zombie(limp: true, fallingApart: false)

 

import Foundation

struct Mayor {
    
    var population: String = "I am deeply saddened information about the recent tragedy. I promise I will exactly look at the  avalanche of violence."
    var anxietyLevel: Int = 0
}

 

struct Town {
    let region: String
    var population: Int {
        didSet(oldPopulation) {
            if oldPopulation > population {
                print("The size of the population has changed at \(population) from \(oldPopulation).")
                print(mayor.population)
            }
        }
    }
    var numberOfStopLights: Int
    
    init(region: String, population: Int, stopLights: Int) {
        self.region = region
        self.population = population
        numberOfStopLights = stopLights
    }
    
    init(population: Int, stopLights: Int) {
        self.init(region: "brak danych", population: population, stopLights: stopLights)
    }
    enum Size {
        case small
        case medium
        case big
    }
    var townSize: Size {
        get {
            switch self.population {
            case 0...10000:
                return Size.small
            case 10001...100000 :
                return Size.medium
            default:
                return Size.big
            }
        }
    }
    
    func printPopulation() {
        print("Population: \(population), number intersections with light signaling: \(numberOfStopLights) in region \(region).")
    }
    
    mutating func changePopulation(amout: Int) {
        if population > 0 {
        population += amout
        }
        else if population < amout {
            print("Populations isn't in the city")
        }
    }
}

 

class Monster {
    var town: Town?
    var name: String
    static let isTerrifying = true
    
    init?(town:Town?, monsterName: String) {
        if monsterName.isEmpty {
            return nil
        }
        self.town = town
        name = monsterName
    }
    


    class var spookyNoise: String {
         return "Grrr..."
    }
    
    var victimPool: Int {
        get {
            return town?.population ?? 0
        }
        set(newVictimPool) {
            return (town?.population = newVictimPool)!
        }
    }
    
    func terrorizeTown() {
        if town != nil {
            print("\(name) terrorizes the city")
            mayor.anxietyLevel += 1
            print(mayor.population)
            print("Number of anxietyLevel: \(mayor.anxietyLevel).")
           
        }
        else if myTown.population == 0 {
            print("\(name) ceases to terrorize the city")
        }
        else {
            attackTheZombie?.terrorizeTown()
            print("\(name) jet not found the city to terrorize.")
            }
    }
    deinit {
        print("Monster \(name) isn't longer with us")
    }
}
class Zombie: Monster {
    var walksWithLimp: Bool
    
     private(set) var isFallingApart: Bool
    
    override class var spookyNoise: String {
        return "Brains..."
    }
    init?(limp: Bool, fallingApart: Bool, town:Town?, monsterName: String) {
        walksWithLimp = limp
        isFallingApart = fallingApart
        super.init(town: town, monsterName: monsterName)
    }
    
    convenience init?(limp: Bool, fallingApart: Bool) {
        self.init(limp: limp, fallingApart: fallingApart, town: nil, monsterName:"Fred")
        if walksWithLimp {
            print("Zombie has damaged knee")
        }
    }
    
    final override func terrorizeTown() {
        if !isFallingApart {
        if myTown.population > 0 {
           town?.changePopulation(amout: -10)
            print("\(name) terrorizes the city")
            mayor.anxietyLevel += 1
            print("Number of anxietyLevel: \(mayor.anxietyLevel).")
        }
        else if myTown.population <= 0 {
                print("Populations is  0.")
            }
        }
    }
    deinit {
        print("Zombie \(name)")
    }
}
class Vampire: Monster {
    var vampires: [String] = []
    var newVampires = [
        "Marcin",
        "Ewa",
        "Daniel",
        "Paweł",
        "Daniel",
        "Adam"
    ]
    override class var spookyNoise: String {
        return "Blood!!!"
    }
    
    override init?(town: Town?, monsterName: String) {
        super.init(town: town, monsterName: monsterName)
    }
    
    override func terrorizeTown() {
        if myTown.population > 0 {
            for number in newVampires {
                vampires.append(number)
                print("\(name) terrorizes the city")
                print("Number of vampires:\(vampires.count)")
                town?.changePopulation(amout: -1)
                mayor.anxietyLevel += 1
                print("Number of anxietyLevel: \(mayor.anxietyLevel).")
            }
        }
        else if myTown.population == 0 {
            print("Populations: \(myTown.population)")
        }
    }
    deinit {
        print("Vampires \(name) isn't longer with us")
    }
}

 

 

Próbowałem, aby metoda didSet działała tylko wtedy kiedy terroryzowane miasto. Niestety ciągle po określeniu wielkości miasta wyświetla się: "The size of the population has changed at 990 from 1000. I am deeply saddened information about the recent tragedy. I promise I will exactly look at the  avalanche of violence." Próbowałem to zmienić, aby nie wyświetlało się, ale nie udało mi się to. Nie dość, że wyświetla się wypowiedź prezydenta to na start populacja miasta maleje o 10. Jak dołożę tablicę zombie to będzie mi wyświetlało ilość zombi, więc oprócz tego powyżej wszystko działa. Myślałem nad konstrukcją warunkową, ale nie wiem do czego miałbym ją za bardzo porównać. Do tego struktura Town nie widzi jej. Próbowałem, więc innych rzeczy ale bez skutku. Wiesz jak można się tego problemu pozbyć?

komentarz 1 marca 2017 przez Raymond.Z Obywatel (1,800 p.)

Tak na pierwszy rzut oka wszystko zdaje się być okej. 

Wywołujesz metodę terrorizeTown(), która zmienia populacje miasta o 10, wykonuje się didSet, bo populacja została ustawiona na wartość o 10 mniejszą, wypisuje się więc komunikat "The size of the population has changed at 990 from 1000.", a następne kolejna instrukcja w didSet to print(mayor.population), która wypisuje Ci "I am deeply saddened information about the recent tragedy. I promise I will exactly look at the  avalanche of violence."

Ogólnie jak pisałem wcześniej, trochę kod jest źle napisany i kilka zmian by się w nim przydało ( refaktoryzacja ), ale na dobry początek powiedz mi, Ty robisz to w playground'ie czy jakiś projekt masz?

komentarz 1 marca 2017 przez Piotrinformatyk Początkujący (340 p.)
W projekcie z książki to robię. Muszę kod projektu tak zmienić, aby wykonać zadanie.
komentarz 2 marca 2017 przez Piotrinformatyk Początkujący (340 p.)
Co należało by poprawić? Jak się pozbyć komunikatu o którym ostatnio wspomniałem? Skończyłem z tym projektem w książce, ale pozbycie się tego problemu zawsze czegoś mnie nauczy :)

Podobne pytania

0 głosów
3 odpowiedzi 562 wizyt
pytanie zadane 29 stycznia 2017 w Android, Swift, Symbian przez Piotrinformatyk Początkujący (340 p.)
0 głosów
0 odpowiedzi 197 wizyt
pytanie zadane 17 lipca 2019 w Android, Swift, Symbian przez Trefoil Początkujący (350 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...