2017-06-18 115 views
-2

有人可以帮我弄清楚这个Ruby代码在做什么吗?Ruby代码在做什么?

def initialize(board = nil) 
    @board = board || Array.new(9, " ") 
end 

def won? 
    WIN_COMBINATIONS.detect do |combo| 
    position(combo[0]) == position(combo[1]) && position(combo[1]) == position(combo[2]) && position_taken?(combo[0]) 
    end 
end 

def position(location) 
    @board[location.to_i] 
end 

WIN_COMBINATIONS = [ 
    #horizontal 
    [0,1,2], 
    [3,4,5], 
    [6,7,8], 
    #vertical 
    [0,3,6], 
    [1,4,7], 
    [2,5,8], 
    #diagonal 
    [0,4,8], 
    [6,4,2] 
] 

我特别不明白以下几点:

  1. 如何won?方法进行操作?
  2. won?如何使用position方法?
+1

哪里是'won?'方法? –

+2

显然,代码是更大类的一部分,但是您只显示不能单独运行的摘录。为了获得帮助,你必须提供[mcve]。 – Stefan

+0

def won? WIN_COMBINATIONS.detect do | combo | (组合[0])==位置(组合[1])&&位置(组合[1])==位置(组合[2])&& position_taken?(组合[0]) 结束 结束 –

回答

2

该代码定义了用于井字棋的WIN_COMBINATIONS。通过将3个标记放入同一行,有三种水平取胜的方式。有三种方法可以通过将3个标记放入同一列来垂直取胜。有两种方法可以通过将对角线上的3个标记对角线来对角线取胜。

要确定游戏是否为won,您需要获取所有获胜组合并检查游戏是否为won,即combo中的任何一个都有三个类似的标记。

position在特定的position上返回board的值。 won通过传递combo的所需索引来调用position

1

won?方法的运行方式是什么?

它是通过所有可能的WIN_COMBINATIONS搜索当前@board,一个接一个,直到它开创一个成功的位置。

这就是detect的用途;从docs

通行证在枚举每个条目。返回第一个为 不为假。

因此,如果第一中奖位置不匹配(内侧detect块即条件false)它移动到下一个;它一找到匹配就停止查找(即条件是true)。

won?如何使用position方法?

position在给定location,其中location@board数组的索引返回@board值。

won?比较如果在获胜组合每location(即,在每combo值)具有相同的值,并检查值是否是不是空白(ⅰ假定position_taken?这是否检查)。

例如,考虑一个板具有以下位置:

x | o | o 
---+---+--- 
x | x | x 
---+---+--- 
o | | 

其转换为@board内容为:

["x", "o", "o", "x", "x", "x", "o", " " ," "] 
# 0 1 2 3 4 5 6 7 8 

第二行表示在阵列中的每个位置的索引;我把它仅仅作为参考。

所以,当won?被调用,它遍历WIN_COMBINATIONS,像这样:

# First iteration 
combo = [0,1,2] 

position(0) == position(1) && position(1) == position(2) && position_taken?(0) 

换算成:

@board[0] == @board[1] && @board[1] == @board[2] && position_taken?(0) 

然后到:

"x" == "o" && "o" == "o" && true 

这将自第一家公司以来,评估为false ndition为false(当使用&&运营商全部条件需要为true以便返回true)。

所以,既然是false,迭代继续说:

# Second iteration 
combo = [3,4,5] 

position(3) == position(4) && position(4) == position(5) && position_taken?(0) 

换算成:

@board[3] == @board[4] && @board[4] == @board[5] && position_taken?(3) 

然后到:

"x" == "x" && "x" == "x" && true 

这将计算为true全部 com binations是true,所以迭代将停止,并且win?也将评估为true

注意,as pointed outengineersmnkywon?会返回一个 truthy价值[3,4,5] (Array)true (TrueClass)

+1

好的解释虽然技术上'won?'会返回'[3,4,5]'('Array')的真值而不是'true'('TrueClass')。由于此方法以'?'结尾,提示布尔响应'Enumerable#any?'会比'Enumerable#detect'更好的选择,并且会做出相应的响应 – engineersmnky

+0

@engineersmnky你说得对,好的观察,'detect'返回匹配的元素或'nil'。我会在答案中添加一个注释。谢谢! – Gerry