Διαδρομές
/
Crystal
Crystal
/
Ασκήσεις
/
Μαγεμένο ατσάλι
Μαγεμένο ατσάλι

Μαγεμένο ατσάλι

Άσκηση εκμάθησης

Εισαγωγή

Στον προγραμματισμό, η επανάληψη αναφέρεται στη διαδικασία επανάληψης ενός μπλοκ κώδικα πολλές φορές. Αυτό μπορεί να γίνει χρησιμοποιώντας έννοιες όπως οι βρόχοι while και οι until βρόχοι. Μπορεί επίσης να γίνει με αναδρομή, δηλαδή μια συνάρτηση που καλεί τον εαυτό της.

Ωστόσο, τις περισσότερες φορές θέλεις να επαναλάβεις πάνω σε μια συλλογή στοιχείων, όπως έναν Array, ένα Range ή μια String. Τόσο η κλάση Array όσο και η κλάση Range στη Crystal περιλαμβάνουν το module Enumerable, το οποίο παρέχει έναν αριθμό μεθόδων για επανάληψη πάνω στα στοιχεία. Εν τω μεταξύ, η κλάση String έχει το δικό της σύνολο μεθόδων για επανάληψη πάνω στους χαρακτήρες.

Η Crystal επίσης δεν έχει καμία εντολή for όπως οι άλλες γλώσσες. Αντ' αυτού, έχει αρκετές μεθόδους που μπορούν να χρησιμοποιηθούν για επανάληψη.

Επανάληψη

Ο πιο συνηθισμένος τρόπος για να επαναλάβεις πάνω σε μια συλλογή είναι να χρησιμοποιήσεις τη μέθοδο each, η οποία περνάει κάθε στοιχείο της συλλογής σε ένα μπλοκ. Αυτό μπορεί να γίνει εύκολα με ένα Range. Ας πούμε ότι θέλεις να κάνεις βρόχο από το 1 έως το 3, μπορείς να χρησιμοποιήσεις τη μέθοδο each για να επαναλάβεις πάνω στο Range.

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

# Output:
# 1
# 2
# 3

Ακόμα πιο απλά, αν θέλεις απλώς να επαναλάβεις έναν αριθμό φορών, μπορείς να χρησιμοποιήσεις τη μέθοδο times, η οποία υπάρχει στην κλάση Int.

3.times do |n|
  puts n
end

# Output:
# 0
# 1
# 2

Επανάληψη πάνω σε μια String

Μια String είναι μια ακολουθία χαρακτήρων και δεν ανήκει στο module Enumerable, που σημαίνει ότι έχει το δικό της σύνολο μεθόδων για επανάληψη πάνω στους χαρακτήρες. Ο πιο συνηθισμένος τρόπος για να επαναλάβεις πάνω σε μια String είναι να χρησιμοποιήσεις τη μέθοδο each_char, η οποία περνάει κάθε χαρακτήρα της String σε ένα μπλοκ.

Note

Η μέθοδος each_char περνάει ένα αντικείμενο Char και όχι ένα αντικείμενο String στο μπλοκ.

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

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

Ένας άλλος τρόπος για να επαναλάβεις πάνω σε μια String είναι να χρησιμοποιήσεις τη μέθοδο each_line. Αυτή η μέθοδος χρησιμοποιείται κυρίως όταν διαβάζεις ένα αρχείο γραμμή προς γραμμή.

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

# Output:
# hello
# world

Επανάληψη πάνω σε ένα αντικείμενο που περιλαμβάνει το module Enumerable

Το module Enumerable παρέχει έναν αριθμό μεθόδων για επανάληψη πάνω στα στοιχεία μιας συλλογής. Οι συλλογές που περιλαμβάνουν το module Enumerable είναι οι Array, Range, Hash, Set και άλλες, οι οποίες θα καλυφθούν σε επόμενες έννοιες.

Ο πιο συνηθισμένος τρόπος για να επαναλάβεις πάνω σε έναν Array είναι να χρησιμοποιήσεις τη μέθοδο each, η οποία περνάει κάθε στοιχείο του Array σε ένα μπλοκ.

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

# Output:
# 5
# 2
# 3

Map

Η μέθοδος map είναι ένας άλλος τρόπος για να επαναλάβεις πάνω σε έναν Array, επιστρέφει έναν νέο Array που περιέχει τα αποτελέσματα της εφαρμογής του μπλοκ σε κάθε στοιχείο. Είναι παρόμοια με τη μέθοδο each, αλλά επιστρέφει έναν νέο Array με τα μετασχηματισμένα στοιχεία. Ο μετασχηματισμός είναι πολύ χρήσιμος όταν θέλεις να εφαρμόσεις μια συνάρτηση σε κάθε στοιχείο της συλλογής, κάτι που είναι μια συνηθισμένη λειτουργία.

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

new_arr
# => [2, 4, 6]

Με μια ροή ελέγχου όπως η if μπορείς επίσης να φιλτράρεις ποια στοιχεία θα μετασχηματίσεις.

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

new_arr
# => [2, 2, 6]

Με θέση

Μερικές φορές χρειάζεται να ξέρεις τη θέση του στοιχείου πάνω στο οποίο επαναλαμβάνεις, μπορείς να χρησιμοποιήσεις τη μέθοδο each_with_index ή τη μέθοδο map_with_index γι' αυτό. Περνάει κάθε στοιχείο και τη θέση του σε ένα μπλοκ, η μέθοδος δέχεται επίσης ένα προαιρετικό όρισμα για να ορίσεις τη θέση από την οποία ξεκινά.

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

Σημείωσε ότι η μέθοδος each_char_with_index είναι επίσης διαθέσιμη για αντικείμενα String.

sum

Η μέθοδος sum επιστρέφει το άθροισμα όλων των στοιχείων της συλλογής, δέχεται επίσης ένα προαιρετικό μπλοκ για να μετασχηματίσεις τα στοιχεία πριν τα αθροίσεις. Δέχεται επίσης ένα προαιρετικό όρισμα για να ορίσεις την αρχική τιμή του αθροίσματος.

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

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

reduce

Η reduce, ή fold όπως είναι γνωστή σε άλλες γλώσσες, είναι μια μέθοδος που, με μια μέθοδο συνδυασμού και μια αρχική τιμή, θα συνδυάσει όλα τα στοιχεία της συλλογής. Η μέθοδος reduce έχει έναν συσσωρευτή που περνάεται στο μπλοκ, ο συσσωρευτής είναι το αποτέλεσμα της προηγούμενης επανάληψης. Αυτό γίνεται μια αναδρομική διαδικασία που θα συνδυάσει όλα τα στοιχεία της συλλογής.

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

Η reduce μπορεί να φαίνεται παρόμοια με τη sum, αλλά η reduce είναι πιο ευέλικτη γιατί σου επιτρέπει να ορίσεις την αρχική τιμή του συσσωρευτή και τη μέθοδο συνδυασμού. Η reduce μπορεί να χρησιμοποιηθεί για να υλοποιήσεις τη sum, τη count και άλλες μεθόδους.

Οδηγίες

Στο παιχνίδι με κάρτες Spellbound Steel, έχεις μια τράπουλα με κάρτες που έχουν είτε διαφορετικούς χαρακτήρες, όπως warriors, mages και rogues, είτε διαφορετικά ξόρκια, όπως fireball, ice storm και lightning bolt. Στο παιχνίδι παίζουν δύο έως τέσσερις παίκτες και ο στόχος είναι να νικήσεις τους άλλους παίκτες παίζοντας κάρτες με υψηλότερα επίπεδα ισχύος.

Θέλεις να αποκτήσεις το πάνω χέρι στο παιχνίδι δημιουργώντας διάφορες μεθόδους για να υπολογίζεις, να ταξινομείς και να συγκρίνεις τα επίπεδα ισχύος των καρτών.

1. Βρες κάρτα στην τράπουλα

Δεν είσαι σίγουρος αν μια κάρτα βρίσκεται στην τράπουλα ή όχι. Γι' αυτό θέλεις μια μέθοδο που να σου λέει πού μπορείς να βρεις την πρώτη κάρτα στην τράπουλα του είδους που ψάχνεις. Ή, αν η κάρτα δεν βρίσκεται στην τράπουλα, θέλεις να το ξέρεις κι αυτό.

Υλοποίησε μια μέθοδο SpellboundSteel.find_card? που παίρνει έναν Array από String κάρτες και μια String κάρτα προς εύρεση. Η μέθοδος πρέπει να επιστρέφει τη θέση της πρώτης κάρτας στην τράπουλα που ταιριάζει με την κάρτα προς εύρεση. Αν η κάρτα δεν βρίσκεται στην τράπουλα, η μέθοδος πρέπει να επιστρέφει nil.

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

2. Κάνε όλους τους χαρακτήρες κεφαλαίους

Για να γίνουν οι κάρτες πιο ευανάγνωστες, θέλεις να μετατρέψεις όλους τους χαρακτήρες στα ονόματα των καρτών σε κεφαλαίους. Έτσι θα βλέπεις εύκολα τα ονόματα των καρτών όταν παίζεις τις κάρτες.

Υλοποίησε μια μέθοδο SpellboundSteel.capitalize_cards που παίρνει έναν Array από String κάρτες και επιστρέφει τις κάρτες με όλους τους χαρακτήρες κεφαλαίους.

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

3. Υπολόγισε το επίπεδο ισχύος όλων των καρτών

Στο παιχνίδι είναι σημαντικό να υπολογίζεις το επίπεδο ισχύος όλων των καρτών. Η ισχύς όλων των καρτών φαίνεται στον παρακάτω πίνακα:

Τύπος κάρτας Επίπεδο ισχύος
Warrior 10
Mage 20
Rogue 30
Fireball 15
Ice Storm 25
Lightning Bolt 35

Υλοποίησε μια μέθοδο SpellboundSteel.calculate_power_level που παίρνει έναν Array από String κάρτες και επιστρέφει το συνολικό επίπεδο ισχύος όλων των καρτών.

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

4. Αποκωδικοποίησε μια κάρτα

Στο παιχνίδι υπάρχουν οι λεγόμενες καταραμένες κάρτες. Αυτές οι κάρτες είναι κρυφές κάρτες που μπορεί να τις αποκωδικοποιήσει μόνο ο παίκτης που τις έπαιξε. Για να αποκωδικοποιήσεις την κάρτα, πρέπει να πάρεις κάθε δεύτερο χαρακτήρα στο όνομα της κάρτας και να τον αφαιρέσεις. Έτσι θα πάρεις το όνομα της κάρτας.

Υλοποίησε μια μέθοδο SpellboundSteel.decode_card που παίρνει μια String κάρτα και επιστρέφει την αποκωδικοποιημένη κάρτα.

SpellboundSteel.decode_card("Wbalrrrlimoqr")
# => "Warrior"
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Crystal Exercism

Έτοιμος να ξεκινήσεις την άσκηση Μαγεμένο ατσάλι;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Crystal με 26 έννοιες142 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.