Kurzusok
/
Crystal
Crystal
/
Feladatok
/
elvarázsolt-acél
elvarázsolt-acél

elvarázsolt-acél

Tanulófeladat

Bevezetés

A programozásban az iteráció egy kódrészlet többszöri megismétlését jelenti. Ezt megteheted például while- és until-ciklusokkal. Rekurzióval is megoldható, ami egy önmagát meghívó függvény.

Leggyakrabban azonban egy elemgyűjteményen szeretnél iterálni, például egy Array, Range vagy String objektumon. A Crystalben az Array és a Range osztály is tartalmazza az Enumerable modult, ami számos metódust kínál az elemeken való iteráláshoz. A String osztálynak eközben saját metóduskészlete van a karaktereken való iteráláshoz.

A Crystalben ráadásul nincs for utasítás, mint sok más nyelvben. Helyette több metódus is használható az iteráláshoz.

Iterálás

A leggyakoribb módja a gyűjteményen való iterálásnak a each metódus használata, ami a gyűjtemény minden elemét átadja egy blokknak. Ez egy Range segítségével könnyedén megtehető. Tegyük fel, hogy 1 és 3 között szeretnél ciklust futtatni; ekkor az each metódussal iterálhatsz a tartományon.

(1..3).each do |n|
  puts n
end

# Output:
# 1
# 2
# 3

Még egyszerűbb, ha csak adott számú alkalommal szeretnél iterálni: használhatod a times metódust, ami az Int osztályon érhető el.

3.times do |n|
  puts n
end

# Output:
# 0
# 1
# 2

Iterálás String-en

A String karakterek sorozata, és nem tartozik az Enumerable modulhoz, ami azt jelenti, hogy saját metóduskészlete van a karaktereken való iteráláshoz. A leggyakoribb módja a String-en való iterálásnak a each_char metódus használata, ami a String minden karakterét átadja egy blokknak.

Note

Az each_char metódus egy Char objektumot ad át a blokknak, nem pedig egy String objektumot.

str = "hello"
str.each_char { |char| puts char }

# Output:
# h
# e
# l
# l
# o

A String-en való iterálás másik módja a each_line metódus használata. Ezt a metódust főleg akkor használod, amikor egy fájlt soronként olvasol be.

str = "hello\nworld"
str.each_line do |line|
  puts line
end

# Output:
# hello
# world

Iterálás olyan objektumon, amely tartalmazza az Enumerable modult

Az Enumerable modul számos metódust kínál egy gyűjtemény elemein való iteráláshoz. Gyűjtemények, amelyek tartalmazzák az Enumerable modult: Array, Range, Hash, Set és mások; az utóbbiakkal későbbi fogalmakban fogsz találkozni.

A leggyakoribb módja az Array-en való iterálásnak a each metódus használata, ami az Array minden elemét átadja egy blokknak.

arr = [5, 2, 3]
arr.each do |element|
  puts element
end

# Output:
# 5
# 2
# 3

Map

A map metódus egy másik módja az Array-en való iterálásnak: egy új Array-t ad vissza, amely a blokk minden elemre való alkalmazásának eredményeit tartalmazza. Hasonlít az each metódushoz, de egy új Array-t ad vissza az átalakított elemekkel. Az átalakítás nagyon hasznos, ha egy függvényt szeretnél alkalmazni a gyűjtemény minden elemére, ami gyakori művelet.

arr = [1, 2, 3]
new_arr = arr.map do |element|
  element * 2
end

new_arr
# => [2, 4, 6]

Egy if-hez hasonló vezérlési szerkezettel azt is megválaszthatod, hogy mely elemeket alakítsd át.

arr = [1, 2, 3]
new_arr = arr.map do |element|
  if element.odd?
    element * 2
  else
    element
  end
end

new_arr
# => [2, 2, 6]

Indexszel

Néha tudnod kell, hogy éppen melyik elemen iterálsz; erre az each_with_index vagy a map_with_index metódust használhatod. Minden elemet és annak indexét átadja egy blokknak, és a metódus elfogad egy opcionális argumentumot is a kezdőindex megadásához.

arr = [1, 2, 3]
arr.each_with_index(4) do |element, index|
  puts "Element: #{element}, Index: #{index}"
end

# Output:
# Element: 1, Index: 4
# Element: 2, Index: 5
# Element: 3, Index: 6

Ne feledd, hogy az each_char_with_index metódus is elérhető String objektumokhoz.

sum

A sum metódus a gyűjtemény összes elemének összegét adja vissza, és elfogad egy opcionális blokkot is, amellyel az elemeket az összegzés előtt átalakíthatod. Egy opcionális argumentumot is elfogad az összeg kezdőértékének megadásához.

arr = [1, 2, 3]
arr.sum
# => 6

arr.sum(2) { |n| n * 2 }
# => 14

reduce

A reduce, amit más nyelvekben fold néven is ismernek, egy olyan metódus, amely egy összekapcsoló művelettel és egy kezdőértékkel az összes elemet összevonja a gyűjteményben. A reduce metódusnál van egy akkumulátor, amit átad a blokknak; az akkumulátor az előző iteráció eredménye. Ez egy rekurzív folyamattá válik, amely összevonja a gyűjtemény összes elemét.

arr = [1, 2, 3]
arr.reduce(0) do |acc, n|
  acc + n
end
# => 6

A reduce hasonlíthat a sum-hoz, de rugalmasabb, mert megadhatod az akkumulátor kezdőértékét és az összekapcsoló műveletet. A reduce segítségével megvalósíthatod a sum, count és más metódusokat.

Utasítások

A Spellbound Steel kártyajátékban a pakli kártyáin különféle karakterek, például warrior, mage és rogue, vagy különféle varázslatok, például fireball, ice storm és lightning bolt szerepelnek. A játékban kettő-négy játékos vesz részt, a cél pedig az, hogy legyőzd a többi játékost nagyobb erőszintű kártyák kijátszásával.

Szeretnéd átvenni az irányítást a játékban, ezért különféle metódusokat hozol létre a kártyák erőszintjének kiszámításához, rendezéséhez és összehasonlításához.

1. Találd meg a kártyát a pakliban

Nem vagy benne biztos, hogy egy kártya benne van-e a pakliban vagy sem. Ezért szeretnél egy metódust, ami megmondja, hol találod meg a pakliban az első olyan kártyát, amit keresel. Vagy ha a kártya nincs a pakliban, szeretnéd ezt is tudni.

Valósítsd meg a SpellboundSteel.find_card? metódust, amely egy String kártyákból álló Array-t és a megkeresendő String kártyát veszi át. A metódus adja vissza annak az első kártyának az indexét a pakliban, amely megegyezik a keresett kártyával. Ha a kártya nincs a pakliban, a metódus nil-t adjon vissza.

cards = ["Warrior", "Mage", "Rogue", "Fireball", "Ice Storm", "Lightning Bolt", "Mage"]
SpellboundSteel.find_card?(cards, "Mage")
# => 1

2. Írd nagybetűvel az összes karaktert

Hogy a kártyák könnyebben olvashatók legyenek, a kártyanevekben az összes karaktert nagybetűvel szeretnéd írni. Így könnyen látod a kártyaneveket, amikor kijátszod a kártyákat.

Valósítsd meg a SpellboundSteel.capitalize_cards metódust, amely egy String kártyákból álló Array-t veszi át, és a kártyákat úgy adja vissza, hogy minden karakterük nagybetűvel van írva.

cards = ["warrior", "mage", "rogue", "fireball", "ice storm", "lightning bolt"]
SpellboundSteel.capitalize_cards(cards)
# => ["Warrior", "Mage", "Rogue", "Fireball", "Ice Storm", "Lightning Bolt"]

3. Számítsd ki az összes kártya erőszintjét

A játékban fontos, hogy kiszámítsd az összes kártya erőszintjét. Az összes kártya ereje a következő táblázatban látható:

Card Type Power Level
Warrior 10
Mage 20
Rogue 30
Fireball 15
Ice Storm 25
Lightning Bolt 35

Valósítsd meg a SpellboundSteel.calculate_power_level metódust, amely egy String kártyákból álló Array-t veszi át, és visszaadja az összes kártya összesített erőszintjét.

cards = ["Warrior", "Mage", "Rogue", "Fireball", "Ice Storm", "Lightning Bolt"]
SpellboundSteel.calculate_power_level(cards)
# => 135

4. Dekódolj egy kártyát

A játékban vannak úgynevezett átkozott kártyák. Ezek rejtett kártyák, amelyeket csak az a játékos tud dekódolni, aki kijátszotta. A kártya dekódolásához a kártyanév minden második karakterét kell eltávolítanod. Így megkapod a kártya nevét.

Valósítsd meg a SpellboundSteel.decode_card metódust, amely egy String kártyát vesz át, és visszaadja a dekódolt kártyát.

SpellboundSteel.decode_card("Wbalrrrlimoqr")
# => "Warrior"
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Crystal Exercism

Készen állsz elkezdeni a(z) elvarázsolt-acél feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Crystal nyelvet 26 fogalom142 feladat segítségével, valódi emberi mentorálással, mindez ingyen.