2016-03-21 3 views
1

Ich bin beschäftigt, eine Version von Minesweeper in Python 3.5 zu schreiben, und der Code, den ich hier habe, ist entworfen, um jeden Wert in einem 2-dimensionalen Array, das ich als das Spielbrett erstellt habe, zu überprüfen und zu überprüfen, wie viele Minen (bezeichnet mit "O") umgeben es. Es funktioniert, aber ich fühle, dass der Code zu klobig ist. Gibt es eine Funktion in Python, die dies tut, oder gibt es eine Funktion, die ich schreiben könnte, die es vereinfachen würde?Effizient Werte um einen anderen Wert in einem 2D-Array lesen?

Die if-Anweisungen sind da, um zuerst zu überprüfen, ob der Wert im Array ist, so dass außerhalb des Bereichs nicht auftritt, und dann am Ort zu überprüfen.

for x in range(len(array)): 

     for y in range(len(array[0])): 

      if array[x][y] != "O": 

       counter = 0 

       if (x - 1 >= 0) and (array[x-1][y] == "O"): 

        counter += 1 

       if (x + 1 < len(array)) and (array[x+1][y] == "O"): 

        counter += 1 

       if (y - 1 >= 0) and (array[x][y+1] == "O"): 

        counter += 1 

       if (y + 1 < len(array)) and (array[x][y+1] == "O"): 

        counter += 1 

       if (x - 1 >= 0) and (y - 1 >= 0) and (array[x-1][y-1] == "O"): 

        counter += 1 

       if (x - 1 >= 0) and (y + 1 < len(array)) and (array[x-1][y+1] == "O"): 

        counter += 1 

       if (x + 1 < len(array)) and (y - 1 >= 0) and (array[x+1][y-1] == "O"): 

        counter += 1 

       if (x + 1 < len(array)) and (y + 1 < len(array)) and (array[x+1][y+1] == "O"): 

        counter += 1 

       array[x][y] = counter 
+0

Welche Werte kann ein Array-Element nehmen? Ich nehme 'if Array [x] [y]! = 0 ', um zu bedeuten, dass es keine leere Zelle ist und daher die Zahl darin bedeuten würde, wie viele Minen es gibt. Versteh ich etwas falsch? – Reti43

+0

Können Sie auch numpy verwenden? – Reti43

+0

Ich wollte schreiben! = "O", was bedeutet, dass es keine Mine ist. Ich habe es aktualisiert. Ich bin nicht so erfahren, und obwohl ich von numpy gehört habe, wusste ich nicht, dass es so etwas tun könnte. – Dova

Antwort

1

Versuchen Sie, diese Funktion nach array [x] [y]! = 0

def checkNeighbours(x,y,matrix): 
    neighbourValues = [matrix[x_][y_] for x_ in range(x-1,x+2) for y_ in range(y-1,y+2) 
         if (0 <= x_ < len(matrix) and 0 <= y_ < len(matrix) and (x_ != x or y_ != y))] 
    return neighbourValues.count('O') 
+0

Der Code funktioniert perfekt, aber wie funktioniert es? Entschuldigung, aber ich verstehe den Code innerhalb der NeighbourValues-Zuordnung nicht. – Dova

+0

@Dova Diese Zeile ist ein Listenverständnis. Das 'für x_ im Bereich (x-1, x + 2) für y_ im Bereich (y-1, y + 2)' erzeugt das 3x3-Fenster um die interessierende Zelle einschließlich der Zelle selbst und der Bedingungen in der if-Anweisung ignoriere alle außerhalb der Grenzen liegenden Koordinaten (die Zelle bei (0, 0) hat nur 3 Nachbarn + selbst). Die Bedingung 'x_! = X oder y_! = Y 'schließt die zentrale Zelle aus, aber es wäre in Ordnung, diese Bedingung zu löschen, da wir garantieren, dass es keine Mine mit' if array [x] [y] ist! = "O'". – Reti43

+0

Ah, danke, aber was bedeuten die Unterstriche? – Dova

1

Eine mögliche numpy basierte Lösung so sein würde. Überprüfen Sie die Kommentare stellen Sie sicher, Sie verstehen, was sie machen:

import numpy as np 

m = np.random.randint(0,2,(5,5)).astype('bool') 

print(m) # game matrix 

# Running all cels in matrix 
for i in range(m.shape[0]): 
    for j in range(m.shape[1]): 
     # clip will ensure you'll never have a value below 0 for indexes which 
     # is important at the borders of the game. 
     c = np.count_nonzero(m[np.clip(i-1,0,m.shape[0]):i+2,np.clip(j-1,0,m.shape[1]):j+2]) 
     if m[i,j]: 
      c = c - 1 # ensure you are not couting the cell where you are in. 
     print('FOR POSITION ',i,j,' FOUND ',c,' MINES.') 

Das Ergebnis war:

[[False False False True False] 
[ True True False True True] 
[ True True True True True] 
[ True True True False True] 
[ True True True True False]] 
FOR POSITION 0 0 FOUND 2 MINES. 
FOR POSITION 0 1 FOUND 2 MINES. 
FOR POSITION 0 2 FOUND 3 MINES. 
FOR POSITION 0 3 FOUND 3 MINES. 
FOR POSITION 0 4 FOUND 3 MINES. 
FOR POSITION 1 0 FOUND 4 MINES. 
FOR POSITION 1 1 FOUND 5 MINES. 
FOR POSITION 1 2 FOUND 6 MINES. 
FOR POSITION 1 3 FOUND 6 MINES. 
FOR POSITION 1 4 FOUND 5 MINES. 
FOR POSITION 2 0 FOUND 6 MINES. 
FOR POSITION 2 1 FOUND 8 MINES. 
FOR POSITION 2 2 FOUND 7 MINES. 
FOR POSITION 2 3 FOUND 7 MINES. 
FOR POSITION 2 4 FOUND 5 MINES. 
FOR POSITION 3 0 FOUND 6 MINES. 
FOR POSITION 3 1 FOUND 9 MINES. 
FOR POSITION 3 2 FOUND 8 MINES. 
FOR POSITION 3 3 FOUND 7 MINES. 
FOR POSITION 3 4 FOUND 4 MINES. 
FOR POSITION 4 0 FOUND 4 MINES. 
FOR POSITION 4 1 FOUND 6 MINES. 
FOR POSITION 4 2 FOUND 5 MINES. 
FOR POSITION 4 3 FOUND 4 MINES. 
FOR POSITION 4 4 FOUND 2 MINES. 
+0

Die Frage wurde leicht abgeändert. Das OP wollte schreiben: Wenn Array [x] [y]! = 'O'' ist, willst du über Nichtbombenzellen iterieren und die umgebenden Bomben zählen. Um zu reflektieren, dass ich denke, Sie brauchen 'window = m [np.clip() ...]; c = np.sum (Fenster == 'O') '. Es ist nicht nötig, 'm [i, j]' zu verwerfen, weil Sie diese Quadrate ohnehin ausschließen. – Reti43

+1

Außerdem ist es schneller als mit 'np.clip()' '' i0 = max (i-1, 0); j0 = max (j-1, 0); Fenster = m [i0: i + 2, j0: j + 2] '. – Reti43

+0

Oh, ich habe die Schleife nur zu Demonstrationszwecken benutzt. Theoretisch wäre der Code innerhalb der Schleife in der Lage, jederzeit und an jedem Ort aufgerufen zu werden. Vereinbar mit dem Max anstelle des Clips, da wir nicht unbedingt ein Maximum aufnehmen müssen (obwohl die Funktion es erfordert). Und es ist lesbarer. – armatita