我正在测试Ruby Connect 4游戏中的对角线胜利。我一直在使用硬编码的2D数组进行测试:
grid_array = [
["B", ".", ".", ".", ".", ".", ".", "."],
[".", "B", ".", ".", ".", ".", ".", "."],
[".", ".", "B", ".", ".", ".", ".", "."],
[".", ".", ".", "B", ".", ".", ".", "."],
[".", ".", ".", "X", "M", ".", ".", "."],
[".", ".", ".", ".", "X", "M", ".", "."],
[".", ".", ".", ".", ".", "X", "M", "."],
[".", ".", ".", ".", ".", ".", "X", "M"]
]
这个方法的内部循环可以正确地工作(正确地识别'M'
或'B'
分别是获胜者,但是当我试图将对角线检查跨列或向上移动时,外部循环会将'X'
作为获胜值。
def nw_diagonal_win (playing_board)
row = 7
while row < playing_board.size && row >= 0
row = 7
column = 7
piece_count = 0
while (row < playing_board.size && column < playing_board[row].size && column >= 0)
if playing_board[row][column] == 'M'
piece_count += 1
if piece_count == 4
puts "Player is the winner in a diagonal!"
end
puts piece_count.inspect
else
piece_count = 0
puts "No winner."
end
row += 1
column += 1
end
row -= 1
end
end
编辑添加:一个“赢家”在连接4套4个相邻的作品(水平,垂直,或对角线)。在我的游戏中,这由'X'
和'0'
表示。片段从网格中某列的顶部“放下”,并落到该列中最底部的可用空间。棋子可以堆叠在一列中,但不能“浮动”在板的中间。对角线可以从左上到右下或从右上到左下。只有棋子在格子内不间断(没有环绕),才算赢。
想象一个更大版本的井字游戏,其中必须首先在最下面的一行进行移动,然后可以在上面的几行进行移动,像盒子一样堆叠。四个在一排(水平,垂直,或对角线\ /)获胜。
根据Steve的回答建议,如下:
def top_left_diagonal (playing_board, player_piece)
row = 0
while row < playing_board.size - 3
piece_count = 0
column = 0
while column < playing_board[row].size - 3 && playing_board[row][column] == player_piece
if (playing_board[row][column] == playing_board[row + piece_count][column + piece_count])
piece_count += 1
else
piece_count = 0
end
column += 1
end
if piece_count == 4
puts "Diagonal winner!"
end
row += 1
end
end
4条答案
按热度按时间kmpatx3s1#
假设我们有
的确,这是只有6x6,但解决方案没有什么不同。
首先,由于数组很小,我们不必担心计算效率,因此我们可以专注于代码效率。
让我们首先检查是否有四个在一行中的每一行。
检查行
如果一行中有四个
w
,则此方法返回w
;如果一行中有四个b
,则返回b
;否则返回nil
。对于
arr = grid
,我们发现没有一行包含四个'b'
或'w'
。请注意,此方法不要求
arr.size == grid.size
或arr
的所有元素具有相同的大小。它只是检查一行中是否有四个'w'
或四个'b'
。这将在以后有意义。例如,传递给块的
arr
的最后一个元素如下所示。然后我们计算
和
enum1
可以被认为是一个 compound 枚举器,尽管Ruby没有这样定义。请参见Enumerable#each_cons和Enumerable#find。我们可以将这个枚举数转换为数组,以查看将传递给块的元素。
第一个元素被传递给块,并进行以下计算。
因此,我们不需要计算
a.first != '.'
。enum1
的剩余两个元素被传递到块,并为每个元素计算nil
,这表明一行中没有四个'w'
或最后一行中的'b'
。我们就快完成了!
“等等”,你说,我们只检查了行!还有那些柱子和对角线!请继续收看。..
请勾选栏目
这一个是死容易。
给你
检查对角线(从左上到右下)
在这里,我们需要做的就是构造包含对角线的数组
arr
,然后应用four_in_a_row(arr)
。首先确定第一列中包含长度为4
或更长的元素的对角线。其中包括以下对角线没有必要考虑第一列中包含元素的其余对角线,因为它们包含的元素少于
4
:我们可以得到前三条对角线如下。
类似地,标识包括第一行中除
grid[0][0]
之外的元素的对角线,这些元素的长度为4
或更大。那些是对角线包含第一行中元素的其余对角线(
grid[0][0]
除外)包含少于4
的元素。我们得到这些对角线如下。因此,我们可以得到一个所有对角线的数组如下。
我们看到没有对角线包含四行。
检查前对角线(从左下到右上)
我们可以通过与计算对角线相同的推理,但由于计算效率在这里并不重要,因此有一种更简单的方法:计算通过“旋转”
grid
90度获得的阵列的对角线。我们看到,没有一个前对角线包含四行。
把一切都放在一起
four_in_a_row_by_row
的替代计算也可以如下写
four_in_a_row_by_row
。如果首选,
row.nil? ? nil : four_in_a_row(row)
可替换为t98cgbkg2#
如果存在获胜对角线,则开始位置必须在row [0-3]和col [0-3]的范围内。任何从左上方方框外开始的对角线都没有足够的右和下位置来使其连续四个。
所以实际上你需要一个
while row < 4
和while col < 4
嵌套循环。对于每个行列组合,假设值不是“”。“然后你可以设置你的piece_count为1,然后做一个计数器1到3,检查
playing_board[row + counter][col + counter]
等于playing_board[row][col]
的值,如果它是递增你的piece_count。在计数器1到3循环之外,如果piece_count为4,则您有赢家。
q43xntqr3#
我想出了一个解决方案,似乎在测试中工作。它从右下角到左上角,从我的8x8网格中的第7行第7列开始。我还创建了从左下角移动到右上角的前对角线。
我已经测试了最后一小段时间,并没有发现一个错误,但很想知道是否有人戳它的漏洞。
我非常感谢你们所有人--你们的解决方案和建议让我走到了这一步!
wd2eg0qa4#
我正在玩一个类似的网格,为一个填字游戏,并出来了一种方法,以获得对角线。我改变了一点,以适应连接4。这不是一个完整的答案,但我希望它能有所帮助。
首先,我想Map网格以获得坐标:
然后有几种方法来恢复矩阵的所有对角线(无论如何,应该有更好的解决方案)。
第一个只取一个方向上对角线的一半:
这调用半对角(matrix)对矩阵的变换以得到所有对角:
现在,需要检查每个对角线的赢家,因此定义一个方法来执行此操作:
现在调用
grid_map
上的方法,以获得连接的四个的计数,颜色和坐标:由于
check.detect
,四个"M"
没有返回。