轨道
/
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. 定义 rank 和 file 的范围

程序需要存储棋盘的 rank。 rank 是棋盘的行,编号从 1 到 8。

程序还需要存储棋盘的 file。 file 是棋盘的列,用字母 A 到 H 表示。

定义Chess::RANKS和Chess::FILES常量,分别存储 rank 和 file 的范围。

Chess::RANKS
# => 1..8

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

2. 检查格子是否有效

程序需要检查一个格子是否有效。 如果 rank 和 file 都在各自的范围之内,这个格子就是有效的。

定义Chess.valid_square?方法,它接受两个实参:rank存放表示 rank 的整数,file存放表示 file 的字符。 如果 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. 创建走棋消息

程序需要为一步走棋创建消息,说明哪位玩家移动到了哪个格子。 消息要用到玩家的昵称和他们移动到的格子。 程序还要判断这步棋是否有效,方法是检查该格子的 file 和 rank 是否在各自的范围之内。

如果这步棋有效,消息应当是:"{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,全部免费。