Create a function that returns the name of the winner in a fight between two fighters.
Each fighter takes turns attacking the other and whoever kills the other first is victorious. Death is defined as having health <= 0.
Each fighter will be a Fighter object/instance. See the Fighter class below in your chosen language.
Both health and damagePerAttack (damage_per_attack for python) will be integers larger than 0. You can mutate the Fighter objects.
Your function also receives a third argument, a string, with the name of the fighter that attacks first.
Example:
declare_winner(Fighter("Lew", 10, 2), Fighter("Harry", 5, 4), "Lew") => "Lew"Lew attacks Harry; Harry now has 3 health.
Harry attacks Lew; Lew now has 6 health.
Lew attacks Harry; Harry now has 1 health.
Harry attacks Lew; Lew now has 2 health.
Lew attacks Harry: Harry now has -1 health and is dead. Lew wins.
Technical note: The second fighter argument (f2) always attacks first.
這次題目實在太長了,先整理一下:
Create a function declare_winner
that determines the name of the winner in a fight between two fighters (Fighter
).
Rules:
Fighters take turns attacking each other.
The first to reduce the opponent’s health (hp
) to 0 or below wins.
Each fighter has:
name
: the fighter’s namehp
: health (an integer > 0)attack
: damage dealt per attack (an integer > 0)The third argument specifies the name of the fighter who attacks first.
Fighter
objects are mutable.
這題在調整測試的寫法(我是用 comment 做 evaluate)就花了不少工夫。
這是我的解法,我不使用 Fighter 物件,而是在測試中直接傳入對應的 map 資料結構:
(comment
(tester {:name "Harald" :health 20 :damage-per-attack 5} {:name "Harry" :health 5 :damage-per-attack 4} "Harald")
(tester {:name "Jerry" :health 30 :damage-per-attack 3} {:name "Harald" :health 20 :damage-per-attack 5} "Harald"))
Math/ceil
: rounds up to calculate number of attacks needed to win
let
: binds the number of attacks each fighter needsif
: determines the winner based on who needs fewer attacks; implement
(defn declare-winner [f1 f2]
(let [attacks-f1-needs (Math/ceil (/ (:health f2) (:damage-per-attack f1)))
attacks-f2-needs (Math/ceil (/ (:health f1) (:damage-per-attack f2)))]
(if (<= attacks-f1-needs attacks-f2-needs)
(:name f1)
(:name f2))))
; test
; execute implement function
(defn tester [f1 f2 exp]
(= (declare-winner f1 f2) exp))
; args & exception
(comment
(tester {:name "Harald" :health 20 :damage-per-attack 5} {:name "Harry" :health 5 :damage-per-attack 4} "Harald")
(tester {:name "Jerry" :health 30 :damage-per-attack 3} {:name "Harald" :health 20 :damage-per-attack 5} "Harald"))