Minesweeper --> Konstruktor

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
diefragerin
User
Beiträge: 10
Registriert: Samstag 8. Dezember 2018, 14:20

Montag 2. Dezember 2019, 14:43

Hallo zusammen,

ich schreibe gerade das Spiel minesweeper für ein Schulprojekt.
Unser Lehrer hat uns ein Anfangsprogramm geschrieben, mit dem wir arbeiten können, es aber nicht müssen:

Code: Alles auswählen

import pygame
from gameBase import *

class gameObject(pygame.sprite.Sprite):
    
    #Konsturktor. Der überschriebene Konstruktor pygame.sprite.Sprite.__init__
    # MUSS aufgerufen werden.
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self._image_original =  pygame.image.load('images/sprite.png')
        self.links = 100
        self.oben = 100
        self.breite = 100
        self.höhe = 100
        self.richtung = 0
        
        #Rect
        left_rect_posX  = 50
        left_rect_posY  = 50
        
        right_rect_posX = 1220
        right_rect_posY = 50
        
        left_rect_HEIGHT   = 150
        right_rect_HEIGHT  = 150
        
        #Circle
        circle_start_posX = int(WIDTH / 2)
        circle_start_posY = int(HEIGHT / 2)
        
        circle_posY = circle_start_posY
        circle_posX = circle_start_posX
    
    #Update wird in jedem Frame vor dem Zeichnen aufgerufen. 
    #Hier wird das Objekt (insbes. image und rect) angepasst.
    def update(self):
        
        left_rect_can_move_upwards    = True
        left_rect_can_move_downwards  = True
        right_rect_can_move_upwards   = True
        right_rect_can_move_downwards = True
        
        #Circle movement factor
        cmfX = 450
        cmfY = 450
        
        #Circle movement
        circle_time_passed = clock.tick(60)
        circle_time_sec = circle_time_passed / 1000.0
        circle_posX += cmfX * circle_time_sec
        circle_posY += cmfY * circle_time_sec
    
        
Ich habe mein eigens Programm geschrieben und möchte einen Konstruktor nach diesem Prinzip anlegen. Bei mir wird allerdings immer der Fehler:
NameError: name 'self' is not defined
anzeigt.

Hier ist meine Klasse:

Code: Alles auswählen

@dataclass
class Cell(self):
  
  def __init__(self):
    self.zeile = 0
    self.spalte = 0
    self.mine = False
    self.aufgedeckt = False
    self.markiert = False
    self.anzMinenDrumrum = int = 0


  #Zeichenroutine innerhalb der Klasse
  def show(self):
    pos = (self.spalte*abstand, self.zeile*abstand)
    if self.aufgedeckt:
      if self.mine:
        screen.blit(bild_mine, pos)
      else:
        screen.blit(bild_aufgedeckt[self.anzMinenDrumrum], pos)
    else:
      if self.markiert:
        screen.blit(bild_markiert, pos)
      else:
        screen.blit(bild_normal, pos)
  
  #Wieviel Minen drumrum?
  def anzMinenErmitteln(self):
    for pos in benachbarteFelder:
      neueZeile, neueSpalte = self.zeile + pos[0], self.spalte + pos[1]
      if gültig(neueZeile, neueSpalte) and matrix[neueZeile*raster+neueSpalte].mine:
        self.anzMinenDrumrum += 1
Wie muss ich self definieren, dass es klappt?
Über eine Antwort würde ich mich sehr freuen :)
DieFragerin
Sirius3
User
Beiträge: 10900
Registriert: Sonntag 21. Oktober 2012, 17:20

Montag 2. Dezember 2019, 15:20

Erst einmal zum Code an sich: eingedrückt wird in Python immer mit vier Leerzeichen pro Ebene, nicht zwei. Methoden und Attribute schreibt man wie Variablennamen klein_mit_unterstrich.

In den Klammern nach Cell gehören die Elternklassen. Bei Dir also nichts.

Weitere Anmwrkungen: warum dekoeIUI erst Du die Klasse mit dataclass?
Das int bei anzMinenDrumrum ist falsch.
Alles was eine Methode braucht muss sie auch über ihre Argumente bekommen. Bei show fehlen abstand screen und die ganzen Bilder. Bei anzMinenErmitteln benachbarteFelder, matrix und raster.

Codedopplung sollte man vermeiden. In show sollte es nur ein screen.blib geben.
Benutzeravatar
__blackjack__
User
Beiträge: 4681
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Montag 2. Dezember 2019, 17:34

@diefragerin: Mal inhaltlich war die Idee mit `dataclass` vielleicht gar nicht schlecht, denn für meinen Geschmack macht dieses `Cell`-Objekt zu viel. Sachen die Wissen über die Welt, also das Minenfeld, benötigen, würde ich da nicht rein stecken. (Wobei ich `dataclass` doof finde und lieber das externe `attr`-Modul bevorzuge, weil man da keine Typen angeben muss.)

`anzMinenErmitteln()` zum Beispiel würde ich nicht die Zelle selbst ermitteln lassen. Die Methode sollte aber mindestens so geschrieben sein, dass man sie mehr als einmal aufrufen kann, ohne dass das Programm falsche Ergebnisse produziert.
“Give a man a fire and he's warm for a day, but set fire to him and he's warm for the rest of his life.”
— Terry Pratchett, Jingo
Antworten