我正在尝试制作 "Game of Set" 但不知道如何正确检查集合
I am trying to make "Game of Set" but don't know how to correctly check the set
嗨,我刚开始学习编码,ruby 是我的第一语言。我正在尝试制作一款名为“Game of Set”的游戏,可以在 here or wikipedia
中查看规则
我能够获取用户卡片并将它们输入不同的数组。然而,我花了很多时间试图弄清楚如何验证集合。我试图按索引比较数组,但结果不是我想要的。
示例:
first = ['two', 'purple', 'stripe', 'diamond']
second = ['one', 'purple', 'solid', 'diamond']
third = ['three', 'purple', 'empty', 'diamond']
这应该是正确的,因为都是紫色的,都是钻石的,不同的数字和不同的过滤器。
first = ['one', 'green', 'stripe', 'squiggle']
second = ['one', 'purple', 'solid', 'diamond']
third = ['two', 'green', 'empty', 'oval']
这是错误的,因为两个数字相同,一个不相同,颜色也类似。
这就是我要实现的set游戏here
请帮忙谢谢!
在这个游戏中,一个__set被定义为:
Several games can be played with these cards, all involving the concept of a set. A set consists of three cards satisfying all of these conditions:
- They all have the same number or have three different numbers.
- They all have the same shape or have three different shapes.
- They all have the same shading or have three different shadings.
- They all have the same color or have three different colors.
-- Wikipedia
可以用 one-liner:
来检查
first = ['two', 'purple', 'stripe', 'diamond']
second = ['one', 'purple', 'solid', 'diamond']
third = ['three', 'purple', 'empty', 'diamond']
first.zip(second, third).all? { |array| [1,3].include?(array.uniq.length) }
#=> true
first = ['one', 'green', 'stripe', 'squiggle']
second = ['one', 'purple', 'solid', 'diamond']
third = ['two', 'green', 'empty', 'oval']
first.zip(second, third).all? { |array| [1,3].include?(array.uniq.length) }
#=> false
具体是如何工作的?
first
.zip(second, third) #=> [["two", "one", "three"], ["purple", "purple", "purple"], ["stripe", "solid", "empty"], ["diamond", "diamond", "diamond"]]
.all? { |array|
# do all nested arrays comply with the set conditions and
# contain only the same element or three different ones?
[1,3].include?(array.uniq.length)
}
我们得到
first = ['two', 'purple', 'stripe', 'diamond']
second = ['one', 'purple', 'solid', 'diamond']
third = ['three', 'purple', 'empty', 'diamond']
让
arr = [first, second, third]
#=> [["two", "purple", "stripe", "diamond"],
# ["one", "purple", "solid", "diamond"],
# ["three", "purple", "empty", "diamond"]]
我们希望检查 arr
的每个“列”是否包含每个“行”的相同字符串或每行中的不同字符串。
Ruby 没有数组“列”和“行”的概念,只有元素。 arr
有三个元素,即数组first
、second
和third
。但是,我们可以将方法 Array#transpose1 发送到对象 arr
以获得我们可以使用的东西:
a = arr.transpose
#=> [["two", "one", "three"],
# ["purple", "purple", "purple"],
# ["stripe", "solid", "empty"],
# ["diamond", "diamond", "diamond"]]
我们现在只需要看看 a
的四个元素是否都通过了测试。
首先,我们想知道是否
b = a[1]
#=> ["purple", "purple", "purple"]
满足要求属性。一种方便的方法是使用方法 Array#uniq:
计算数组 b
的唯一元素
c = b.uniq
#=> ["purple"]
如果c
中的元素个数等于1
或b
中的元素个数b.size #=> 3
,则b
满足要求.由于c.size #=> 1
,c
满足要求。
注意 b.size
与 arr.size
相同。
我们可以将其放在一个方法中:
def valid?(arr)
nbr_elements = arr.size
a = arr.transpose
a.all? do |b|
sz = b.uniq.size
sz == 1 || sz == nbr_elements
end
end
我们来试试吧。
valid?(arr)
#=> true
为了说明 valid?
执行的计算,我将在用 puts
语句对方法加盐后再次 运行 它。
def valid?(arr)
nbr_elements = arr.size
puts "nbr_elements = #{nbr_elements}"
a = arr.transpose
a.all? do |b|
sz = b.uniq.size
puts "b = #{b}"
puts " sz = #{sz}"
puts " #{sz == 1} || #{sz == nbr_elements} => #{sz == 1 || sz == nbr_elements}"
sz == 1 || sz == nbr_elements
end
end
valid?(arr)
#=> true
nbr_elements = 3
b = ["two", "one", "three"]
sz = 3
false || true => true
b = ["purple", "purple", "purple"]
sz = 1
true || false => true
b = ["stripe", "solid", "empty"]
sz = 3
false || true => true
b = ["diamond", "diamond", "diamond"]
sz = 1
true || false => true
我们也试试第二个例子。
arr = [["one", "green", "stripe", "squiggle"],
["one", "purple", "solid", "diamond" ],
["two", "green", "empty", "oval" ]]
valid?(arr)
#=> false
nbr_elements = 3
b = ["one", "one", "two"]
sz = 2
false || false => false
实际上我们可能不会有语句 a = arr.transpose
而是 chain arr.transpose
to all?
:
def valid?(arr)
nbr_elements = arr.size
arr.transpose.all? do |b|
sz = b.uniq.size
sz.zero? || sz == nbr_elements
end
end
1 当一个数组的所有元素都是元素个数相同的数组时,方法transpose
和Array#zip可以互换使用more-or-less。 @spickerman 在他的回答中使用了 zip
。
2 Enumerable
是一个包含实例方法的模块。任何 包含 模块的 class(现在不用担心细节)都使用了 Enumerable
的所有方法,或多或少就像它们一样已在 class.
中定义
嗨,我刚开始学习编码,ruby 是我的第一语言。我正在尝试制作一款名为“Game of Set”的游戏,可以在 here or wikipedia
中查看规则我能够获取用户卡片并将它们输入不同的数组。然而,我花了很多时间试图弄清楚如何验证集合。我试图按索引比较数组,但结果不是我想要的。 示例:
first = ['two', 'purple', 'stripe', 'diamond']
second = ['one', 'purple', 'solid', 'diamond']
third = ['three', 'purple', 'empty', 'diamond']
这应该是正确的,因为都是紫色的,都是钻石的,不同的数字和不同的过滤器。
first = ['one', 'green', 'stripe', 'squiggle']
second = ['one', 'purple', 'solid', 'diamond']
third = ['two', 'green', 'empty', 'oval']
这是错误的,因为两个数字相同,一个不相同,颜色也类似。
这就是我要实现的set游戏here
请帮忙谢谢!
在这个游戏中,一个__set被定义为:
Several games can be played with these cards, all involving the concept of a set. A set consists of three cards satisfying all of these conditions:
- They all have the same number or have three different numbers.
- They all have the same shape or have three different shapes.
- They all have the same shading or have three different shadings.
- They all have the same color or have three different colors.
-- Wikipedia
可以用 one-liner:
来检查first = ['two', 'purple', 'stripe', 'diamond']
second = ['one', 'purple', 'solid', 'diamond']
third = ['three', 'purple', 'empty', 'diamond']
first.zip(second, third).all? { |array| [1,3].include?(array.uniq.length) }
#=> true
first = ['one', 'green', 'stripe', 'squiggle']
second = ['one', 'purple', 'solid', 'diamond']
third = ['two', 'green', 'empty', 'oval']
first.zip(second, third).all? { |array| [1,3].include?(array.uniq.length) }
#=> false
具体是如何工作的?
first
.zip(second, third) #=> [["two", "one", "three"], ["purple", "purple", "purple"], ["stripe", "solid", "empty"], ["diamond", "diamond", "diamond"]]
.all? { |array|
# do all nested arrays comply with the set conditions and
# contain only the same element or three different ones?
[1,3].include?(array.uniq.length)
}
我们得到
first = ['two', 'purple', 'stripe', 'diamond']
second = ['one', 'purple', 'solid', 'diamond']
third = ['three', 'purple', 'empty', 'diamond']
让
arr = [first, second, third]
#=> [["two", "purple", "stripe", "diamond"],
# ["one", "purple", "solid", "diamond"],
# ["three", "purple", "empty", "diamond"]]
我们希望检查 arr
的每个“列”是否包含每个“行”的相同字符串或每行中的不同字符串。
Ruby 没有数组“列”和“行”的概念,只有元素。 arr
有三个元素,即数组first
、second
和third
。但是,我们可以将方法 Array#transpose1 发送到对象 arr
以获得我们可以使用的东西:
a = arr.transpose
#=> [["two", "one", "three"],
# ["purple", "purple", "purple"],
# ["stripe", "solid", "empty"],
# ["diamond", "diamond", "diamond"]]
我们现在只需要看看 a
的四个元素是否都通过了测试。
首先,我们想知道是否
b = a[1]
#=> ["purple", "purple", "purple"]
满足要求属性。一种方便的方法是使用方法 Array#uniq:
计算数组b
的唯一元素
c = b.uniq
#=> ["purple"]
如果c
中的元素个数等于1
或b
中的元素个数b.size #=> 3
,则b
满足要求.由于c.size #=> 1
,c
满足要求。
注意 b.size
与 arr.size
相同。
我们可以将其放在一个方法中:
def valid?(arr)
nbr_elements = arr.size
a = arr.transpose
a.all? do |b|
sz = b.uniq.size
sz == 1 || sz == nbr_elements
end
end
我们来试试吧。
valid?(arr)
#=> true
为了说明 valid?
执行的计算,我将在用 puts
语句对方法加盐后再次 运行 它。
def valid?(arr)
nbr_elements = arr.size
puts "nbr_elements = #{nbr_elements}"
a = arr.transpose
a.all? do |b|
sz = b.uniq.size
puts "b = #{b}"
puts " sz = #{sz}"
puts " #{sz == 1} || #{sz == nbr_elements} => #{sz == 1 || sz == nbr_elements}"
sz == 1 || sz == nbr_elements
end
end
valid?(arr)
#=> true
nbr_elements = 3
b = ["two", "one", "three"]
sz = 3
false || true => true
b = ["purple", "purple", "purple"]
sz = 1
true || false => true
b = ["stripe", "solid", "empty"]
sz = 3
false || true => true
b = ["diamond", "diamond", "diamond"]
sz = 1
true || false => true
我们也试试第二个例子。
arr = [["one", "green", "stripe", "squiggle"],
["one", "purple", "solid", "diamond" ],
["two", "green", "empty", "oval" ]]
valid?(arr)
#=> false
nbr_elements = 3
b = ["one", "one", "two"]
sz = 2
false || false => false
实际上我们可能不会有语句 a = arr.transpose
而是 chain arr.transpose
to all?
:
def valid?(arr)
nbr_elements = arr.size
arr.transpose.all? do |b|
sz = b.uniq.size
sz.zero? || sz == nbr_elements
end
end
1 当一个数组的所有元素都是元素个数相同的数组时,方法transpose
和Array#zip可以互换使用more-or-less。 @spickerman 在他的回答中使用了 zip
。
2 Enumerable
是一个包含实例方法的模块。任何 包含 模块的 class(现在不用担心细节)都使用了 Enumerable
的所有方法,或多或少就像它们一样已在 class.