2017-08-01 1 views
-2

私はCodefightsの問題に固執しています。Python:なぜこのアルゴリズムは意図したとおりに動作しませんか?

人気のMinesweeperゲームでは、鉱山のあるボードがあり、鉱山を持たないセルに隣接するセルの鉱山の総数を示す数字が表示されます。いくつかの鉱山の配置から始めて、地雷探知機のゲーム設定を作成したいと考えています。

matrix = [[True, False, False], 
     [False, True, False], 
     [False, False, False]] 

について出力は次のようになります。

minesweeper(matrix) = [[1, 2, 1], 
        [2, 1, 1], 
        [1, 1, 1]] 

だから、私が理解、我々は我々がする必要があるので、行列全体をトラフ見ているからどのセルが真であるかを知っている、つまり爆弾が入っているとわかったら、それを見つけたら、すべての隣接セルの値を増やすべきです境界セルのif/elifステートメントを使用してコードを記述しようとしましたが(エラーをスローしないように)、コードは実際には醜く長くなりました。だから私が思い付くことができる唯一の事は、このでした:

def minesweeper(matrix): 

# First creating the same matrix but instead full of zeros. 
result = [[0]* len(matrix[0]) for row in matrix] 

# Start iterating through the original matrix to find True elements 
for y in range(len(matrix)): 
    for x in range(len(matrix[0])): 
     if matrix[y][x] == True: 

      # The remaining code tries to increment all possible neighbours by 1. 
      for j in range(-1,2): 
       for i in range(-1,2): 

        # If statement so that we do not increment the bomb cell itself. 
        if not (j == 0 and i == 0): 
         try: 
          result[y+j][x+i] += 1 
         except: 
          continue 
return result 

input = [[True, False, False], 
     [False, True, False], 
     [False, False, False]] 

のための私の関数の出力は

[[1, 2, 2], [2, 1, 2], [2, 2, 2]] 

誰もが、それは仕事をdoesntなぜアイデアを持っているのですか?また、try/exceptステートメントでエラーをキャッチしようとする必要があり、これはおそらく悪い習慣であることを知っています。

+0

例をさらに修正してください。小文字の「true」と「false」は文字列(つまり「true」と「false」)または大文字にする必要があります。また、内側ループの 'yi'と' xi'は実際には定義されていません。したがって、コードが壊れているように見えます。 – alisianoi

+0

[リストの変更はサブリスト間で予期せず反映されます](https:// stackoverflow。com/questions/240178/list-of-lists-changes-across-sublists-unexpectedly) –

+0

@ŁukaszRogalskiそれは重複していません。結果変数は正しく初期化されます。 – Enfenion

答えて

0

あなたの問題は、負のインデックスを使用して値にアクセスすることは、Pythonで有効な操作であると思います。したがって、最初の要素を処理するときは、結果行列の最後の要素を増やします。

デバッガを使用してステップ実行するか、xとyの最初の反復後に値を停止してチェックアウトするか、小さな手順でコードをデバッグするようにしてください。

+0

はい、まさにイエスです。ありがとうございます。 –

0

受け入れられた回答の助けを借りて、次のコードが機能しました。そして、try/except文は、内部のコードがエラーを投げたことはないので、無用であった。

def minesweeper(matrix): 
    result = [[0]* len(matrix[0]) for row in matrix] 

    for y in range(len(matrix)): 
     for x in range(len(matrix[0])): 
      if matrix[y][x] == True: 
       for j in range(-1,2): 
        for i in range(-1,2): 
         if not (j == 0 and i == 0) and not ((y+j) < 0 or (x+i) < 0):  
          result[y+yi][x+xi] += 1 
    return result 
1

回のみ、細胞は全ての点(繰り返し)で細胞自体であるかどうかをチェックすることなく、lenminmax機能を実行しながら範囲を制限する別の可能な方法:

true = True # or "true" 
false = False # or "false" 

matrix = [[true, false, false], 
      [false, true, false], 
      [false, false, false]] 


def minesweeper(matrix): 
    # First creating the same matrix but instead full of zeros. 
    result = [[0] * len(matrix[0]) for row in matrix] 

    # Start iterating through the original matrix to find "true" elements 
    y_max = len(matrix) 
    for y in range(y_max): 
     x_max = len(matrix[0]) 
     for x in range(x_max): 
      if matrix[y][x] == true: 
       # The remaining code increments all neighbours by 1, but not beyond the matrix size! 
       for dy in range(max(0, y - 2), min(y_max, y + 2)): 
        for dx in range(max(0, x - 2), min(x_max, x + 2)): 
         result[dx][dy] += 1 
       # Do not increment the bomb cell itself (it was). 
       result[y][x] -= 1 

    return result 

そしてprint(minesweeper(matrix))与えるの所望の結果[[1, 2, 1], [2, 1, 1], [1, 1, 1]]

関連する問題