Du bist nicht angemeldet.

Werbeanzeige

1

01.05.2019, 09:47

Pygame: Tick Tack Toe, was kann ich besser machen?

Hallo :)

Ich habe mit Pygame Tick Tack Toe programmiert und wollte fragen was ich in meinem Code besser machen kann da ich noch ein Anfänger bin. Ich habe Tick Tack Toe programmiert um mich in der Spiele Entwicklung zu verbessern (als Training).

Das Spiel funktioniert aber ich wollte zum Beispiel wissen was ich in Zeile 61-84 tun kann wo abgefragt wird wer gewonnen hat und ob unentschieden ist. Ich könnte mir vorstellen das es leichter zu schreiben ist als wie ich es getan habe :rolleyes: . Oder wie ich übersichtlicher Code und was ich im Code hätte weg lassen können. Ich wollte gerne eure Erfahrungen, Tipps wissen wie ich mich verbessern kann :D

Vielen Dank im voraus :thumbsup:

Tick Tack Toe


(Link)


Main.py

HLSL-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import pygame
from Block import Block
from Player import Player

screenSize = (500,400)
screenTitle = "Tick Tack Toe!"

gridWidth = 3
gridHeight = 3
gridSpace = 10

blocks = []
turnsPlayer1 = []
turnsPlayer2 = []

turn = "Player1"

pygame.init()

screen = pygame.display.set_mode(screenSize)
pygame.display.set_caption(screenTitle)

running = True

clock = pygame.time.Clock()

for y in range(0, gridHeight):
    for x in range(0, gridWidth):
        b = Block(x*(64+gridSpace)+(screenSize[0]/2)-(64+(gridWidth*gridSpace)), y*(64+gridSpace)+(screenSize[1]/2)-(64+(gridHeight*gridSpace)), "block.png")
        blocks.append(b)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        for i in blocks:
            if (turn == "Player1"):
                if (i.click(pygame.mouse.get_pos())):
                    if (event.type == pygame.MOUSEBUTTONDOWN):
                        i.state = "Player1"
                        turnsPlayer1.append(Player(i.x, i.y, "cross.png"))
                        turn = "Player2"
            if (turn == "Player2"):
                if (i.click(pygame.mouse.get_pos())):
                    if (event.type == pygame.MOUSEBUTTONDOWN):
                        i.state = "Player2"
                        turnsPlayer2.append(Player(i.x, i.y, "circle.png"))
                        turn = "Player1"

    screen.fill((50,50,50))
    
    for i in blocks:
        i.render(screen)

    for i in turnsPlayer1:
        i.render(screen)

    for i in turnsPlayer2:
        i.render(screen)

    if (blocks[0].state == "Player1" and blocks[1].state == "Player1" and blocks[2].state == "Player1" or
        blocks[3].state == "Player1" and blocks[4].state == "Player1" and blocks[5].state == "Player1" or
        blocks[6].state == "Player1" and blocks[7].state == "Player1" and blocks[8].state == "Player1" or
        blocks[0].state == "Player1" and blocks[3].state == "Player1" and blocks[6].state == "Player1" or
        blocks[1].state == "Player1" and blocks[4].state == "Player1" and blocks[7].state == "Player1" or
        blocks[2].state == "Player1" and blocks[5].state == "Player1" and blocks[8].state == "Player1" or
        blocks[0].state == "Player1" and blocks[4].state == "Player1" and blocks[8].state == "Player1" or
        blocks[2].state == "Player1" and blocks[4].state == "Player1" and blocks[6].state == "Player1"):
        print("Spieler 1 Gewinnt!")

    if (blocks[0].state == "Player2" and blocks[1].state == "Player2" and blocks[2].state == "Player2" or
        blocks[3].state == "Player2" and blocks[4].state == "Player2" and blocks[5].state == "Player2" or
        blocks[6].state == "Player2" and blocks[7].state == "Player2" and blocks[8].state == "Player2" or
        blocks[0].state == "Player2" and blocks[3].state == "Player2" and blocks[6].state == "Player2" or
        blocks[1].state == "Player2" and blocks[4].state == "Player2" and blocks[7].state == "Player2" or
        blocks[2].state == "Player2" and blocks[5].state == "Player2" and blocks[8].state == "Player2" or
        blocks[0].state == "Player2" and blocks[4].state == "Player2" and blocks[8].state == "Player2" or
        blocks[2].state == "Player2" and blocks[4].state == "Player2" and blocks[6].state == "Player2"):
        print("Spieler 2 Gewinnt!")

    if (blocks[0].canPlace() == False and blocks[1].canPlace() == False and blocks[2].canPlace() == False and
        blocks[3].canPlace() == False and blocks[4].canPlace() == False and blocks[5].canPlace() == False and
        blocks[6].canPlace() == False and blocks[7].canPlace() == False and blocks[8].canPlace() == False):
        print("Unentschieden!")

    pygame.display.update()
    clock.tick(60)

pygame.quit()


Block.py

HLSL-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import pygame

class Block:
    def __init__(self, x, y, image):
        self.image = pygame.image.load(image)
        self.x = x
        self.y = y
        self.width = self.image.get_rect()[2]
        self.height = self.image.get_rect()[3]
        self.state = 0

    def click(self, mousePos):
        mouseX = mousePos[0]
        mouseY = mousePos[1]

        if (mouseX > self.x and mouseX < self.x + self.width and 
            mouseY > self.y and mouseY < self.y + self.height):
            if (self.state == 0):
                return True
        return False

    def canPlace(self):
        if (self.state != 0):
            return False
        return True

    def render(self, screen):
        screen.blit(self.image, (self.x, self.y))


Player.py

HLSL-Quelltext

1
2
3
4
5
6
7
8
9
10
import pygame

class Player:
    def __init__(self, x, y, image):
        self.x = x
        self.y = y
        self.image = pygame.image.load(image)

    def render(self, screen):
        screen.blit(self.image, (self.x, self.y))

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »N4SONIC« (01.05.2019, 09:52)


2

01.05.2019, 11:56

Copy-Past-Code von Zeile 61-69 und 71-79 kann man eigentlich immer vermeiden. Anstelle zu prüfen, ob [im Feld 1 = Spieler 1], [im Feld 2 = Spieler 1] und [im Feld 3 = Spieler 1] ist, kannst du auch prüfen, ob Feld 1 = Feld 2 = Feld 3 ist. Sobald eine Abfrage zutrifft wird ermittelt, ob nun Spieler 1 oder 2 gewonnen hat, je nachdem, welcher Spieler am Zug war. Denn jener, der nicht am Zug ist, kann in diesem Zug auch nicht gewinnen.

Das Unentschieden kann auch wesentlich einfacher gelöst werden. Du zählst die Züge mit und erreicht der Wert dann den 10. Zug (der nicht mehr ausgeführt werden darf), ist das Spiel unentschieden. Das hat auch den Vorteil, dass du den Code zur Gewinnerermittlung nicht vor dem 5. Zug ausführen musst, weil bis dahin auch keiner gewinnen kann. Ein weiterer Vorteil ist, dass es unabhängig der Felderanzahl immer der selbe Code bleibt. Auf deine Weise müsstest du bei 4x4 Felder schon 16x abfragen, ob das jeweilige Feld belegt ist und das nach jeder Runde.

Nox

Supermoderator

Beiträge: 5 282

Beruf: Student

  • Private Nachricht senden

3

05.05.2019, 23:08

man kann auch spalten, zeilen und diagonalenweise prüfen man muss nur die indizes entsprechend berechnen. sprich "for row in range(3): blocks[row*3].state == blocks[row*3+1].state == blocks[row*3+2].state" etc.

Zeile 37 bis 48 zeigt auch viel Redundanz. Einfach mal überlegen welchen Wert z.b. turn hat und ggf mit einem dict ala images = {"P1": img1, "P2":img2} kombinieren.

Generell würde ich von strings als "zustandsvariable" eher abraten. Dafür gibt es Enum.

Zeilen 23 bis 25 in Block.py kann man zu einem return self.state == 0 zusammenfassen.

Sonst sieht es eig garnicht so schlech aus.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Werbeanzeige