I have a 2D array:
我有一个2D数组:
winning moves = [
["a1","a2", "a3"],
["b1","b2", "b3"],
["c1","c2", "c3"],
["a1","b1", "c1"],
["a2","b2", "c2"],
["a3","b3", "c3"],
["a1","b2", "c3"],
["a3","b2", "c1"],
]
Then I have 2 other arrays of variable arbitrary lengths
然后我有另外两个可变任意长度的数组
Player X = ["c3", "b3", "a2", "a1", "c2" ]
Player Y = ["b1", "c1", "a3", "b2"]
In the above scenario, Y is a sequence that exists in wm.
在上面的场景中,Y是存在于wm中的序列。
I have the following way that works but is this the best way?
我有以下方式可行,但这是最好的方法吗?
wm.each_with_index do |arr, index|
puts "wm[#{index}]=#{arr}"
winner = nil
matchx = 0
matchy = 0
arr.each do|el|
if(X.include?(el))
matchx = matchx + 1
end
if(Y.include?(el))
matchy = matchy + 1
end
end
puts "matchx = #{matchx}"
puts "matchy = #{matchy}"
if(matchx == 3)
puts "winner = X"
end
if(matchy == 3)
puts "winner = Y"
end
end
OUTPUT of the above code is this:
上面代码的输出是这样的:
wm[0]=["a1", "a2", "a3"]
matchx = 2
matchy = 1
wm[1]=["b1", "b2", "b3"]
matchx = 1
matchy = 2
wm[2]=["c1", "c2", "c3"]
matchx = 2
matchy = 1
wm[3]=["a1", "b1", "c1"]
matchx = 1
matchy = 2
wm[4]=["a2", "b2", "c2"]
matchx = 2
matchy = 1
wm[5]=["a3", "b3", "c3"]
matchx = 2
matchy = 1
wm[6]=["a1", "b2", "c3"]
matchx = 2
matchy = 1
wm[7]=["a3", "b2", "c1"]
matchx = 0
matchy = 3
winner =Y
2 个解决方案
#1
0
If you are playing TicTacToe you can do the next which is more effective
如果你正在玩TicTacToe,你可以做下一个更有效的
For each row/column/diagonal(only 2) save 2 values: the number of mark each played did on that row/column/diagonal
对于每行/列/对角线(仅2)保存2个值:每个在该行/列/对角线上播放的标记数
Each move you update the values, if one of the value reach 3 , the player won the game. if player i play on (x,y) cell, the pseudo code code look like this
每次移动都会更新值,如果其中一个值达到3,则玩家赢得游戏。如果玩家在(x,y)单元格上播放,则伪代码代码如下所示
row[x][i]++
column[y][i]++
if (x == y) then diagonalA[i]++
if ((x + y) == 2) then diagonalB[i]++
if (row[x][i] == 3 || column[y][i] == 3 ||
diagonalA[i] == 3 || diagonalB[i] == 3)
then 'player i has won'
EDIT
编辑
update the code to handle both diagonal
更新代码以处理两个对角线
#2
0
I originally approached this using sets, but after seeing @vidaica's answer, it was obvious that using array intersections would be more straightforward. The latter is equivalent to using sets (with Set#subset?
, for example), but avoids the need to convert between arrays and sets.
我最初使用套装接近这个,但在看到@ vidaica的答案之后,很明显使用阵列交叉点会更直接。后者等同于使用集合(例如,使用Set#subset?),但是避免了在数组和集合之间进行转换的需要。
WM = [
["a1","a2", "a3"], ["b1","b2", "b3"], ["c1","c2", "c3"],
["a1","b1", "c1"], ["a2","b2", "c2"], ["a3","b3", "c3"],
["a1","b2", "c3"], ["a3","b2", "c1"],
]
def find_winner(x_moves, y_moves)
return "No winner" if x_moves.size < 3
3.upto(x_moves.size) do |i|
if (w = win?(x_moves.first(i)))
return "X wins with #{w}"
elsif i <= y_moves.size && (w = win?(y_moves.first(i)))
return "Y wins with #{w}"
end
end
return "No winner"
end
def win?(moves)
WM.find { |m| (m & moves).size == 3 }
end
puts find_winner([], [])
# => No winner
puts find_winner(["b1"], ["c3"])
# => No winner
puts find_winner(["b1", "c1", "a3", "b2"], ["c3", "b3", "a2", "a1"])
# => X wins with ["a3", "b2", "c1"]
puts find_winner(["b1", "c1", "a3", "b2"], ["c3", "b3", "a2"])
# => X wins with ["a3", "b2", "c1"]
puts find_winner(["b1", "a2", "a3", "c2", "c1"], ["c3", "b3", "a1", "b2"])
# => Y wins with ["a1", "b2", "c3"]
puts find_winner(["b1", "a2", "b2", "c3", "c1"], ["a1", "b3", "c2", "a3"])
# => No winner
#1
0
If you are playing TicTacToe you can do the next which is more effective
如果你正在玩TicTacToe,你可以做下一个更有效的
For each row/column/diagonal(only 2) save 2 values: the number of mark each played did on that row/column/diagonal
对于每行/列/对角线(仅2)保存2个值:每个在该行/列/对角线上播放的标记数
Each move you update the values, if one of the value reach 3 , the player won the game. if player i play on (x,y) cell, the pseudo code code look like this
每次移动都会更新值,如果其中一个值达到3,则玩家赢得游戏。如果玩家在(x,y)单元格上播放,则伪代码代码如下所示
row[x][i]++
column[y][i]++
if (x == y) then diagonalA[i]++
if ((x + y) == 2) then diagonalB[i]++
if (row[x][i] == 3 || column[y][i] == 3 ||
diagonalA[i] == 3 || diagonalB[i] == 3)
then 'player i has won'
EDIT
编辑
update the code to handle both diagonal
更新代码以处理两个对角线
#2
0
I originally approached this using sets, but after seeing @vidaica's answer, it was obvious that using array intersections would be more straightforward. The latter is equivalent to using sets (with Set#subset?
, for example), but avoids the need to convert between arrays and sets.
我最初使用套装接近这个,但在看到@ vidaica的答案之后,很明显使用阵列交叉点会更直接。后者等同于使用集合(例如,使用Set#subset?),但是避免了在数组和集合之间进行转换的需要。
WM = [
["a1","a2", "a3"], ["b1","b2", "b3"], ["c1","c2", "c3"],
["a1","b1", "c1"], ["a2","b2", "c2"], ["a3","b3", "c3"],
["a1","b2", "c3"], ["a3","b2", "c1"],
]
def find_winner(x_moves, y_moves)
return "No winner" if x_moves.size < 3
3.upto(x_moves.size) do |i|
if (w = win?(x_moves.first(i)))
return "X wins with #{w}"
elsif i <= y_moves.size && (w = win?(y_moves.first(i)))
return "Y wins with #{w}"
end
end
return "No winner"
end
def win?(moves)
WM.find { |m| (m & moves).size == 3 }
end
puts find_winner([], [])
# => No winner
puts find_winner(["b1"], ["c3"])
# => No winner
puts find_winner(["b1", "c1", "a3", "b2"], ["c3", "b3", "a2", "a1"])
# => X wins with ["a3", "b2", "c1"]
puts find_winner(["b1", "c1", "a3", "b2"], ["c3", "b3", "a2"])
# => X wins with ["a3", "b2", "c1"]
puts find_winner(["b1", "a2", "a3", "c2", "c1"], ["c3", "b3", "a1", "b2"])
# => Y wins with ["a1", "b2", "c3"]
puts find_winner(["b1", "a2", "b2", "c3", "c1"], ["a1", "b3", "c2", "a3"])
# => No winner