Created
December 9, 2014 20:34
-
-
Save anonymous/e97df77504507e036d10 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
WHITE = "#FFFFFF" | |
GRAY = "#CCCCCC" | |
RED = "#FF8888" | |
YELLOW = "#FFFF88" | |
GREEN = "#88FF88" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from sys import exit | |
import colors | |
import models | |
import views | |
class TkController(object): | |
def __init__(self): | |
self.viewer = views.TkViewer() | |
# Events vom Viewer schnappen und an eigene Methoden weiterleiten | |
# Neues Spiel-GUI oeffnen | |
self.viewer.NewGameEvent.append(self.newGame) | |
# Leichter Schwierigkeitsgrad | |
self.viewer.EasyEvent.append(lambda: self.genFirstGrid(9, 9, 10)) | |
# Mittlerer Schwierigkeitsgrad | |
self.viewer.NormalEvent.append(lambda: self.genFirstGrid(16, 16, 40)) | |
# Schwerer Schwierigkeitsgrad | |
self.viewer.HardEvent.append(lambda: self.genFirstGrid(30, 16, 99)) | |
# Eigener Schwierigkeitsgrad | |
self.viewer.CustomGameEvent.append(self.genCustomGrid) | |
# GUI fuer eigenen Schwierigkeitsgrad oeffnen | |
self.viewer.MyEvent.append(self.viewer.createUserSweeperGUI) | |
# Generell das Anklicken von Feldern | |
self.viewer.ClickOnFieldEvent.append(self.clickOnField) # y, x | |
# Generell das Rechtsklicken von Feldern | |
self.viewer.RightClickOnFieldEvent.append(self.rightClick) # y, x | |
# Programm beenden | |
self.viewer.QuitEvent.append(self.quit) | |
# Programminfo | |
self.viewer.InfoEvent.append(self.info) | |
def run(self): | |
"""Setzt alles in Gang^^.""" | |
self.newGame() | |
self.viewer.run() | |
def quit(self): | |
"""Beendet das Programm.""" | |
exit() | |
def info(self): | |
"""Benutzer hat auf Info geklickt.""" | |
self.viewer.showInfo() | |
def newGame(self): | |
"""Startet ein neues Spiel.""" | |
self.viewer.createDifficultyGUI() | |
def genFirstGrid(self, width, height, mines): | |
"""Grid erstellen.""" | |
self.width = width | |
self.height = height | |
self.mines = mines | |
self.gamefield = None | |
self.viewer.createMineSweeperGUI(width, height) | |
def genCustomGrid(self, width, height, mines): | |
"""Eigenes Grid erstellen. | |
Es sind falsche Eingaben moeglich, deshalb braucht das | |
eine eigene Methode zur Fehlerpruefung. | |
""" | |
print(width, height, mines) | |
try: | |
width = int(width) | |
height = int(height) | |
mines = int(mines) | |
if mines+1 > width * height or width < 2 or width > 30 \ | |
or height < 2 or height > 24: | |
raise ValueError | |
except ValueError: | |
self.viewer.showWrongCustom() | |
else: | |
self.genFirstGrid(width, height, mines) | |
def clickOnField(self, y, x): | |
"""Es wurde auf ein Spielfeld geklickt. | |
Erst hier wird das Modell erstellt. Dadurch wird verhindert, | |
dass der erste Klick vom Benutzer direkt eine Mine ausloest. | |
""" | |
if self.gamefield is None: | |
# Modell entsprechend generieren | |
self.gamefield = models.Gamefield(self.width, self.height) | |
self.gamefield.genMines(self.mines, noty=y, notx=x) | |
# Modell-Event schnappen: Feld geoeffnet | |
self.gamefield.OpenNonMineEvent.append(self.MDL_OpenNonMine) | |
# Modell-Event schnappen: Minenfeld geoeffnet | |
self.gamefield.OpenMineEvent.append(self.MDL_OpenMine) | |
# Modell-Event schnappen: Farbe geaendert | |
self.gamefield.ColorChangedEvent.append(self.MDL_ColorChanged) | |
# Modell-Event schnappen: Spiel gewonnen | |
self.gamefield.WinEvent.append(self.MDL_Winner) | |
# Weitergeben ans Modell: | |
self.gamefield.openField(y, x) | |
def rightClick(self, y, x): | |
"""Ein Rechtsklick wurde auf einem Feld ausgefuehrt.""" | |
# Ein Rechtsklick, obwohl das Spielfeld noch nichtmal | |
# generiert wurde, haette keinen Sinn, da der Spieler | |
# beim ersten Klick sowieso keine Mine trifft. | |
if self.gamefield is not None: | |
self.gamefield.markField(y, x) | |
if self.gamefield.gamefield[y][x].color == colors.RED: | |
self.mines -= 1 | |
else: | |
self.mines += 1 | |
self.viewer.showStatusbar("Noch {} Minen übrig".format(self.mines)) | |
def MDL_OpenNonMine(self, obj, y, x, value): | |
"""Modell meldet, ein Feld (keine Mine) wurde geoeffnet.""" | |
if value != 0: | |
field = self.gamefield.gamefield[y][x] | |
self.viewer.changeText(y, x, value) | |
self.viewer.changeColorToWhite(y, x) | |
self.viewer.disableRightClick(y, x) | |
self.viewer.unbindLeftClick(y, x) | |
def MDL_ColorChanged(self, obj, y, x, color): | |
"""Modell meldet, ein Feld hat seine Farbe geaendert.""" | |
# Wurde rot markiert? Dann Feld im Viewer auch | |
# rot markieren und dabei gleich deaktivieren. | |
if color == colors.RED: | |
self.viewer.changeColorToRed(y, x) | |
self.viewer.unbindLeftClick(y, x) | |
# Bei grauer Markierung dementsprechend anders vorgehen. | |
elif color == colors.GRAY: | |
self.viewer.changeColorToGray(y, x) | |
self.viewer.bindLeftClick(y, x) | |
def MDL_OpenMine(self, *args): | |
"""Modell meldet, eine Mine wurde geoeffnet.""" | |
# Statusbar aktualisieren | |
self.viewer.showLoserBar() | |
# Alle Buttons deaktivieren | |
self.viewer.disableAllButtons() | |
# Alle noch nicht markierten Minen anzeigen | |
for i in self.gamefield.getMines(): | |
self.viewer.changeColorToRed(i[0], i[1]) | |
# Falsch markierte Minen gelb einfaerben | |
for i in self.gamefield.getFalsemarkedMines(): | |
self.viewer.changeColorToYellow(i[0], i[1]) | |
def MDL_Winner(self, *args): | |
"""Modell meldet, das Spiel wurde gewonnen.""" | |
# Eingaben blockieren | |
self.viewer.disableAllButtons() | |
# Statusbar aktualisieren | |
self.viewer.showWinnerBar() | |
# Alle noch nicht markierten Minen anzeigen | |
for i in self.gamefield.getMines(): | |
self.viewer.changeColorToRed(i[0], i[1]) | |
# Falsch markierte Minen gelb einfaerben | |
for i in self.gamefield.getFalsemarkedMines(): | |
self.viewer.changeColorToYellow(i[0], i[1]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Der wohl billigste Eventhandler in Python^^. | |
class Event(list): | |
def notify(self, *args, **kwargs): | |
for listener in self: | |
listener(*args, **kwargs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import views | |
import controls | |
if __name__ == "__main__": | |
controller = controls.TkController() | |
controller.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from random import randint | |
from sys import exit | |
import colors | |
import event | |
class Field(object): | |
id = 0 | |
def __init__(self): | |
self.id = Field.id | |
Field.id += 1 | |
# Die Nachbarfelder | |
self.onLeft = None | |
self.onRight = None | |
self.onUp = None | |
self.onDown = None | |
# Wert. Bei -1 = Mine, ansonsten die | |
# Anzahl der benachbarten Minen. | |
self.value = 0 | |
# Felder sind am Anfang immer verschlossen... | |
self.closed = True | |
# Feldfarbe, in RGB-Notation | |
self.color = colors.GRAY | |
def __repr__(self): | |
return self.value | |
class Gamefield(object): | |
def __init__(self, width, height): | |
"""Generiert ein Feld und setzt alle Nachbarfelder.""" | |
# Event-Handling: | |
# Event soll abgefeuert werden, wenn KEINE Mine geoeffnet wurde. | |
self.OpenNonMineEvent = event.Event() # Konvention: self, y, x, value | |
# Event soll abgefeuert werden, WENN eine Mine geoeffnet wurde. | |
self.OpenMineEvent = event.Event() # Konvention: self, y, x | |
# Event soll abgefeuert werden, wenn | |
# alle minenfreien Felder offen sind | |
self.WinEvent = event.Event() # Konvention: self | |
# Event soll bei Farbaenderung abgefeuert werden | |
self.ColorChangedEvent = event.Event() # Konvention: self, y, x, color | |
# Spielfeld generieren | |
self.width = width | |
self.height = height | |
self.gamefield = [ | |
[Field() for _ in range(width)] for _ in range(height) | |
] | |
# Anzahl Minen speichern | |
self.minesCount = 0 | |
# Anzahl Felder zum Oeffnen speichern | |
self.winCount = width * height | |
# Nachbarfelder zuweisen | |
for y, line in enumerate(self.gamefield): | |
for x, field in enumerate(line): | |
# Oben zuweisen | |
if y > 0: | |
field.onUp = self.gamefield[y-1][x] | |
# Unten zuweisen | |
if y < height-1: | |
field.onDown = self.gamefield[y+1][x] | |
# Links zuweisen | |
if x > 0: | |
field.onLeft = self.gamefield[y][x-1] | |
# Rechts zuweisen | |
if x < width-1: | |
field.onRight = self.gamefield[y][x+1] | |
def __repr__(self): | |
return self.gamefield | |
def setMine(self, y, x): | |
"""Setzt eine Mine auf das Feld. | |
Falls schon eine Mine auf dem Feld ist, wird False | |
zurueckgegeben, ansonsten True. | |
""" | |
# Fehlerpruefung: Es sollten immer mind. 10 freie | |
# Plaetze auf dem Spielfeld geben: | |
if self.minesCount-1 > self.width * self.height: | |
raise | |
field = self.gamefield[y][x] | |
# Schon eine Mine gesetzt? Dann gib "False" zurueck | |
if field.value == -1: | |
return False | |
# Mine setzen, Minen-Zaehler erhoehen u. Gewinn-Zaehler verringern | |
# (Bei Letzterem soll die Mine ja nicht wirklich aufgedeckt werden ;) ) | |
field.value = -1 | |
self.minesCount += 1 | |
self.winCount -= 1 | |
# Nachbarfelder informieren, dass eine Mine in der Naehe liegt: | |
for direction in (field.onLeft, field.onRight, | |
field.onUp, field.onDown): | |
if direction is not None and direction.value != -1: | |
direction.value += 1 | |
# Diagonale Felder auch informieren: | |
for y_dir in (field.onUp, field.onDown): | |
if y_dir is not None: | |
for x_dir in (y_dir.onLeft, y_dir.onRight): | |
if x_dir is not None and x_dir.value != -1: | |
x_dir.value += 1 | |
return True | |
def genMines(self, count, noty=-1, notx=-1): | |
"""Setzt eine festgelegte Anzahl Minen zufaellig ins Spielfeld. | |
noty und notx ist das Feld, in das keine Mine generiert wird | |
(ueblicherweise das Feld, welches der Spieler als Erstes anklickt). | |
Optional. | |
""" | |
# Zufallsposition generieren und Mine ggf. setzen | |
i = count | |
while i: | |
i -= 1 | |
y = randint(0, self.height-1) | |
x = randint(0, self.width-1) | |
# Es wurde zufaellig die Position ermittelt, die nicht | |
# ermittelt werden duerfte? Dann keine Mine generieren | |
# und einen zusaetzlichen Schleifenlauf anfordern. | |
# TODO: Waer eigentlich sinnvoller, erst die Minen zu | |
# generieren und erst am Schluss zu pruefen, ob eine | |
# Mine an der fraglichen Position liegt und diese ein- | |
# fach zu entfernen... | |
if y == noty and x == notx: | |
i += 1 | |
# False zurueckgegeben (= eine Mine existiert schon | |
# an dieser Position)? Dann wiederholen... | |
elif not self.setMine(y, x): | |
i += 1 | |
def openField(self, y, x): | |
"""Oeffnet ein angegebenes Feld. | |
Falls Feld den Wert (Value) 0 hat, werden rekursiv auch alle | |
anderen Felder herum geoeffnet. | |
""" | |
field = self.gamefield[y][x] | |
# Feld bereits geoeffnet? Dann nichts tun; sonst oeffnen. | |
if not field.closed: | |
return None | |
field.closed = False | |
# Mine geoeffnet oder nicht? Je nachdem, das passende Event abfeuern: | |
if field.value == -1: | |
self.OpenMineEvent.notify(self, y, x) | |
else: | |
self.OpenNonMineEvent.notify(self, y, x, field.value) | |
# Ueberpruefe, ob gewonnen wurde: | |
self.winCount -= 1 | |
if self.winCount == 0: | |
self.WinEvent.notify(self) | |
# Feld hat den Wert 0? Dann alle umliegenden Felder rekursiv oeffnen: | |
if field.value == 0: | |
# Nachbarfelder auch aufdecken: | |
for direction in (field.onLeft, field.onRight, | |
field.onUp, field.onDown): | |
if direction is not None: | |
y, x = self.__getPosByObject(direction) | |
self.openField(y, x) | |
# Diagonale Felder auch informieren: | |
for y_dir in (field.onUp, field.onDown): | |
if y_dir is not None: | |
for x_dir in (y_dir.onLeft, y_dir.onRight): | |
if x_dir is not None: | |
y, x = self.__getPosByObject(x_dir) | |
self.openField(y, x) | |
def __getPosByObject(self, field): | |
"""Gibt die Position des Objekts zurueck. | |
Rueckgabewert: Tupel (Y-Position, X-Position) | |
""" | |
id = field.id | |
for y, line in enumerate(self.gamefield): | |
for x, field in enumerate(line): | |
if field.id == id: | |
return (y, x) | |
def getPrintView(self): | |
"""Gibt das Feld zurueck. | |
Nur fuer TerminalViewer zu gebrauchen^^. | |
""" | |
ret = "" | |
for line in self.gamefield: | |
for field in line: | |
if field.closed: | |
ret += "#" | |
else: | |
if field.value == -1: | |
ret += "*" | |
else: | |
ret += str(field.value) | |
ret += "\n" | |
return ret | |
def DEBUG_getCheatView(self): | |
"""Gibt das komplette Feld zurueck. | |
DEBUG: Ignoriert, ob das Feld schon geoeffnet ist. | |
""" | |
ret = "" | |
for line in self.gamefield: | |
for field in line: | |
if field.value == -1: | |
ret += "*" | |
else: | |
ret += str(field.value) | |
ret += "\n" | |
return ret | |
def markField(self, y, x): | |
"""Markiert ein Feld. | |
Nach jedem Aufruf tauscht sich die Farbe | |
(bzw. "nur" der Variablenwert) zwischen | |
grau und rot.""" | |
field = self.gamefield[y][x] | |
if field.color == colors.GRAY: | |
field.color = colors.RED | |
else: | |
field.color = colors.GRAY | |
self.ColorChangedEvent.notify(self, y, x, field.color) | |
def getMines(self): | |
"""Gibt alle Felder mit Minen zurueck. | |
Der Rueckgabewert ist eine Liste, die | |
pro Mine eine Y-/X-Liste enthaelt. | |
""" | |
ret = list() | |
for y, line in enumerate(self.gamefield): | |
for x, field in enumerate(line): | |
if field.value == -1: | |
ret.append(list()) | |
ret[-1] = y, x | |
return ret | |
def getFalsemarkedMines(self): | |
"""Gibt alle roten Nicht-Minen-Felder zurueck. | |
Einfacher formuliert: Diese Funktion gibt saemtliche | |
Felder zurueck, die zwar rot markiert wurden, | |
aber keine Minen enthalten. | |
""" | |
ret = list() | |
for y, line in enumerate(self.gamefield): | |
for x, field in enumerate(line): | |
if field.value != -1 and field.color == colors.RED: | |
ret.append(list()) | |
ret[-1] = y, x | |
return ret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Fix fuer Python 2.x/3.x | |
try: | |
import Tkinter as tk | |
except ImportError: | |
import tkinter as tk | |
try: | |
import tkMessageBox as msgbox | |
except ImportError: | |
import tkinter.messagebox as msgbox | |
import colors | |
import event | |
class TkViewer(object): | |
def __init__(self): | |
"""Stellt Minesweeper in Tk-Fenstern dar.""" | |
# Events bereitstellen, die ggf. ein Controller abfragt. | |
# Schwierigkeitsgradauswahl: | |
self.CustomGameEvent = event.Event() # Konvention: nix | |
self.NewGameEvent = event.Event() # Konvention: nix | |
self.QuitEvent = event.Event() # Konvention: nix | |
self.InfoEvent = event.Event() # Konvention: nix | |
self.EasyEvent = event.Event() # Konvention: nix | |
self.NormalEvent = event.Event() # Konvention: nix | |
self.HardEvent = event.Event() # Konvention: nix | |
self.MyEvent = event.Event() # Konvention: nix | |
# Wenn in ein Feld geklickt wird | |
self.ClickOnFieldEvent = event.Event() # Konvention: y, x | |
# Wenn auf ein Feld RECHTSgeklickt wird | |
self.RightClickOnFieldEvent = event.Event() # Konvention: y, x | |
# Root-Fenster | |
self.root = tk.Tk() | |
self.root.title("Another Minesweeper-Clone by Astorek86") | |
self.root.geometry("1000x700") | |
# Window-Layout; wird bei Bedarf geloescht und neu erstellt | |
self.window = tk.Frame(self.root) | |
self.window.pack(expand=True, fill=tk.BOTH) | |
# Menubar; aendert sich im laufenden Programm auch nicht mehr | |
# "Datei"-Menue | |
self.menubar = tk.Menu(self.root) | |
self.filemenu = tk.Menu(self.menubar, tearoff=0) | |
self.filemenu.add_command(label="Neues Spiel", | |
command=self.NewGameEvent.notify) | |
self.filemenu.add_separator() | |
self.filemenu.add_command(label="Programm beenden", | |
command=self.QuitEvent.notify) | |
self.menubar.add_cascade(label="Datei", menu=self.filemenu) | |
# "Hilfe"-Menue | |
self.infomenu = tk.Menu(self.menubar, tearoff=0) | |
self.infomenu.add_command(label="Hilfe", command=self.InfoEvent.notify) | |
self.menubar.add_cascade(label="Info", menu=self.infomenu) | |
self.root.config(menu=self.menubar) | |
# Statusbar | |
self.statusbar = tk.Label(self.root) | |
self.statusbar.pack(side=tk.BOTTOM, expand=False, anchor=tk.NW) | |
self.statusbar.configure(font=(None, 12), anchor=tk.W, justify=tk.LEFT) | |
def __createGrid(self, width, height): | |
"""Erstellt eine bestimmte Anzahl an Zellen. | |
Warnung: Vorher wird der Fensterinhalt komplett | |
geloescht! | |
""" | |
# Altes Fenster komplett loeschen & neu erstellen | |
self.window.destroy() | |
self.window = tk.Frame(self.root) | |
self.window.pack(expand=True, fill=tk.BOTH) | |
# Spalten generieren | |
self.columns = list() | |
for _ in range(width): | |
self.columns.append(tk.Frame(self.window)) | |
self.columns[-1].pack(side=tk.LEFT, expand=True, fill=tk.BOTH) | |
# Buttons generieren | |
self.button = dict() | |
for x, column in enumerate(self.columns): | |
for y in range(height): | |
self.button[y, x] = tk.Button(column, height=True, width=True, | |
font=(None, 12)) | |
# Nachtraegliches Aendern der Groesse verhindern | |
self.button[y, x].pack_propagate(0) | |
self.button[y, x].pack(side=tk.TOP, expand=True, fill=tk.BOTH) | |
# Statusbar-Text loeschen | |
self.statusbar.configure(text="") | |
def createDifficultyGUI(self): | |
"""Erstellt den Schwierigkeitsgrad-Auswahlbildschirm.""" | |
self.__createGrid(2, 2) | |
self.button[0, 0].configure(text="Einfach\n(9x9 Felder, 10 Minen)", | |
command=self.EasyEvent.notify) | |
self.button[0, 1].configure(text="Normal\n(16x16 Felder, 40 Minen)", | |
command=self.NormalEvent.notify) | |
self.button[1, 0].configure(text="Schwierig\n(30x16 Felder, 99 Minen)", | |
command=self.HardEvent.notify) | |
self.button[1, 1].configure(text="Benutzerdefiniert", | |
command=self.MyEvent.notify) | |
def createUserSweeperGUI(self): | |
"""Erstellt einen Benutzerdefiniert-Schwierigkeitsgrad-Bildschirm.""" | |
# Fenster neu erstellen | |
self.window.destroy() | |
self.window = tk.Frame(self.root) | |
self.window.pack(expand=True, fill=tk.BOTH) | |
# 2 Spalten generieren | |
left = tk.Frame(self.window) | |
left.pack(side=tk.LEFT, expand=True, fill=tk.BOTH) | |
right = tk.Frame(self.window) | |
right.pack(side=tk.LEFT, expand=True, fill=tk.BOTH) | |
# Text generieren | |
tmpdata = list() | |
for text in [ | |
"Breite des Feldes (2-30):", | |
"Höhe des Feldes (2-24):", | |
"Anzahl der Minen:" | |
]: | |
j = tk.Label(left, font=(None, 10), anchor=tk.E, text=text) | |
j.pack(side=tk.TOP, expand=False, fill=tk.BOTH) | |
tmpdata.append(tk.Entry(right, font=(None, 12))) | |
tmpdata[-1].pack(side=tk.TOP, expand=False, fill=tk.BOTH) | |
w = tk.Button( | |
right, text="OK", bg=colors.GREEN, | |
command=lambda: | |
self.CustomGameEvent.notify(tmpdata[0].get(), | |
tmpdata[1].get(), | |
tmpdata[2].get()) | |
) | |
w.pack(side=tk.TOP, expand=True, fill=tk.BOTH) | |
def createMineSweeperGUI(self, width, height): | |
"""Hier wird das eigentliche Spielfeld erstellt. | |
Automatisch werden auch Links- und Rechtsklicks abgefragt und | |
saemtliche Farben auf grau geschaltet. | |
""" | |
self.__createGrid(width, height) | |
for button in self.button.items(): | |
y = button[0][0] | |
x = button[0][1] | |
# Ueberall Linksklicks erlauben... | |
self.bindLeftClick(y, x) | |
# ...und Rechtsklicks auch: | |
self.button[y, x].bind( | |
'<Button-3>', | |
lambda event, y=y, x=x: | |
self.RightClickOnFieldEvent.notify(y, x) | |
) | |
# Farben schalten: | |
self.changeColorToGray(y, x) | |
def run(self): | |
self.root.mainloop() | |
def changeText(self, y, x, value): | |
"""Aendert den Text auf dem angegebenen Button.""" | |
self.button[y, x].configure(text=value) | |
def changeColorToGray(self, y, x): | |
"""Aendert die Farbe eines Buttons auf Grau.""" | |
self.button[y, x].configure(bg=colors.GRAY) | |
def changeColorToRed(self, y, x): | |
"""Aendert die Farbe eines Buttons auf Rot.""" | |
self.button[y, x].configure(bg=colors.RED) | |
def changeColorToWhite(self, y, x): | |
"""Aendert die Farbe eines Buttons auf Weiss.""" | |
self.button[y, x].configure(bg=colors.WHITE) | |
def changeColorToYellow(self, y, x): | |
"""Aendert die Farbe eines Buttons auf Gelb.""" | |
self.button[y, x].configure(bg=colors.YELLOW) | |
def bindLeftClick(self, y, x): | |
"""Erlaubt Linksklicks (Standardmaessig erlaubt).""" | |
self.button[y, x].configure( | |
command=lambda y=y, x=x: self.ClickOnFieldEvent.notify(y, x) | |
) | |
self.button[y, x].config(state='normal') | |
def unbindLeftClick(self, y, x): | |
"""Verbietet Linksklicks.""" | |
self.button[y, x].configure(command=None) | |
self.button[y, x].config(state='disabled') | |
def disableRightClick(self, y, x): | |
"""Deaktiviert Rechtsklicks auf das ausgewaehlte Feld.""" | |
self.button[y, x].unbind('<Button-3>') | |
def disableAllButtons(self): | |
"""Deaktiviert saemtliche Buttons.""" | |
for button in self.button.items(): | |
y = button[0][0] | |
x = button[0][1] | |
self.unbindLeftClick(y, x) | |
self.disableRightClick(y, x) | |
def showLoserBar(self): | |
"""Zeigt eine -Du hast verloren-Meldung an.""" | |
self.statusbar.configure(text="LEIDER VERLOREN! :(") | |
def showWinnerBar(self): | |
"""Zeigt eine -Du hast gewonnen-Meldung an.""" | |
self.statusbar.configure(text="HERZLICHEN GLÜCKWUNSCH, ALLE FELDER" | |
+ "AUFGEDECKT! :)") | |
def showStatusbar(self, text): | |
"""Zeigt eine selbstdefinierte Meldung an.""" | |
self.statusbar.configure(text=text) | |
def showInfo(self): | |
"""Zeigt eine Info an.""" | |
msgbox.showinfo( | |
"Info", | |
"Erstellt von Astorek86.\n\nVielen Dank an die Python- und" + | |
"QBasic-\nCommunity für sämtliche erhaltenen Hilfen. :)" | |
) | |
def showWrongCustom(self): | |
"""Zeigt eine Fehlermeldung an.""" | |
msgbox.showerror( | |
"Fehler", | |
"Eingaben konnten nicht korrekt verarbeitet werden, oder" + | |
"\ndie Anzahl der Minen übersteigt die Feldgröße." | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment