2017-06-18 111 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