I have this array of arrays:
WIN_COMBINATIONS = [
[0,1,2],
[3,4,5],
[6,7,8],
[0,3,6],
[0,4,8],
[6,4,2],
[1,4,7],
[2,5,8]
]
and I am defining this method:
def won?(board)
for x in WIN_COMBINATIONS
win_index_1 = x[0]
win_index_2 = x[1]
win_index_3 = x[2]
p1 = board[win_index_1]
p2 = board[win_index_2]
p3 = board[win_index_3]
if p1 == 'X' && p2 == 'X' && p3 == 'X'
return x
else
false
end
end
end
and when
board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
The won?
method returns every item in WIN_COMBINATIONS instead of false. I have no idea why and I would appreciate it if someone would please help.
In ruby
each block
, returns something even if you don't explicitly return a value, in your case the for block
is returning the collection over you are iterating I think that your logic is correct but you need to make a small change, something like:
def won?(board)
for x in WIN_COMBINATIONS
win_index_1 = x[0]
win_index_2 = x[1]
win_index_3 = x[2]
p1 = board[win_index_1]
p2 = board[win_index_2]
p3 = board[win_index_3]
return x if p1 == "X" && p2 == "X" && p3 == "X"
end
false
end
The code above will return x
if any of the sequences are valid, false in any other case (although you should follow the convention and return true or false
if you are using the signature ?
, other option is remove the ?
and return nil
instead of false). Hope this helps!
Every block of code returns a value even if there is no explicit return
keyword. for
loop returns itself. With board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
you never hit the return x
statement and you get WIN_COMBINATIONS
back. If you replace return false
with return []
, it will allow you to avoid 'expected a collection that can be converted to an array with #to_ary or #to_a, but got false'
. But Ruby has a bunch of nice methods to work with arrays .
By convention, methods that end with ?
should return a boolean value. Your method returns an array when the if
statement is true. In your case, I'd rename the method and use the find
method to iterate through WIN_COMBINATIONS
:
def find_win_combination(board)
# You can use decomposition as in the next example `do |wi_0, wi_1, wi_2|`
win_combination = WIN_COMBINATIONS.find do |combination|
win_index_0 = combination[0]
win_index_1 = combination[1]
win_index_2 = combination[2]
# If it's true the find method will return the win combination
board[win_index_0] == "X" && board[win_index_1] == "X" && board[win_index_2] == "X"
end
# return an empty array if win_combination is not found
win_combination || []
end
board = [' ', ' ', ' ', 'X', 'X', 'X', ' ', ' ', ' ']
> find_win_combination(board)
=> [3, 4, 5]
board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
> find_win_combination(board)
=> []
If you need won?
method to return a boolean method, just use any?
method on WIN_COMBINATIONS
. The result of any? will be returned as a result of
any? will be returned as a result of
won`?
def won?(board)
# Here is a decomposition of each item of `WIN_COMBINATIONS` into three variables
WIN_COMBINATIONS.any? do |wi_0, wi_1, wi_2|
board[wi_0] == "X" && board[wi_1] == "X" && board[wi_2] == "X"
end
end
board = [' ', ' ', ' ', 'X', 'X', 'X', ' ', ' ', ' ']
> won?(board)
=> true
board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
> won?(board)
=> false
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.