UmsteigerProblem: 2D-lists bei MineSweeper

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Hallo

Ich studiere Info und würde mir gerne eine neue Sprache aneignen und habe mir da mal Python angelacht. Wie auch in Java will ich als erstes ein Minesweeper bauen, da da eigentlich alle Grundkenntnisse einer Sprache benötigt werden. (GUI wird noch mal ein anderes Problem, aber dazu mache ich mir später Gedanken)

Für ein einzelnes Feld wollte ein eine Liste nehmen, in der ich verschiedene Einträge habe wie vermint, beflaggt, Anzahl der Nachbarminen. Diese Teile will ich dann in eine Liste einer Liste speichern. (also kurz eine dreifach verschachtelte Liste. )

Code: Alles auswählen

def newField(x, y, p):

# L: runter, rechts
    
    # eine passende 2D-Liste wird angelegt
    L = []
    for i in range( y):
        b = [] 
        for j in range( x ): 
            b.append( ['',False,0] ) 
        L.append(b)


    # die Minen werden gelegt
    for i in range(y):
        for j in range(x):
            if 1 : # TODO random Syntax >rand(p) :
                L[i][j]= ['bomb',False, 0]
            else:
                L[i][j]= ['bomb' ,False, 0]


    # die Anzahl der Nachbarbomben wird gezählt:
    for i in range(y):
        for j in range(x):
            cnt=0
            d=[-1,0,1]            
            for dy in d:
                for dx in d:
                    if (dx==0 and dy==0): continue
                    try:
                        if isbomb(L[i+dy][j+dx]):
                            cnt+=1;
                            print 'cnt' + cnt
                    except:
                        print i+dy
                        print j+dx
                        print ''
            print cnt
            L[i][j][2] = cnt

    return L
(IsBomb(x) return x[0]=='bomb')
Mein Problem besteht jetzt darin, dass ich immer in das except reinlaufe, obwohl überall Bomben liegen, ich aber trotzdem immer in das except reinlaufe.
Könnte mir da jemand etwas auf die Sprünge helfen?

Frohe Weihnachten :)

Nikolas
Benutzeravatar
Hobbes Hobson
User
Beiträge: 42
Registriert: Sonntag 9. Dezember 2007, 15:24
Wohnort: Bremen

if isbomb(L[i+dy][j+dx])

hier hast du den ersten aufruf von isbomb

du musst das vorher schon erstellen, um zu schauen was drin ist



p.s.: frohe weihnachten
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Also wenn es dir um die Grundkenntnisse der Sprache geht, realisiere die Minen usw. doch über Klassen, ist sicherlich um einiges hübscher ;)
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

@Hobbes: was meinst du damit? So lange ich die random-Syntax noch nicht gefunden habe, belege ich jedes Feld mit einer Bombe.
Und wenn ich mir einen beliebigen Eintrag aus meinem 2D element nehme und in der Kommandozeile das isBomb aufrufe, bekomme ich da auch immer ein true zurück.

Zurzeit entwickle ich mit IDLE. Gibts da eine Möglichkeit durch den Code zu steppen? (Also das auf Tastendruck die nächste Zeile ausgeführt wird und ich die Möglichkeit habe, die aktuelle Belegung der Variablen auszulesen, wie z.B. bei Delphi?)

@RedPrince: Von Klassen habe ich hier leider noch keine Ahnung :)
Und wenn ich die Einträge in Klassen verpacke, kann ich da auch nur isBomb oder isFlagged als eigene Funktionen reinstecken, die in der jetzigen Version auch nur Einzeiler sind. Unnötig erschweren will ich es mir auch nicht.
Eine Möglichkeit wäre vielleicht, den ganzen Code in eine Klasse zu packen, der man dann die Mausklicks übergibt und nur eine Zeichenfläche zuweist. Aber da ich nachher noch eine GUI bauen will, halte ich den Rest erst mal so einfach wie möglich.
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
BlackJack

@Nikolas: Vielleicht ein schönes Beispiel warum man nicht einfach nur ``except`` ohne konkrete Ausnahme verwendet sollte, sondern immer nur die behandeln sollte, die man auch erwartet. Was hier zum Beispiel sein könnte ist ein simpler `NameError`. Im Programm steht `isbomb()`, im Text hast Du aber `IsBomb()` geschrieben. Vielleicht ist es auch etwas anderes, aber wenn Du konkret den `IndexError` abfängst, den Du ja eigentlich nur behandeln möchtest, bekommst Du vielleicht schon eine Fehlermeldung, die Dich weiter bringt.

Wenn man die einzelnen Felder als Klassen modellieren würde, wären `is_bomb` und `is_flagged` nicht einmal Methoden, da reichen einfache Attribute. Der Quelltext könnte dadurch einfacher verständlich werden. Aus einem ``if minefield[y][x][1]:`` mit einer "magischen" Konstante 1 würde ``if minefield[x][y].flagged:``.
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Ok, so einen Fehler habe ich jetzt noch in keiner Sprache gesehen. (Bisher waren auch alle Sprachen compiliert...)

Wenn ich jetzt eine korrekte isBomb einsetze und

Code: Alles auswählen

                    try:
                        if isBomb(L[i+dy][j+dx]):
                            cnt+=1;
                            print i+dy
                            print j+dx
                            print 'Bombe'
                            # print 'cnt' + cnt
                    except IndexError:
                        print i+dy
                        print j+dx
                        print 'Fehler'
schreibe. Bekomme ich für den Aufruf a=newField(2,2,1) folgendes:
-1
-1
Bombe
-1
0
Bombe
-1
1
Bombe
0
-1
Bombe
0
1
Bombe
1
-1
Bombe
(...)
Anscheinend gibt es ein Feld a[-1][-1] das mit einer Bombe belegt ist. (was ich auch in der Kommandozeile erfahre). Anscheined kann ich dieses Feld auch mit a[1][1] ansprechen, die Liste sieht also etwas zyklisch aus. wobei a[5][5] einen IndexFehler hervorbringt.

Kann mir das jemand erklären? Nach dem Learning Python von O'Reilly ist eine Liste in python doch 0-indiziert.

- Das als Klasse zu machen ist vielleicht doch nicht ganz blöd. Ich werd's mir mal überlegen. Morgen habe ich noch 4h Zugfahrt vor mir, da werde ich wohl die Zeit dazu finden.

(randomSytnax ist jetzt auch klar)
einfach ein
import random from random
und dann if random()<p: ... (ist doch die sauberste Version, oder )


zur magischen Konstanten:
in c++ fand ich die enums ganz nett, habe ich nichts ähnliches gefunden. (Bis auf eine Klasse, die so etwas simuliert). Muss man hier also ohne so eine Konstruktion auskommen?
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Nikolas hat geschrieben:Anscheinend gibt es ein Feld a[-1][-1] das mit einer Bombe belegt ist. (was ich auch in der Kommandozeile erfahre). Anscheined kann ich dieses Feld auch mit a[1][1] ansprechen, die Liste sieht also etwas zyklisch aus. wobei a[5][5] einen IndexFehler hervorbringt.
Mit dem Index -1 wird das letzte Element der Liste zurückgegeben, -2 würde das vorletzte zurückgeben, etc.
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Und den indexerror gibts dann nur, wenn der übergebene index betragsmäßig größer als die (anzahl der Element-1) ist?
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Nikolas hat geschrieben:Und den indexerror gibts dann nur, wenn der übergebene index betragsmäßig größer als die (anzahl der Element-1) ist?
Ein negativer Index entspricht quasi

Code: Alles auswählen

liste[-n] == liste[len(liste) - n]
Du bekommst also einen IndexError, wenn dein Index > len(liste) - 1 oder aber auch Index < -len(liste).
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Muss ich dann alles von Hand schreiben, oder gibst da noch etwas, das mir Arbeit abnehmen könnte?

Danke an alle, das hilft schon mal deutlich weiter :lol:
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
Antworten