0

How can I split this class into several simpler ones, using the principle of single responsibility? There is this awful class:

# engine for game logic
import HB_classLib as cllib
from card_mech import *
from pygame import Color, display
import itertools as itools
from turn import Turn


def genSlots(details, screen):
    """Generating slots for cards"""
    base = [10, 570, 85, 670]
    for i in range(8):
        typlpx = 420 + (i - 4) * 95 if i >= 4 else base[0] + i * 95
        l1 = [typlpx, base[1], typlpx + 75, base[1]]
        l2 = [typlpx, base[1], typlpx, base[3]]
        l3 = [typlpx, base[3], typlpx + 75, base[3]]
        l4 = [typlpx + 75, base[1], typlpx + 75, base[3]]
        details.append(cllib.CardSlot(screen, [l1, l2, l3, l4],
                                      Color("white"), bn=3))


class Engine:
    """Engine which will calculate gameClasses's interactions"""

    def __init__(self, screen, usnames, mode=1):
        self.names_frame = (cllib.Text(usnames[0].get_value(), 36, Color("white")),
                            cllib.Text(usnames[1].get_value(), 36, Color("white")))

        self.screen = screen

        self.mode = mode
        self.mod_buttons = [cllib.Button((260, 340), (300, 90), Color("gold"),
                                         "Divided field", None, 54, xIndF=40, yIndF=30),
                            cllib.Button((260, 450), (300, 90), Color("yellow"),
                                         "No man's land", None, 54, xIndF=20, yIndF=30)]

        self.start_cards = [MeleeCard(Image_fn="images/card1.jpg", pos=(10, 575), health=5, attack=3),
                            CavalryCard(Image_fn="images/card2.xcf", pos=(108, 575), health=3, attack=3),
                            CavalryCard(Image_fn="images/card3.xcf", pos=(198, 575), health=5, attack=4)]
        self.pl = Player()
        self.pl2 = Player()

        self.map = cllib.Map()
        self.currlvlmap = cllib.LvlMap()

        self.borderline = cllib.Line(self.screen, [400, 0, 400, 480], "black", 3)
        self.blno_mans_land = [cllib.Line(self.screen, [240, 0, 240, 480], "blue", 3),
                               cllib.Line(self.screen, [560, 0, 560, 480], "red", 3)]

        self.turnButton = cllib.Button((360, 485), (80, 80), Color("#E0FFFF"),
                                       "End Turn", None, 24,
                                       xIndF=5, yIndF=35, shape='round', fontColor="#800000")
        self.turnArrow = cllib.Image("images/turn_arrow.jpg", (360, 680), imSize=(90, 120))
        self.turnFight = cllib.Image("images/fight.jpg", (360, 680), imSize=(90, 120))
        self.turneng = Turn(self.pl, self.pl2, self)

        self.details = [self.currlvlmap, self.turnButton, self.turnArrow, self.start_cards]
        self.cardpos_acc = [i.pos for i in self.start_cards]

    def up_phase(self):
        """Increase phase ratio unconditionly"""
        +self.turneng

    def check_turns(self, transformed, is_increase=True):
        self.up_phase() if is_increase else None
        self.turneng.do_logic()
        match self.turneng.phase:
            case 0:
                self.details[2] = cllib.Image(self.turnArrow.image,
                                              (360, 680), imSize=(90, 120)
                                              )

            case 1:
                self.details[2] = cllib.Image(transformed,
                                              (360, 680), imSize=(90, 120))
            case 2:
                self.details[2] = cllib.Image(self.turnFight.image,
                                              (360, 680), imSize=(90, 120)
                                              )

    def start(self):
        """Create default settings and init needed classes, draw map with mods buttons"""
        self.pl.hand.fill([self.start_cards[0], self.start_cards[1]])
        self.pl2.hand.fill([self.start_cards[2]])
        self.map.fill_with(self.mod_buttons)
        self.map.draw(self.screen)

    def turn_level(self):
        """Turn on level, generate and draw level's map, setting up selected mode"""
        self.map.should_draw = False
        for btn in self.mod_buttons:
            btn.keepOn = False
        self.currlvlmap.set(self.screen)
        genSlots(self.details, self.screen)

    def update_map(self):
        self.map.draw(self.screen)

    def update_level(self):
        nested = lambda b: b is self.start_cards or isinstance(b, list | tuple)
        for det in self.details:
            det.draw(self.screen) if not nested(det) else [atom.draw(self.screen) for atom in det]
        blitter = lambda align, factor: (
            self.screen.blit(name.image, (align + index * factor - len(str(name.text)) * 6, 500))
            for index, name in enumerate(self.names_frame)
        )
        match self.mode:
            case 1:
                self.borderline.draw()
                blitter(200, 400)
            case 2:
                for el in self.blno_mans_land: el.draw()
                blitter(120, 560)
        display.flip()

    def fight(self):
        pass

I tried to separate this class into a Starter class, an Updater class, a TurnChecker class, and a FightMechanicsExecutor class, but the result was that each class was dependent on each other and, of course, this structure was not viable.

In addition, I have already moved the function genSlots outside the class, but this doesn't greatly simplify the code.

khelwood
  • 55,782
  • 14
  • 81
  • 108
VladSkarn
  • 1
  • 1

0 Answers0