Vorbereitungsphase für ein Spiel

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Twize
User
Beiträge: 3
Registriert: Samstag 11. Februar 2023, 05:40

Guten Morgen zusammen,

ich bin derzeit dabei ein Geschenk für meine Frau zu erstellen(ein Spiel aus Ihrer Heimat, Game of the Generals), jedoch bin ich leider komplett neu in diesem Thema..
Mir ist bewusst, dass dies kein guter Anfang ist um Python zu lernen aber ich war noch fest am glauben, dass ich es bis zum 14.02 fertigstellen kann (Mittlerweile bin ich mir bewusst, dass dies nichts wird :) ).

Ich bin hier an meine Grenzen gekommen:
Ich hätte gerne eine Vorbereitungsphase wenn man das Spiel startet, dass beide Spieler ihre Figuren auf ihrer Seite bewegen können wie sie wollen.
Spieler 1 mit der Farbe "w" soll die Teile im Bereich 5 0 - 7 8 und Spieler 2 mit der Farbe "b" im Bereich 0 0 - 3 8 bewegen können wie sie wollen (Das board ist bo = Board(8, 9))

Sobald beide Spieler Fertig sind, können Sie einen Ready_Button klicken und wenn dies beide getan haben, soll das normale spiel beginnen mit abwechselnder runde W,B,W,B etc. und die normalen definierten "valid_moves" sollten erst dann aktiviert sein.

bis jetzt printe ich nur, dass Player 1 und 2 Ready ist:

player1_ready = True
print("Player 1 is ready")
elif self.player_number == 2:
player2_ready = True
print("Player 2 is ready")

Ich glaube auch, dass der code den ich habe relativ schlecht und unnötig lang ist aber ich mache dies erst seitdem 04.02 und lese dafür viel und schaue viele Videos zur Hilfe, daher Entschuldigung!

Ich hoffe, jemand hat die Zeit mir ein wenig zu helfen oder ein paar kleine Tipps zu gehen :) Vielen Dank!

Da mir nicht bewusst ist, was genau ich ändern muss und wo poste ich einfach mal alles was ich bisher habe:

game.py:

Code: Alles auswählen

import pygame
import os
from piece import FiveStarGeneral
from board import Board

board = pygame.transform.scale(pygame.image.load(os.path.join("img", "board.png")), (1250, 1100))
rect = (12, 12, 1228, 1082)


def redraw_gameWindow(win, bo):
    win.blit(board, (0, 0))
    bo.draw(win)


def end_screen(win, text):
    pygame.font.init()
    font = pygame.font.SysFont("comicsans", 80)
    txt = font.render(text, 1, (255, 0, 0))
    win.blit(txt, (width / 2 - txt.get_width() / 2, 300))
    pygame.display.update()

    pygame.set_timer(pygame.USEREVENT + 1, 3000)

    run = True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
                run = False
            elif event.type == pygame.KEYDOWN:
                run = False
            elif event.type == pygame.USEREVENT + 1:
                run = False

    pygame.display.update()


def click(pos):
    """

    :return: pos (x, y) ub rabge 0-7 0-7
    """
    x = pos[0]
    y = pos[1]
    if rect[0] < x < rect[0] + rect[2]:
        if rect[1] < y < rect[1] + rect[3]:
            divX = x - rect[0]
            divY = y - rect[0]
            i = int(divX / (rect[2] / 9))
            j = int(divY / (rect[3] / 8))
            return i, j

pygame.font.init()
font = pygame.font.SysFont("comicsans", 80)

class Button():
    def __init__(self, image, x_pos, y_pos, text_input, player_number):
        self.image = image
        self.x_pos = x_pos
        self.y_pos = y_pos
        self.rect = self.image.get_rect(center=(self.x_pos, self.y_pos))
        self.player_number = player_number

    def update(self):
        win.blit(self.image, self.rect)

    #check if the button is pressed
    def checkForInput(self, position):
        if position[0] in range(self.rect.left, self.rect.right) and position[1] in range(self.rect.top, self.rect.bottom):
            if self.player_number == 1:
                player1_ready = True
                print("Player 1 is ready")
            elif self.player_number == 2:
                player2_ready = True
                print("Player 2 is ready")

button_surface = pygame.image.load(os.path.join("img", "rdy.png"))
button_surface = pygame.transform.scale(button_surface, (400, 100))

button1 = Button(button_surface, 625, 620, "Player 1", 1)
button2 = Button(button_surface, 625, 480, "Player 2", 2)

def main():
    turn = "w"
    bo = Board(8, 9)
    player1_ready = False
    player2_ready = False
    both_players_ready = False
    clock = pygame.time.Clock()
    run = True
    while run:
        clock.tick(10)

        redraw_gameWindow(win, bo)
        button1.update()
        button2.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                quit()
                pygame.quit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                button1.checkForInput(pygame.mouse.get_pos())
                button2.checkForInput(pygame.mouse.get_pos())

            if player1_ready and player2_ready:
                both_players_ready = True

                if event.type == pygame.MOUSEBUTTONUP and both_players_ready:
                    pos = pygame.mouse.get_pos()
                    bo.update_moves()
                    i, j = click(pos)
                    Change = bo.select(i, j, turn)
                    bo.update_moves()

                    if Change:
                        if turn == "w":
                            turn = "b"
                        else:
                            turn = "w"
            pygame.display.update()


width = 1250
height = 1100
win = pygame.display.set_mode((width, height))
pygame.display.set_caption("Game of the Generals")
main()
board.py

Code: Alles auswählen

from piece import FiveStarGeneral
from piece import FourStarGeneral
from piece import ThreeStarGeneral
from piece import TwoStarGeneral
from piece import OneStarGeneral
from piece import Colonel
from piece import LieutenantColonel
from piece import Major
from piece import Captain
from piece import FirstLieutenant
from piece import SecondLieutenant
from piece import Sergeant
from piece import Private
from piece import Spy
from piece import Flag
import pygame
import time
from piece import RANK_ELIMINATIONS



class Board:
    rect = (12, 12, 1228, 1082)
    StartX = rect[0]
    StartY = rect[1]
    def __init__(self, rows, cols):
        self.rows = rows
        self.cols = cols

        self.board = [[0 for x in range(9)] for _ in range(rows)]

        self.board[0][0] = FiveStarGeneral(0, 0, "b", "FiveStarGeneral")
        self.board[0][1] = FourStarGeneral(0, 1, "b", "FourStarGeneral")
        self.board[0][2] = ThreeStarGeneral(0, 2, "b", "ThreeStarGeneral")
        self.board[0][3] = TwoStarGeneral(0, 3, "b", "TwoStarGeneral")
        self.board[0][4] = OneStarGeneral(0, 4, "b", "OneStarGeneral")
        self.board[0][5] = Colonel(0, 5, "b", "Colonel")
        self.board[0][6] = LieutenantColonel(0, 6, "b", "LieutenantColonel")
        self.board[0][7] = Major(0, 7, "b", "Major")
        self.board[0][8] = Captain(0, 8, "b", "Captain")

        self.board[1][0] = FirstLieutenant(1, 0, "b", "FirstLieutenant")
        self.board[1][1] = SecondLieutenant(1, 1, "b", "SecondLieutenant")
        self.board[1][2] = Sergeant(1, 2, "b", "Sergeant")
        self.board[1][3] = Private(1, 3, "b", "Private")
        self.board[1][4] = Private(1, 4, "b", "Private")
        self.board[1][5] = Private(1, 5, "b", "Private")
        self.board[1][6] = Private(1, 6, "b", "Private")
        self.board[1][7] = Private(1, 7, "b", "Private")
        self.board[1][8] = Private(1, 8, "b", "Private")

        self.board[2][0] = Spy(2, 0, "b", "Spy")
        self.board[2][1] = Spy(2, 1, "b", "Spy")
        self.board[2][2] = Flag(2, 2, "b", "Spy")

        self.board[7][0] = FiveStarGeneral(7, 0, "w", "FiveStarGeneral")
        self.board[7][1] = FourStarGeneral(7, 1, "w", "FourStarGeneral")
        self.board[7][2] = ThreeStarGeneral(7, 2, "w", "ThreeStarGeneral")
        self.board[7][3] = TwoStarGeneral(7, 3, "w", "TwoStarGeneral")
        self.board[7][4] = OneStarGeneral(7, 4, "w", "OneStarGeneral")
        self.board[7][5] = Colonel(7, 5, "w", "Colonel")
        self.board[7][6] = LieutenantColonel(7, 6, "w", "LieutenantColonel")
        self.board[7][7] = Major(7, 7, "w", "Major")
        self.board[7][8] = Captain(7, 8, "w", "Captain")

        self.board[6][0] = FirstLieutenant(6, 0, "w", "FirstLieutenant")
        self.board[6][1] = SecondLieutenant(6, 1, "w", "SecondLieutenant")
        self.board[6][2] = Sergeant(6, 2, "w", "Sergeant")
        self.board[6][3] = Private(6, 3, "w", "Private")
        self.board[6][4] = Private(6, 4, "w", "Private")
        self.board[6][5] = Private(6, 5, "w", "Private")
        self.board[6][6] = Private(6, 6, "w", "Private")
        self.board[6][7] = Private(6, 7, "w"," Private")
        self.board[6][8] = Private(6, 8, "w", "Private")

        self.board[5][0] = Spy(5, 0, "w", "Spy")
        self.board[5][1] = Spy(5, 1, "w", "Spy")
        self.board[5][2] = Flag(5, 2, "w", "Flag")


    def update_moves(self):
        for i in range(self.rows):
            for j in range(self.cols):
                if self.board[i][j] != 0:
                    self.board[i][j].update_valid_moves(self.board)

    def draw(self, win):
        for i in range(self.rows):
            for j in range(self.cols):
                if self.board[i][j] != 0:
                    self.board[i][j].draw(win)

    def select(self, col, row, color):
        changed = False
        prev = (-1, -1)
        for i in range(self.rows):
            for j in range(self.cols):
                if self.board[i][j] != 0:
                    if self.board[i][j].selected:
                        prev = (i, j)

        # if piece
        if self.board[row][col] == 0:
            if prev != (-1, -1) and self.board[prev[0]][prev[1]] and not isinstance(self.board[prev[0]][prev[1]], int):
                if isinstance(self.board[prev[0]][prev[1]], object) and hasattr(self.board[prev[0]][prev[1]],
                                                                                'selected'):
                    moves = self.board[prev[0]][prev[1]].move_list
                    if (col, row) in moves:
                        self.move(prev, (row, col))
                        changed = True
            self.reset_selected()
        else:
            if prev != (-1, -1) and self.board[prev[0]][prev[1]] and not isinstance(self.board[prev[0]][prev[1]],
                                                                                    int) and \
                    isinstance(self.board[prev[0]][prev[1]], object) and hasattr(self.board[prev[0]][prev[1]],
                                                                                 'selected') and \
                    self.board[prev[0]][prev[1]].color != self.board[row][col].color:
                moves = self.board[prev[0]][prev[1]].move_list
                if (col, row) in moves:
                        self.move(prev, (row, col))
                        changed = True

                self.reset_selected()
                if not isinstance(self.board[row][col], int):
                    if self.board[row][col].color == color:
                        self.board[row][col].selected = True
            else:
                self.reset_selected()
                if not isinstance(self.board[row][col], int):
                    if self.board[row][col].color == color:
                        self.board[row][col].selected = True

        return  changed



    def reset_selected(self):
        for i in range(self.rows):
            for j in range(self.cols):
                if self.board[i][j] != 0:
                    self.board[i][j].selected = False

    def move(self, start, end):
        nBoard = self.board[:]
        start_piece = nBoard[start[0]][start[1]]
        end_piece = nBoard[end[0]][end[1]]
        start_rank = start_piece.__class__.__name__
        end_rank = end_piece.__class__.__name__

        if end_piece == 0:
            # No piece at the end position, move the piece
            start_piece.change_pos((end[0], end[1]))
            nBoard[end[0]][end[1]] = start_piece
            nBoard[start[0]][start[1]] = 0
        elif end_rank in RANK_ELIMINATIONS[start_rank]:
            # End piece has a lower ranking, eliminate it
            start_piece.change_pos((end[0], end[1]))
            nBoard[end[0]][end[1]] = start_piece
            nBoard[start[0]][start[1]] = 0
        elif start_rank in RANK_ELIMINATIONS[end_rank]:
            # Start piece has a lower ranking, eliminate it
            nBoard[start[0]][start[1]] = 0
        elif start_rank == end_rank:
            # Pieces have equal ranking, eliminate both
            nBoard[end[0]][end[1]] = 0
            nBoard[start[0]][start[1]] = 0

        self.board = nBoard
pieces.py

Code: Alles auswählen

import pygame
import os

b_Five_Star_General = pygame.image.load(os.path.join("img", "Five_Star_General_Black.png"))
b_Four_Star_General = pygame.image.load(os.path.join("img", "Four_Star_General_Black.png"))
b_Three_Star_General = pygame.image.load(os.path.join("img", "Three_Star_General_Black.png"))
b_Two_Star_General = pygame.image.load(os.path.join("img", "Two_Star_General_Black.png"))
b_One_Star_General = pygame.image.load(os.path.join("img", "One_Star_General_Black.png"))
b_Colonel = pygame.image.load(os.path.join("img", "Colonel_Black.png"))
b_Lieutenant_Colonel = pygame.image.load(os.path.join("img", "Lieutenant_Colonel_Black.png"))
b_Major = pygame.image.load(os.path.join("img", "Major_Black.png"))
b_Captain = pygame.image.load(os.path.join("img", "Captain_Black.png"))
b_First_Lieutenant = pygame.image.load(os.path.join("img", "First_Lieutenant_Black.png"))
b_Second_Lieutenant = pygame.image.load(os.path.join("img", "Second_Lieutenant_Black.png"))
b_Sergeant = pygame.image.load(os.path.join("img", "Sergeant_Black.png"))
b_Private = pygame.image.load(os.path.join("img", "Private_Black.png"))
b_Spy = pygame.image.load(os.path.join("img", "Spy_Black.png"))
b_Flag = pygame.image.load(os.path.join("img", "Flag_Black.png"))

w_Five_Star_General = pygame.image.load(os.path.join("img", "Five_Star_General_White.png"))
w_Four_Star_General = pygame.image.load(os.path.join("img", "Four_Star_General_White.png"))
w_Three_Star_General = pygame.image.load(os.path.join("img", "Three_Star_General_White.png"))
w_Two_Star_General = pygame.image.load(os.path.join("img", "Two_Star_General_White.png"))
w_One_Star_General = pygame.image.load(os.path.join("img", "One_Star_General_White.png"))
w_Colonel = pygame.image.load(os.path.join("img", "Colonel_White.png"))
w_Lieutenant_Colonel = pygame.image.load(os.path.join("img", "Lieutenant_Colonel_White.png"))
w_Major = pygame.image.load(os.path.join("img", "Major_White.png"))
w_Captain = pygame.image.load(os.path.join("img", "Captain_White.png"))
w_First_Lieutenant = pygame.image.load(os.path.join("img", "First_Lieutenant_White.png"))
w_Second_Lieutenant = pygame.image.load(os.path.join("img", "Second_Lieutenant_White.png"))
w_Sergeant = pygame.image.load(os.path.join("img", "Sergeant_White.png"))
w_Private = pygame.image.load(os.path.join("img", "Private_White.png"))
w_Spy = pygame.image.load(os.path.join("img", "Spy_White.png"))
w_Flag = pygame.image.load(os.path.join("img", "Flag_White.png"))

b = [b_Five_Star_General, b_Four_Star_General, b_Three_Star_General, b_Two_Star_General, b_One_Star_General,
     b_Colonel, b_Lieutenant_Colonel, b_Major, b_Captain, b_First_Lieutenant, b_Second_Lieutenant, b_Sergeant,
     b_Private, b_Spy, b_Flag]
w = [w_Five_Star_General, w_Four_Star_General, w_Three_Star_General, w_Two_Star_General, w_One_Star_General,
     w_Colonel, w_Lieutenant_Colonel, w_Major, w_Captain, w_First_Lieutenant, w_Second_Lieutenant, w_Sergeant,
     w_Private, w_Spy, w_Flag]

B = []
W = []

for img in b:
    B.append(pygame.transform.scale(img, (130, 128)))

for img in w:
    W.append(pygame.transform.scale(img, (130, 128)))

RANKS = ['FiveStarGeneral', 'FourStarGeneral', 'ThreeStarGeneral', 'TwoStarGeneral', 'OneStarGeneral',
         'Colonel', 'LieutenantColonel', 'Major', 'Captain', 'FirstLieutenant', 'SecondLieutenant',
         'Sergeant', 'Spy', 'Private', 'Flag']

RANK_ELIMINATIONS = dict(
    FiveStarGeneral=['FourStarGeneral', 'ThreeStarGeneral', 'TwoStarGeneral', 'OneStarGeneral', 'Colonel',
                     'LieutenantColonel', 'Major', 'Captain', 'FirstLieutenant', 'SecondLieutenant', 'Sergeant',
                     'Private', 'Flag'],
    FourStarGeneral=['ThreeStarGeneral', 'TwoStarGeneral', 'OneStarGeneral', 'Colonel', 'LieutenantColonel', 'Major',
                     'Captain', 'FirstLieutenant', 'SecondLieutenant', 'Sergeant', 'Private', 'Flag'],
    ThreeStarGeneral=['TwoStarGeneral', 'OneStarGeneral', 'Colonel', 'LieutenantColonel', 'Major', 'Captain',
                      'FirstLieutenant', 'SecondLieutenant', 'Sergeant', 'Private', 'Flag'],
    TwoStarGeneral=['OneStarGeneral', 'Colonel', 'LieutenantColonel', 'Major', 'Captain', 'FirstLieutenant',
                    'SecondLieutenant', 'Sergeant', 'Private', 'Flag'],
    OneStarGeneral=['Colonel', 'LieutenantColonel', 'Major', 'Captain', 'FirstLieutenant', 'SecondLieutenant',
                    'Sergeant', 'Private', 'Flag'],
    Colonel=['LieutenantColonel', 'Major', 'Captain', 'FirstLieutenant', 'SecondLieutenant', 'Sergeant', 'Private',
             'Flag'],
    LieutenantColonel=['Major', 'Captain', 'FirstLieutenant', 'SecondLieutenant', 'Sergeant', 'Private', 'Flag'],
    Major=['Captain', 'FirstLieutenant', 'SecondLieutenant', 'Sergeant', 'Private', 'Flag'],
    Captain=['FirstLieutenant', 'SecondLieutenant', 'Sergeant', 'Private', 'Flag'],
    FirstLieutenant=['SecondLieutenant', 'Sergeant', 'Private', 'Flag'],
    SecondLieutenant=['Sergeant', 'Private', 'Flag'],
    Sergeant=['Private', 'Flag'],
    Spy=['FiveStarGeneral', 'FourStarGeneral', 'ThreeStarGeneral', 'TwoStarGeneral', 'OneStarGeneral', 'Colonel',
         'LieutenantColonel', 'Major', 'Captain', 'FirstLieutenant', 'SecondLieutenant', 'Sergeant','Flag'],
    Private=['Spy', 'Flag'], Flag=['Flag'])


class Piece:
    img = -1
    rect = (12, 12, 1228, 1082)
    StartX = rect[0]
    StartY = rect[1]

    def __init__(self, row, col, color,rank):
        self.row = row
        self.col = col
        self.color = color
        self.selected = False
        self.move_list = []
        self.rank = rank

    def valid_moves(self, board):
        pass

    def isSelected(self):
        return self.selected

    def update_valid_moves(self, board):
        self.move_list = self.valid_moves(board)

    def draw(self, win):
        if self.color == "w":
            drawThis = W[self.img]
        else:
            drawThis = B[self.img]

        if self.selected:
            moves = self.move_list

            for move in moves:
                x = 70 + self.StartX + (move[0] * self.rect[2] / 8.95)
                y = 70 + self.StartY + (move[1] * self.rect[2] / 9)
                pygame.draw.circle(win, (255, 0, 0), (x, y), 15)



        x = self.StartX + (self.col * self.rect[2] / 8.95)
        y = self.StartY + (self.row * self.rect[2] / 9)

        win.blit(drawThis, (x, y))
        if self.selected:
            pygame.draw.rect(win, (255, 0, 0), (x, y, 130, 128), 2)



    def change_pos(self, pos):
        self.row = pos[0]
        self.col = pos[1]

    def __str__(self):
        return str(self.col) + str(self.row)

class FiveStarGeneral(Piece):
    img = 0

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class FourStarGeneral(Piece):
    img = 1

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class ThreeStarGeneral(Piece):
    img = 2

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class TwoStarGeneral(Piece):
    img = 3

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class OneStarGeneral(Piece):
    img = 4

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class Colonel(Piece):
    img = 5

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class LieutenantColonel(Piece):
    img = 6

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class Major(Piece):
    img = 7

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class Captain(Piece):
    img = 8

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class FirstLieutenant(Piece):
    img = 9

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class SecondLieutenant(Piece):
    img = 10

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class Sergeant(Piece):
    img = 11

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class Private(Piece):
    img = 12

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class Spy(Piece):
    img = 13

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # TOP MIDDLE
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))
            elif p.color != self.color:
                moves.append((j, i - 1))

        # BOTTOM MIDDLE
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))
            elif p.color != self.color:
                moves.append((j, i + 1))

        # MIDDLE LEFT
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))
            elif p.color != self.color:
                moves.append((j - 1, i))

        # MIDDLE RIGHT
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))
            elif p.color != self.color:
                moves.append((j + 1, i))

        return moves


class Flag(Piece):
    img = 14

    def __init__(self, row, col, color, rank):
        super().__init__(row, col, color, rank)

    def valid_moves(self, board):
        i = self.row
        j = self.col

        moves = []

        # Check moves to top
        if i > 0:
            p = board[i - 1][j]
            if p == 0:
                moves.append((j, i - 1))

        # Check moves to bottom
        if i < 7:
            p = board[i + 1][j]
            if p == 0:
                moves.append((j, i + 1))

        # Check moves to left
        if j > 0:
            p = board[i][j - 1]
            if p == 0:
                moves.append((j - 1, i))

        # Check moves to right
        if j < 8:
            p = board[i][j + 1]
            if p == 0:
                moves.append((j + 1, i))

        return moves
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Fuer einen Anfang gar nicht schlecht. Bitte in Zukunft Code in die dafuer vorgesehenen Tags setzen, das ist der </>-Knopf im vollstaendigen Editor. Ich habe das mal fuer dich gemacht, weil das viel ist. Inhaltlich kann ich erst spaeter was sagen, ggf. gibt's auch andere, die da schon was beitragen koennen.
Twize
User
Beiträge: 3
Registriert: Samstag 11. Februar 2023, 05:40

__deets__ hat geschrieben: Samstag 11. Februar 2023, 10:32 Fuer einen Anfang gar nicht schlecht. Bitte in Zukunft Code in die dafuer vorgesehenen Tags setzen, das ist der </>-Knopf im vollstaendigen Editor. Ich habe das mal fuer dich gemacht, weil das viel ist. Inhaltlich kann ich erst spaeter was sagen, ggf. gibt's auch andere, die da schon was beitragen koennen.

Vielen Dank dafür :) Werde ich beim nächsten mal beachten! :D
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast sehr viel kopierten Codes. Machen wir das mal am Beispiel von pieces.py:
Du willst sicher die Bilder relativ zur py-Datei suchen und nicht relativ zum aktuellen Arbeitsverzeichnis. Mit `RANKS` hast Du schon eine Liste mit den Namen, das mußt Du nicht für weiße und schwarze Bild-Dateien wiederholen.
Konstanten werden KOMPLETT_GROSS geschrieben.
Magische Werte sollten nicht einfach so auftauchen, was bedeutet 8.92? Vor allem, wenn sich sich mehrfach im Code wiederholen, sollten sie als Konstanten definiert werden.
Wenn in __init__ eh nichts anders gemacht wird, als die Basis-Funktion aufzurufen, kann man es gleich ganz weglassen.
Bei `valid_moves` wird sehr oft das Hinzufügen der Positionen in `moves` wiederholt. Das kann man mit der passenden Datenstruktur vermeiden.

Code: Alles auswählen

class FiveStarGeneral(Piece):
    MOVES = [(0, -1), (0, 1), (-1, 0), (1, 0)]
    def valid_moves(self, board):
        moves = []
        for dx, dy in MOVES:
            col = self.col + dx
            row = self.row + dy
            if 0 <= col <= 7 and 0 <= row <= 8:
                p = board[row][col]
                if not p or p.color != self.color:
                    moves.append((col, row))
        return moves
Nun unterscheiden sich die Klassen gar nicht, können also alle weg, es ist nur noch `Piece` nötig.
Bleibt also insgesamt:

Code: Alles auswählen

import pygame
from pathlib import Path

IMAGE_PATH = Path(__file__).parent / "img"
IMAGE_SIZE = (130, 128)

RANKS = ['Spy', 'FiveStarGeneral', 'FourStarGeneral', 'ThreeStarGeneral', 'TwoStarGeneral', 'OneStarGeneral',
         'Colonel', 'LieutenantColonel', 'Major', 'Captain', 'FirstLieutenant', 'SecondLieutenant',
         'Sergeant', 'Private', 'Flag']

BLACK_IMAGES = {
    rank: pygame.transform.scale(
        pygame.image.load(IMAGE_PATH / rank + "_black.png"),
        IMAGE_SIZE
    )
    for rank in RANKS
}

WHITE_IMAGES = {
    rank: pygame.transform.scale(
        pygame.image.load(IMAGE_PATH / rank + "_white.png")
        IMAGE_SIZE
    )
    for rank in RANKS
}

RANK_ELIMINATIONS = {
    rank: RANKS[RANKS.index(r)+1:] for rank in RANKS
}
RANK_ELIMINATIONS["Spy"] = [
    'FiveStarGeneral', 'FourStarGeneral', 'ThreeStarGeneral', 'TwoStarGeneral',
    'OneStarGeneral', 'Colonel', 'LieutenantColonel', 'Major', 'Captain',
    'FirstLieutenant', 'SecondLieutenant', 'Sergeant','Flag']
RANK_ELIMINATIONS["Private"] = ['Spy', 'Flag']
RANK_ELIMINATIONS["Flag"] = ['Flag']


class Piece:
    RECT = (12, 12, 137, 137)
    MOVES = [(0, -1), (0, 1), (-1, 0), (1, 0)]

    def __init__(self, row, col, color, rank):
        self.row = row
        self.col = col
        self.color = color
        self.selected = False
        self.moves = []
        self.rank = rank

    def valid_moves(self, board):
        moves = []
        for dx, dy in self.MOVES:
            col = self.col + dx
            row = self.row + dy
            if 0 <= col <= 7 and 0 <= row <= 8:
                p = board[row][col]
                if not p or (self.rank != "Flag" and p.color != self.color):
                    moves.append((col, row))
        return moves

    def is_selected(self):
        return self.selected

    def update_valid_moves(self, board):
        self.moves = self.valid_moves(board)

    def draw(self, win):
        rank = type(self).__name__
        images = WHITE_IMAGES if self.color == "w" else BLACK_IMAGES
        image = images[self.rank]

        if self.selected:
            for move in self.moves:
                x = 70 + self.RECT[0] + move[0] * self.RECT[2]
                y = 70 + self.RECT[1] + move[1] * self.RECT[3]
                pygame.draw.circle(win, (255, 0, 0), (x, y), 15)

        x = self.RECT[0] + self.col * self.RECT[2]
        y = self.RECT[1] + self.row * self.RECT[3]

        win.blit(image, (x, y))
        if self.selected:
            pygame.draw.rect(win, (255, 0, 0), (x, y) + IMAGE_SIZE, 2)

    def change_pos(self, pos):
        self.row, self.col = pos

    def __str__(self):
        return f"{self.col}/{self.row}"
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

In board.py ändert sich dadurch natürlich auch einiges.
rect, startX und startY werden gar nicht genutzt. `rows` und `cols` sind fix, das als Attribute zu übergeben, ist also verwirrend. Leere Felder sollten den Wert None haben, nicht 0.
Mit Indices arbeitet man nicht, wenn man es nicht vermeiden kann, wie in `update_moves` oder `draw`.
Was dann in `select` gemacht wird, ist sehr kompliziert. Ein Feld kann ja nur eine Figur enthalten oder leer sein, isinstance ist ein deutliches Zeichen, dass man im Design einen Fehler gemacht hat, zumal alles von object erbt, ein isinstance(xyz, object) ist also immer wahr.
Statt (-1, -1) ist hier auch None die besser Kennung für "nicht vorhanden".
Warum machst Du in `move` eine Kopie des Boards?
Wenn in jedem if-Zweig der selbe Code vorkommt, kann man das auch einfach danach einmal schreiben.

Code: Alles auswählen

import pygame
import time
from piece import Piece, RANK_ELIMINATIONS

FIRST_ROW = ["FiveStarGeneral", "FourStarGeneral", "ThreeStarGeneral",
    "TwoStarGeneral", "OneStarGeneral", "Colonel", "LieutenantColonel",
    "Major", "Captain"]
SECOND_ROW = ["FirstLieutenant", "SecondLieutenant", "Sergeant",
    "Private", "Private", "Private", "Private", "Private", "Private"]
THIRD_ROW = ["Spy", "Spy", "Flag"]

class Board:
    def __init__(self):
        self.board = [[None] * 9 for _ in range(8)]
        for index, piece in enumerate(FIRST_ROW):
            self.board[0][index] = Piece(0, index, "b", piece)
            self.board[7][index] = Piece(7, index, "w", piece)
        for index, piece in enumerate(SECOND_ROW):
            self.board[1][index] = Piece(1, index, "b", piece)
            self.board[6][index] = Piece(6, index, "w", piece)
        for index, piece in enumerate(THIRD_ROW):
            self.board[2][index] = Piece(2, index, "b", piece)
            self.board[5][index] = Piece(5, index, "w", piece)

    def update_moves(self):
        for row in self.board:
            for piece in row:
                if piece:
                    piece.update_valid_moves(self.board)

    def draw(self, win):
        for row in self.board:
            for piece in row:
                if piece:
                    piece.draw(win)

    def reset_selected(self):
        for row in self.board:
            for piece in row:
                if piece:
                    piece.selected = False

    def select(self, col, row, color):
        prev = None
        for row in self.board:
            for piece in row:
                if piece and piece.selected:
                    prev = piece

        changed = False
        if not self.board[row][col]:
            if prev:
                if (col, row) in prev.moves:
                    self.move(prev, (row, col))
                    changed = True
            self.reset_selected()
        else:
            if prev.color != self.board[row][col].color:
                if (col, row) in prev.moves:
                    self.move(prev, (row, col))
                    changed = True
            self.reset_selected()
            if self.board[row][col]:
                if self.board[row][col].color == color:
                    self.board[row][col].selected = True
        return changed

    def move(self, start_piece, end_position):
        end_piece = self.board[end_position[0]][end_position[1]]

        if not end_piece or end_piece.rank in RANK_ELIMINATIONS[start_piece.rank]
            # If no piece at the end position, move the piece
            # or if end piece has a lower ranking, eliminate it
            start_piece.change_pos(end_position)
            self.board[end_position[0]][end_position[1]] = start_piece
        elif start_piece.rank in RANK_ELIMINATIONS[end_piece.rank]:
            # Start piece has a lower ranking, eliminate it
            pass
        elif start_piece.rank == end_piece.rank:
            # Pieces have equal ranking, eliminate both
            self.board[end_position[0]][end_position[1]] = None

        self.board[start_piece.row][start_piece.col] = None
Twize
User
Beiträge: 3
Registriert: Samstag 11. Februar 2023, 05:40

Okay, wow.. mir war schon bewusst, dass ich viel unnötigen Code habe aber das es so viel ist... Vielen Dank dafür.
Da ich sowas zum ersten mal mache, schaue ich mir für jedes Thema ein Video an und versuche dann den Code hinzuzufügen bis es läuft :D
Ich werde lieber doch erstmal die Grundlagen lernen bevor ich solch ein Projekt starte.. würde nur darin enden, alle 2 Minuten zu Googlen oder hier nach Hilfe zu fragen...

Ich sehe aber schon anhand deines Codes, dass es noch einiges zu lernen gibt um unnötig langen code zu vermeiden!

Vielen Dank für die Hilfe :)
Antworten