这个Ruby代码在做什么?

时间:2017-06-18 09:44:29

标签: 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方法?

2 个答案:

答案 0 :(得分:2)

此代码为tic-tac-toe定义WIN_COMBINATIONS。通过将3个标记放入同一行,有三种方法可以水平获胜。通过将3个标记放入同一列,有三种方法可以垂直获胜。通过将3个标记放在同一对角线上,有两种方式可以对角线获胜。

要确定游戏是否为won,您需要获取所有获胜组合并检查游戏是否为won,即任何{{1}都有三个相似的标记}}第

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

答案 1 :(得分:1)

  

won?方法如何运作?

通过所有可能的@board逐个搜索当前WIN_COMBINATIONS,直到找到获胜位置。

那是detect的用途;来自docs

  

将枚举中的每个条目传递给。返回第一个   不是假的。

因此,如果第一个获胜位置不匹配(即detect 中的条件为false),则移动到下一个;它一找到匹配就停止查看(即条件为true)。

  

won?如何使用position方法?

position返回给定@board的{​​{1}}值,其中locationlocation数组中的索引。

@board比较获胜组合中的每个won?(即location中的每个值)是否具有相同的值,并检查该值是否为空(我假设{ {1}}进行检查)。

例如,考虑一个具有以下职位的董事会:

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运算符所有条件需要为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也将评估为true < SUP> 1

1 请注意,as pointed out engineersmnkywin?将返回<{em> truthy值 {{1}不是true