學習軌道
/
Ruby
Ruby
/
練習
/
西洋棋對局
西洋棋對局

西洋棋對局

學習練習

簡介

範圍代表兩個值之間的區間。 最常支援範圍的型別是Integer和String。 它們可以用在許多地方,例如快速建立集合、切分字串、檢查某個值是否在範圍內,以及疊代。 建立範圍時使用範圍運算子..或...(分別代表包含與不包含結尾值)。

1..5  # => 1..5
1...5 # => 1...5

(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]

之所以有兩個範圍運算子,是為了讓你能建立包含或不包含結尾值的範圍。這在處理從零開始的索引時會很有用。

範圍也可以用Range建構子new來建立。

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

在 Ruby 中用範圍運算子..或...建立範圍,並想對這個範圍呼叫方法時,需要把範圍用括號包起來。 否則,方法會被呼叫在範圍運算子的第二個引數上。

(1..5).sum # => 15
1..5.sum # => Error: undefined method `sum' for 5:Integer (NoMethodError)

取得子字串

想切分字串時,可以用範圍運算子取得子字串。 也就是建立一個包含子字串開始與結束索引的範圍。

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

你也可以使用負索引,從字串尾端取得子字串。

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

範圍方法

範圍有一些方法可以用來操作它們。 例如,這些方法可以用來取得範圍中所有值的總和,或檢查範圍是否包含某個值。

Method Description Example
sum 回傳範圍中所有值的總和 (1..5).sum # => 15
size 回傳範圍的大小 (1..5).size # => 5
include? 如果範圍包含給定的值就回傳true,否則回傳false (1..5).include?(3) # => true

無限範圍與無起始範圍

範圍可以是無限的,也可以是沒有起始值的。 無限範圍或無起始範圍的起始值或結束值會是nil,但定義範圍時可以省略nil。

使用無起始與無限範圍很實用,例如你想從字串開頭或結尾切分字串時。

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

如果沒有搭配集合使用,無限範圍可能會造成無盡的序列,使用時請小心。

字串範圍

字串也可以用在範圍中,讓你取得兩個字串之間的字串區間。 使用某些字串時,它的行為可能會有點出乎意料,所以請小心使用。

("aa".."az").to_a # => ["aa", "ab", "ac", ..., "az"]

說明

身為一位西洋棋愛好者,你會想寫出屬於自己的版本。沒錯,網路上或許已經有許多現成的西洋棋實作,但你的版本可是獨一無二的喔!

你先從實作棋子的基本移動系統開始。

這盤西洋棋會在一個寬 8 格、長 8 格的棋盤上進行。每個格子都由一個字母和一個數字來標示。

1. 定義橫列與縱列的範圍

遊戲需要儲存棋盤的橫列。橫列是棋盤上橫向的列,編號從 1 到 8。

遊戲也需要儲存棋盤的縱列。縱列是棋盤上縱向的行,以字母 A 到 H 標示。

定義Chess::RANKS和Chess::FILES這兩個常數,分別儲存橫列與縱列的範圍。

Chess::RANKS
# => 1..8

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

2. 檢查格子是否合法

遊戲需要檢查某個格子是否合法。只要格子的橫列與縱列都落在橫列與縱列的範圍內,這個格子就是合法的。

定義Chess.valid_square?方法,它接受引數rank(存有橫列的整數)與file(存有縱列的字元)。若橫列與縱列都在橫列與縱列的範圍內,這個方法應該回傳true,否則回傳false。

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

3. 取得玩家的暱稱

遊戲需要取得玩家的暱稱。暱稱由玩家名字的前 2 個字元和姓氏的後 2 個字元組成。暱稱應該全部轉為大寫。

定義Chess.nickname方法,它接受引數first_name(存有玩家名字的字串)與last_name(存有玩家姓氏的字串)。這個方法應該以大寫字串回傳玩家的暱稱。

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

4. 建立移動訊息

遊戲需要為每一步移動建立訊息,說明是哪位玩家移動到哪個格子。訊息應該使用玩家的暱稱,以及玩家移動到的格子。遊戲還需要判斷這步移動是否合法,方式是檢查格子的縱列與橫列是否落在縱列與橫列的範圍內。

如果移動合法,訊息應該是:"{nickname} moved to {square}" 如果移動不合法,訊息應該是:"{nickname} attempted to move to {square}, but that is not a valid square"

定義Chess.move_message方法,它接受引數first_name(存有玩家名字的字串)、last_name(存有玩家姓氏的字串),以及square(存有玩家移動到的格子的字串)。這個方法應該以字串回傳這步移動的訊息。

Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Ruby Exercism

準備好開始 西洋棋對局 了嗎?

註冊 Exercism,透過 21 個概念121 個練習 和真人引導來學習並精通 Ruby,全部免費。