2

この単純なゲームには、2 人のファイターを戦わせることを目的とするクラス ファイターがあります。体力が 0 未満になると、ゲームに負けます。

戦うために、別の非静的メソッド攻撃 (..) によってサポートされた、1 人の戦闘機がゲームに勝つまで反復する静的メソッドの戦い (..) があります。

object Fighter のヘルスは、メソッドfight(...)とattack(...)を使用してゲーム中に2つのオブジェクトが戦うと変化するはずです。問題は、常に同じファイターのヘルスを出力し、ゲームが終了しないことです。問題がどこにあるのかわかりません

class ViewController: UIViewController {
     override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let david = Fighter(name: "David", health: 100, damage: 30, defense: 10, initiative: 80)
        let goliath = Fighter(name: "Goliath", health: 300, damage: 60, defense: 14, initiative: 90)


        let myFight1 = Fighter.fight(fighter1: david, fighter2: goliath) // always executing same Fighters
        print(myFight1)

    }
}

import Foundation


struct Fighter {
    var name: String
    var health: Double
    var damage: Int
    var defense: Int
    var initiative: Int

    init (name: String, health: Double, damage: Int, defense: Int, initiative: Int) {
        self.name = name
        self.health = health
        self.damage = damage
        self.defense = defense
        self.initiative = initiative
    }

     init (name: String, health: Double, damage: Int, defense: Int) {
        self.name = name
        self.health = health
        self.damage = damage
        self.defense = defense
        self.initiative = 0
    }

    static func fight(fighter1: Fighter, fighter2: Fighter) -> Fighter {
        let f1 = fighter1
        let f2 = fighter2

        if f1.health == f2.health {
            return f1
        }

        if f2.initiative > f1.initiative {
           f2.attack(f: f1)
        }

        var i = 0

        while f1.health > 0 {
            i += 1
            print("--> i: \(i)")
            f1.attack(f: f2 )

            if f2.health <= 0 {
                return f1
            }
        f2.attack(f: f1)
            }
        return f2
        }

    func attack(f: Fighter) -> Void {
        var g = f
        g.health = g.health - Double(g.damage * (1 - g.defense / 100))
        print(g)
    }        
}
4

4 に答える 4

0

Rakesha が指摘しているように、構造体は値型であるため、attackコードは実際には何も変更しません。

func attack(f: Fighter) -> Void {
    var g = f   // Make a mutable copy of `f` called `g`
    g.health = g.health - Double(g.damage * (1 - g.defense / 100)) // Modify g
    print(g) // Print g
    // Throw g away
}

(補足:g.damageここでは間違っていると思います。おそらくあなたが意味していたと思いますself.damage。)

実際には何も変更されませんf。これに対処するにはいくつかの方法があります。1 つはクラスを使用することで、微妙な可変状態を導入します。ここではやらないと思います。「微妙な可変状態」とは、attackを変更することを期待していることを意味しますfが、署名にはそれを行うとは何も書かれていないため、呼び出し元は驚かれる可能性があります。

代わりに、これを実装して、構造体でミューテーションを明示的にする方法がいくつかあります。attack明示的に変更することができますf:

func attack(f: inout Fighter) {
    f.health = f.health - Double(damage * (1 - f.defense / 100))
}

または、他の誰かに攻撃されたときに、向きを変えて自分自身を変更することもできます。

mutating func attackedBy(f: Fighter) {
    health = health - Double(f.damage * (1 - defense / 100)
}
于 2018-10-03T14:38:18.270 に答える