Tracks
/
Crystal
Crystal
/
Übungen
/
Schachspiel
Schachspiel

Schachspiel

Lernübung

Einführung

Ranges stellen ein Intervall zwischen zwei Werten dar. Die häufigsten Typen, die Ranges unterstützen, sind Int, Char und String. Du kannst sie für vieles verwenden, zum Beispiel um schnell eine Sammlung zu erstellen, Strings zu zerschneiden, zu prüfen, ob ein Wert in einem Range liegt, und für Iterationen. Sie werden mit dem Range-Operator .. oder ... erstellt (inklusiv bzw. exklusiv).

1..5  # A range containing 1, 2, 3, 4, 5
1...5 # A range containing 1, 2, 3, 4

Der Grund für zwei Range-Operatoren ist, dass du Ranges erstellen kannst, die den Endwert einschließen oder ausschließen. Das ist zum Beispiel nützlich, wenn du mit nullbasierten Indizes arbeitest.

Ranges kannst du auch mit dem Range-Initialisierer erstellen.

Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Note

Wenn du in Crystal mit den Range-Operatoren .. oder ... einen Range erstellst und eine Methode auf dem Range aufrufen möchtest, musst du den Range in runde Klammern setzen. Sonst wird die Methode nämlich auf dem zweiten Argument des Range-Operators aufgerufen.

(1..5).size # => 5
1..5.size # => Error: undefined method 'size' for Int32

Teilstrings

Wenn du einen String zerschneiden möchtest, kannst du den Range-Operator verwenden, um einen Teilstring zu erhalten. Dazu erstellst du einen Range mit dem Start- und Endindex des Teilstrings.

"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"

Du kannst auch negative Indizes verwenden, um den Teilstring vom Ende des Strings zu erhalten.

"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"

Range-Methoden

Ranges haben eine Reihe von Methoden, mit denen du arbeiten kannst. Mit diesen Methoden kannst du zum Beispiel die Summe aller Werte im Range berechnen oder prüfen, ob der Range einen Wert enthält.

Methode Beschreibung Beispiel
sum Gibt die Summe aller Werte im Range zurück (1..5).sum # => 15
size Gibt die Größe des Ranges zurück (1..5).size # => 5
includes? Gibt true zurück, wenn der Range den gegebenen Wert enthält, sonst false (1..5).includes?(3) # => true

Endlose und anfangslose Ranges

Ein Range kann endlos und anfangslos sein. Bei einem endlosen oder anfangslosen Range ist der Start- oder Endwert nil. Beim Definieren des Ranges kannst du nil aber weglassen.

Anfangslose und endlose Ranges sind nützlich, wenn du zum Beispiel einen String von Anfang an oder bis zum Ende zerschneiden möchtest.

"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello"
Caution

Wenn ein endloser Range nicht auf eine Sammlung angewendet wird, kann er eine endlose Sequenz erzeugen. Sei also vorsichtig.

Char-Ranges

Chars können in Ranges verwendet werden und ermöglichen es dir, ein Intervall von Chars zwischen zwei Chars zu erhalten. Das ist zum Beispiel praktisch, wenn du das Alphabet erhalten möchtest.

'a'..'z' # A range containing ['a', 'b', 'c', ..., 'z']

String-Ranges

Strings können ebenfalls in Ranges verwendet werden. So kannst du ein Intervall von Strings zwischen zwei Strings erhalten. Das Verhalten unterscheidet sich jedoch leicht von dem von Char, wenn mehrere Zeichen in einem String-Range verwendet werden. Bei komplexeren String-Ranges kann das Verhalten verwirrend werden. Sei also vorsichtig.

("aa".."az") # A range containing ["aa", "ab", "ac", ..., "az"]

Anleitung

Als Schachfan möchtest du deine eigene Version des Spiels schreiben. Ja, es gibt online vielleicht schon viele Schach-Implementierungen, aber deine wird einzigartig sein!

Du beginnst damit, ein einfaches Bewegungssystem für die Figuren zu implementieren.

Das Schachspiel wird auf einem acht Felder breiten und acht Felder langen Brett gespielt. Die Felder werden durch einen Buchstaben und eine Zahl gekennzeichnet.

1. Definiere den Bereich der Reihen und Linien

Das Spiel muss die Reihen des Bretts speichern. Die Reihen sind die Zeilen des Bretts und von 1 bis 8 nummeriert.

Das Spiel muss auch die Linien des Bretts speichern. Die Linien sind die Spalten des Bretts und werden durch die Buchstaben A bis H gekennzeichnet.

Definiere die Konstanten Chess::RANKS und Chess::FILES, die den Bereich der Reihen bzw. Linien speichern.

Chess::RANKS
# => 1..8

Chess::FILES
# => 'A'..'H'

2. Prüfe, ob ein Feld gültig ist

Das Spiel muss prüfen, ob ein Feld gültig ist. Ein Feld ist gültig, wenn die Reihe und die Linie innerhalb der Bereiche der Reihen und Linien liegen.

Definiere die Methode Chess.valid_square?, die die Argumente rank (eine Ganzzahl für die Reihe) und file (ein Zeichen für die Linie) entgegennimmt. Die Methode sollte true zurückgeben, wenn die Reihe und die Linie innerhalb der Bereiche der Reihen und Linien liegen, und andernfalls false zurückgeben.

Chess.valid_square?(1, 'A')
# => true

3. Ermittle den Spitznamen des Spielers

Das Spiel muss den Spitznamen des Spielers ermitteln. Der Spitzname besteht aus den ersten zwei Zeichen des Vornamens und den letzten zwei Zeichen des Nachnamens des Spielers. Der Spitzname sollte in Großbuchstaben geschrieben werden.

Definiere die Methode Chess.nickname, die die Argumente first_name (ein String des Vornamens) und last_name (ein String des Nachnamens) entgegennimmt. Die Methode sollte den Spitznamen des Spielers als String in Großbuchstaben zurückgeben.

Chess.nickname("John", "Doe")
# => "JOOE"

4. Erstelle eine Zugnachricht

Das Spiel muss eine Nachricht für einen Zug erstellen, die angibt, welcher Spieler auf welches Feld gezogen ist. Die Nachricht sollte den Spitznamen des Spielers und das Feld, auf das gezogen wurde, verwenden. Das Spiel muss außerdem feststellen, ob der Zug gültig ist, indem es prüft, ob die Linie und die Reihe des Feldes innerhalb der Bereiche der Linien und Reihen liegen.

Wenn der Zug gültig ist, sollte die Nachricht lauten: "{nickname} moved to {square}" Wenn der Zug ungültig ist, sollte die Nachricht lauten: "{nickname} attempted to move to {square}, but that is not a valid square"

Definiere die Methode Chess.move_message, die die Argumente first_name (ein String des Vornamens), last_name (ein String des Nachnamens) und square (ein String des Feldes, auf das der Spieler gezogen ist) entgegennimmt. Die Methode sollte die Nachricht für den Zug als String zurückgeben.

Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Crystal Exercism

Bereit, mit Schachspiel zu starten?

Melde dich bei Exercism an, um Crystal mit 26 Konzepte142 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.