Ruby的新功能,请原谅可怜的代码。我想遍历多维数组WIN_COMBINATIONS
,并检查至少一个数组的所有元素是否等于'X'
或全部等于'O'
。如果是这样,则返回匹配的数组。这是通过won?
函数完成的,但似乎只返回了整个多维数组。任何帮助,将不胜感激。
class TicTacToe
WIN_COMBINATIONS = [
[0,1,2], # top_row
[3,4,5], # middle_row
[6,7,8], # bottom_row
[0,3,6], # left_column
[1,4,7], # center_column
[2,5,8], # right_column
[0,4,8], # left_diagonal
[6,4,2] # right_diagonal
]
def initialize
@board = Array.new(9, " ")
end
def display_board
puts " #{@board[0]} | #{@board[1]} | #{@board[2]} "
puts "-----------"
puts " #{@board[3]} | #{@board[4]} | #{@board[5]} "
puts "-----------"
puts " #{@board[6]} | #{@board[7]} | #{@board[8]} "
end
def input_to_index(board_position)
user_input = board_position.to_i
user_input - 1
end
def move(board_index, player_token = 'X')
@board[board_index] = player_token
end
def position_taken?(board_position)
if @board[board_position] == ' '
false
else
true
end
end
def valid_move?(board_position)
if board_position >= 0 and board_position <= 8
if @board[board_position] == ' '
true
end
else
false
end
end
def current_player
turn_count % 2 == 0 ? "X" : "O"
end
def turn_count
@board.count{|token| token == "X" || token == "O"}
end
def turn
puts "Select your move (1-9)\n"
move = gets.chomp
move_index = input_to_index(move)
if valid_move?(move_index)
token = current_player
move(move_index, token)
display_board
else
puts "Select your move (1-9)\n"
move = gets.chomp
end
end
def won?
WIN_COMBINATIONS.each do |combinations|
if combinations.all? {|combination| combination == 'X' or combination == 'O'}
combinations
else
false
end
end
end
def draw?
if full? and !won?
true
elsif won?
false
else
false
end
end
def over?
end
def winner
end
def play
end
end
[...]似乎只返回整个多维数组。
您尝试的解决方案有几个问题:
WIN_COMBINATIONS
是一个索引数组。这些索引是数字,因此它们永远不会是'X'
或'O'
。您必须检查其对应值是'X'
还是'O'
。
or
是用于do_this or fail
场景的控制流运算符。 布尔值“或”运算符为||
。使用or
代替||
might可以工作,但由于precedence较低,可能会产生意想不到的结果。您几乎总是想要||
。
表达式array.all? { |element| element == 'X' || element == 'O' }
检查所有元素是任一个>] 'X'
还是'O'
。 true
为['X','O','O']
,false
为['X',' ','O']
。那是因为您将条件放在块中。您要检查的元素是全部为'X'
还是全部为'O'
:
array.all?('X') || array.all?('O')
您的方法的返回值是WIN_COMBINATIONS.each { ... }
的结果,并且Array#each
始终返回数组本身,即Array#each
。要获取与条件匹配的第一个元素,请使用WIN_COMBINATIONS
。
让我们将所有这些应用于您的代码。鉴于此板:
find
您可以通过以下方式获得第一个匹配的组合:
find
@board = %w[ X - O O X - - - X ]
返回相应索引的值(WIN_COMBINATIONS.find do |indices| values = @board.values_at(*indices) values.all?('X') || values.all?('O') end #=> [0, 4, 8]
将values_at
数组转换为参数列表,因此values_at
变为*
)。然后,该块的第二行检查这些值是全部为indices
还是全部为values_at(*[0,1,2])
。一旦计算结果为values_at(0,1,2)
,循环就会中断,'X'
返回找到的元素。 (如果没有匹配项,则为'O'
)
这是解决问题的方法: