Minesweeper ohne GUI -> Rekursions-Error
Verfasst: Donnerstag 10. September 2015, 11:44
Hey Leute. Ich habe letztens ein Minesweeper programmiert, was man in der Python-Shell spieln kann. Funktioniert auch eigentlich ganz gut. Aber beim echten Minesweeper werden, wenn man ein Feld ohne Minen auf den Nachbarn anklickt, die Nachbarn automatisch freigeklickt und da klemmt es bei mir (wenn ich es einkommentiere, versteht sich ): Aus mir nicht bekannten Gründen geht die Rekursion zu tief. Könnt ihr mir helfen? (Für weitere Vorschläge bin ich selbstverständlich offen.)
Code: Alles auswählen
from random import randint
from itertools import product as kartesisches_produkt
class SpielVerloren(Exception):
pass
class Minenfeld:
def __init__(self, breite=10, hoehe=10, anz_minen=10):
self.breite = breite
self.hoehe = hoehe
self.freigeklickt = []
self.flaggen = []
self.init_minen(anz_minen)
def init_minen(self, anz_minen):
self.minen = []
while len(self.minen) < anz_minen:
# Vorsicht: Nullbasiert zählen!!
mine = randint(0,self.breite-1), randint(0,self.hoehe-1)
if mine not in self.minen:
self.minen.append(mine)
def klick(self, z, s, out=True):
if not (0<=z<self.hoehe and 0<=s<self.breite):
raise IndexError("Dieses Feld gibts nicht! (%i,%i)"%(z,s))
if (z,s) in self.minen:
raise SpielVerloren("Mine bei (%i,%i) BOOOOOOM!!!!!!!!"%(z,s))
self.freigeklickt.append((z,s))
# Nachbarn errechnen
nachbarn = list(kartesisches_produkt((z-1, z, z+1),
(s-1, s, s+1)))
nachbarn.remove((z, s))
nachbarn = [koords for koords in nachbarn
if 0<=koords[0]<self.breite and 0<=koords[1]<self.hoehe]
# Verminte Nachbarn zählen
anz_nachbarminen = len([nachbar for nachbar in nachbarn if nachbar in self.minen])
# 0er automatisch freiklicken (und hier klemmts)
"""if anz_nachbarn == 0:
self.mehrfachklick(nachbarn)"""
if out: print(self)
return anz_nachbarminen
def mehrfachklick(self, felderliste, out=True):
erg = [self.klick(z,s,out=False) for z,s in felderliste]
if out: print(self)
return erg
def __str__(self):
zeilen = [[self.feldinfo(z,s) for s in range(self.breite)] for z in range(self.hoehe)]
zeilen_str = ["|"+"|".join(zeile)+"|\n" for zeile in zeilen]
trennzeile = "+"+"+".join(["-"]*self.breite)+"+\n"
darstellung = trennzeile + trennzeile.join(zeilen_str) + trennzeile
return darstellung
def feldinfo(self, z, s):
if not (0<=z<self.hoehe and 0<=s<self.breite):
raise IndexError("Dieses Feld gibts nicht! (%i,%i)"%(z,s))
if (z,s) in self.flaggen:
return "Y"
if (z,s) not in self.freigeklickt:
return " "
return str(self.klick(z,s,out=False))
def setze_flagge(self, z, s):
if not (0<=z<self.hoehe and 0<=s<self.breite):
raise IndexError("Dieses Feld gibts nicht! (%i,%i)"%(z,s))
self.flaggen.append((z,s))
m = Minenfeld()