如何更有效地检查游戏板上的条纹?

时间:2019-04-03 01:03:55

标签: python algorithm performance

以下函数将像这样接收2D数组。

[['.', '.', '.', '.', '.', '.', '.'],
 ['.', '.', '.', '.', '.', '.', '.'],
 ['.', '.', 'y', '.', '.', '.', '.'],
 ['.', '.', 'y', '.', 'r', '.', 'y'],
 ['.', 'r', 'r', 'y', 'r', 'y', 'r'],
 ['.', 'r', 'y', 'y', 'r', 'r', 'y']]

该函数的目的是计算2D数组中存在的指定大小的“条纹”的数量。条纹定义为水平,垂直或对角线排列的连续标记行。

以下示例算作1个大小为2的条纹。

[['.', '.', '.', '.', '.', '.', '.'],
 ['.', '.', '.', '.', '.', '.', '.'],
 ['.', '.', '.', '.', '.', '.', '.'],
 ['.', '.', '.', '.', '.', '.', '.'],
 ['.', '.', 'r', '.', '.', '.', '.'],
 ['.', 'r', '.', '.', '.', '.', '.']]

下面的代码片段是我对董事会所有组合的蛮力解决方案。有没有可以代替的更有效的解决方案/算法?

def streaks(num_repeats, board, player_color):    
    reduced_range = num_repeats - 1
    list_idx_offsets = list(range(0, num_repeats))
    counter = 0
    # Checks rows
    for col in range(0, COLUMN_COUNT - reduced_range):
        for row in range(0, ROW_COUNT):
            list_results = []
            for idx in list_idx_offsets:
                list_results.append(board[row][col + idx])
            # If the list is identical and the player is in the list, then increment counter
            if list_els_identical(list_results) and player_color in list_results:
                counter += 1
    # Checks columns
    for col in range(0, COLUMN_COUNT):
        for row in range(0, ROW_COUNT - reduced_range):
            list_results = []
            for idx in list_idx_offsets:
                list_results.append(board[row + idx][col])
            if list_els_identical(list_results) and player_color in list_results:
                counter += 1
    # Check diagonals positive
    for col in range(0, COLUMN_COUNT - reduced_range):
        for row in range(0, ROW_COUNT - reduced_range):
            list_results = []
            for idx in list_idx_offsets:
                list_results.append(board[row + idx][col + idx])
            if list_els_identical(list_results) and player_color in list_results:
                counter += 1
    # Check diagonals negative
    for col in range(0, COLUMN_COUNT - reduced_range):
        for row in range(reduced_range, ROW_COUNT):
            list_results = []
            for idx in list_idx_offsets:
                list_results.append(board[row - idx][col + idx])
            if list_els_identical(list_results) and player_color in list_results:
                counter += 1
    return counter

2 个答案:

答案 0 :(得分:1)

如果只有x个很多,请连续检查x个,因为不能有更多,然后停止。这将比检查每个组合更快。

答案 1 :(得分:1)

  • 只需一次(按等级或文件)即可遍历该字段

    • 对于每个字段,检查条纹(通过查看相邻字段;如果它具有相同的符号,则该字段超出该字段的方向相同,依此类推),但只能“向前”:在一半方向上,即那些尚未走过的田野所在的地方。
      例如。当按等级行走时,将是:

      **********
      ****X-----
      .../|\....
      ../.|.\...
      ./..|..\..
      
  • 将找到的所有条纹保存到结果中
  • 为每个字段创建一个标志矩阵,以表示您已经在该字段中寻找条纹的这四个方向
  • 从字段中查找条纹时,对于您所查看的每个具有相同符号的字段,请适当地填充上述标记(对于当前单元格,也以相同的方式填充标记)。最终在该领域上行走时,请勿再朝那些方向看。
    • 这将确保您只在结果中有完整的条纹,而不是部分。
  • 最后,所有字段都将设置所有标志。您可以将其作为调试断言进行检查(如果未设置所有标志,则无法检查来自相应字段的相应方向)。