这是一个tic tac toe游戏。我有一个包含九个字符串元素的数组board
,以及一个位置组合来自WIN_COMBINATIONS
的嵌套数组board
:
board = ["X", "X", "X", " ", " ", " ", " ", " ", " "]
WIN_COMBINATIONS = [
[0, 1, 2],
[0, 3, 6],
[0, 4, 8],
[3, 4, 5],
[6, 7, 8],
[6, 4, 2],
[1, 4, 7],
[2, 5, 8]
]
如何使用board
中的组合从"X"
全部"O"
或全部WIN_COMBINATIONS
中选择数组合?
例如 一个不同的板,上面的X在右对角线上获胜。
board = ["X", "O", "X", "O", "X", "O", "X", "X", "O"]
# X | O | X
# ---+---+---
# O | X | O
# ---+---+---
# X | X | O
won?(board) #=> [2,4,6]
答案 0 :(得分:5)
ndn's answer的轻微变化:
board = %w(X O X
O X O
X X O)
WIN_COMBINATIONS.select { |c| board.values_at(*c).join =~ /XXX|OOO/ }
#=> [[6, 4, 2]]
说明:
select
返回块返回true
的所有元素。
values_at
返回指定索引处的值:
board.values_at(*[0, 1, 2])
#=> ["X", "O", "X"]
*
将数组转换为参数列表,因此上面的内容变为values_at(0, 1, 2)
join
返回带有连接元素的字符串:
["X", "O", "X"].join
#=> "XOX"
=~
检查字符串是否与regular expression /XXX|OOO/
匹配,即XXX
或OOO
如果您只想检索第一个获胜组合,可以将select
替换为find
。
答案 1 :(得分:2)
编辑代码包含了Stefan的建议。
这样做一次:
WIN_COMBINATIONS.each(&:sort!)
然后,
h = board.each_index.group_by{|i| board[i]}
# => {"X"=>[0, 1, 2], " "=>[3, 4, 5, 6, 7, 8]}
WIN_COMBINATIONS.find{|a| (h["X"] & a) == a or (h["O"] & a) == a}
# => [0, 1, 2]
答案 2 :(得分:1)
WIN_COMBINATIONS.find do |combination|
values_at_positions = board.values_at(*combination).uniq
values_at_positions.size == 1 and ['X', 'O'].include?(*values_at_positions)
end # => [0, 1, 2]
答案 3 :(得分:1)
出于好奇(稍微更新了@Stefan的回答):
WIN_COMBINATIONS.index do |wc|
board.values_at(*wc).join =~ /(?<l>\w)\k<l>\k<l>/
# or, as suggested by @Stefan: board.values_at(*wc).join =~ /(\w)\1\1/
end
#⇒ 5
这里我们将这些组合与三个相同的符号相匹配,这可能是对井字游戏最正确的解释。
答案 4 :(得分:0)
你可以试试这个。
def won?(board)
xpos = []
opos = []
who_won = nil;
board.each_with_index{|x,i| xpos << i if x == "X" }
board.each_with_index{|x,i| xpos << i if x == "O" }
WIN_COMBINATIONS.each do |com|
temp = com & xpos
who_won = "X" if temp == com
temp = com & opos
who_won = "O" if temp == com
break if !who_won.nil?
end
return who_won
end
won?(board) #=> X if x wins, O if O wins. nil if no body wins.
未经测试但应该有效。