Пример #1
0
class SplitScreen(State):
    def __init__(self) -> None:
        self.gameplay1 = Gameplay()
        self.gameplay2 = Gameplay()

        self.popups1: List[Popup] = []
        self.popups2: List[Popup] = []
        self.current_popup1: Optional[Popup] = None
        self.current_popup2: Optional[Popup] = None

        self.finished = False
        self.end_screen = False

    def is_finished(self) -> bool:
        return self.finished

    def initialize(self) -> None:
        self.gameplay1.set_device(ctx.device1)
        self.gameplay1.initialize()

        self.gameplay2.set_device(ctx.device2)
        self.gameplay2.initialize()

    def update(self, switch_state: Callable) -> None:
        if not self.end_screen:
            if self.gameplay1.game_over and not self.gameplay2.game_over:
                self.gameplay2.game_over = True
                self.end_screen = True
                self.popups1.append(
                    Popup("You lost!", color="red", gcolor="orange"))
                self.popups2.append(
                    Popup("You won!", color="green", gcolor="yellow"))
            elif self.gameplay2.game_over and not self.gameplay1.game_over:
                self.gameplay1.game_over = True
                self.end_screen = True
                self.popups1.append(
                    Popup("You won!", color="green", gcolor="yellow"))
                self.popups2.append(
                    Popup("You lost!", color="red", gcolor="orange"))
            elif self.gameplay1.game_over and self.gameplay2.game_over:
                self.end_screen = True
                self.popups1.append(Popup("Draw!", color="cyan"))
                self.popups2.append(Popup("Draw!", color="cyan"))

        if self.gameplay1.cancel or self.gameplay2.cancel:
            if self.end_screen or self.gameplay1.countdown > 0:
                self.finished = True
                return
            else:
                self.gameplay1.game_over = self.gameplay1.cancel
                self.gameplay2.game_over = self.gameplay2.cancel
                self.gameplay1.cancel = False
                self.gameplay2.cancel = False

        self.gameplay1.update()
        self.gameplay2.update()

        if self.gameplay1.score.duel_lines > 0:
            hole = randint(0, 9)
            self.gameplay2.add_garbage(hole, self.gameplay1.score.duel_lines)
            self.gameplay1.score.duel_lines = 0

        if self.gameplay2.score.duel_lines > 0:
            hole = randint(0, 9)
            self.gameplay1.add_garbage(hole, self.gameplay2.score.duel_lines)
            self.gameplay2.score.duel_lines = 0

        self.popups1.extend(self.gameplay1.get_popups())
        self.gameplay1.clear_popups()

        self.popups2.extend(self.gameplay2.get_popups())
        self.gameplay2.clear_popups()

        if not self.current_popup1 and self.popups1:
            self.current_popup1 = self.popups1.pop(0)
        elif self.current_popup1:
            if not self.current_popup1.update():
                self.current_popup1 = None

        if not self.current_popup2 and self.popups2:
            self.current_popup2 = self.popups2.pop(0)
        elif self.current_popup2:
            if not self.current_popup2.update():
                self.current_popup2 = None

    def draw(self) -> None:
        self.gameplay1.draw(130, 80)
        self.gameplay2.draw(880, 80)

        if self.current_popup1:
            self.current_popup1.draw(130 + 155, 80 + 220)

        if self.current_popup2:
            self.current_popup2.draw(880 + 155, 80 + 220)
class Online(State):
    def __init__(self) -> None:
        self.gameplay1 = Gameplay()
        self.gameplay2 = Gameplay()

        self.popups1: List[Popup] = []
        self.popups2: List[Popup] = []
        self.current_popup1: Optional[Popup] = None
        self.current_popup2: Optional[Popup] = None

        self.waiting = True
        self.waiting_cycle = 0
        self.last_waiting_cycle = ctx.now

        self.buffer = b""
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.settimeout(10.0)

        self.finished = False
        self.end_screen = False

    def is_finished(self) -> bool:
        return self.finished

    def initialize(self) -> None:
        self.gameplay1.set_device(ctx.device1)
        self.gameplay1.initialize()

        self.gameplay2.set_device(Device("dummy"))
        self.gameplay2.initialize()

        try:
            self.socket.connect(config.server)
        except (ConnectionRefusedError, socket.timeout):
            print("unable to connect to server")
            self.finished = True

    def update(self, switch_state: Callable) -> None:
        read, write, error = select.select([self.socket], [self.socket],
                                           [self.socket], 0)

        if self.waiting:
            self.gameplay1.cancel_input.update()

            if self.socket in read:
                buffer = self.socket.recv(BUFFER_SIZE)
                if buffer == b"go":
                    self.waiting = False
                    self.current_popup2 = None
                elif buffer == b"ping":
                    self.socket.sendall(b"pong")
                elif buffer == b"":
                    print("server disconnected")
                    self.finished = True
            elif self.gameplay1.cancel:
                self.socket.close()
                self.finished = True

            return

        if not self.end_screen:
            if self.gameplay1.game_over and not self.gameplay2.game_over:
                self.gameplay2.game_over = True
                self.end_screen = True
                self.popups1.append(
                    Popup("You lost!", color="red", gcolor="orange"))
                self.popups2.append(
                    Popup("You won!", color="green", gcolor="yellow"))
            elif self.gameplay2.game_over and not self.gameplay1.game_over:
                self.gameplay1.game_over = True
                self.end_screen = True
                self.popups1.append(
                    Popup("You won!", color="green", gcolor="yellow"))
                self.popups2.append(
                    Popup("You lost!", color="red", gcolor="orange"))
            elif self.gameplay1.game_over and self.gameplay2.game_over:
                self.end_screen = True
                self.popups1.append(Popup("Draw!", color="cyan"))
                self.popups2.append(Popup("Draw!", color="cyan"))

        if self.gameplay1.cancel:
            self.gameplay1.send = True

            self.gameplay1.cancel = False
            self.gameplay1.game_over = True

            if self.end_screen or self.gameplay1.countdown > 0:
                self.finished = True

        self.gameplay1.update()

        if self.socket in read:
            try:
                self.gameplay2 = jsonpickle.decode(
                    protocol.recv(self.socket).decode())
            except (RuntimeError, ConnectionResetError):
                error = [self.socket]

        if self.socket in write and self.gameplay1.send:
            self.gameplay1.send = False
            try:
                protocol.send(self.socket,
                              jsonpickle.encode(self.gameplay1).encode())
            except (ConnectionResetError, ConnectionAbortedError):
                error = [self.socket]

        if self.socket in error:
            if not self.end_screen:
                print("communication error")
                self.finished = True

        if self.gameplay2.score.duel_lines > 0:
            hole = randint(0, 9)
            self.gameplay1.add_garbage(hole, self.gameplay2.score.duel_lines)
            self.gameplay2.score.duel_lines = 0

        self.gameplay1.score.duel_lines = 0

        self.popups1.extend(self.gameplay1.get_popups())
        self.gameplay1.clear_popups()

        self.popups2.extend(self.gameplay2.get_popups())
        self.gameplay2.clear_popups()

        if not self.current_popup1 and self.popups1:
            self.current_popup1 = self.popups1.pop(0)
        elif self.current_popup1:
            if not self.current_popup1.update():
                self.current_popup1 = None

        if not self.current_popup2 and self.popups2:
            self.current_popup2 = self.popups2.pop(0)
        elif self.current_popup2:
            if not self.current_popup2.update():
                self.current_popup2 = None

    def draw(self) -> None:
        self.gameplay1.draw(130, 80)
        self.gameplay2.draw(880, 80, draw_piece=not self.waiting)

        if self.waiting:
            Text.draw("Awaiting", size=4, centerx=880 + 155, top=220)
            Text.draw("opponent",
                      size=4,
                      gcolor="red",
                      centerx=880 + 155,
                      top=280)

            string = "." * self.waiting_cycle

            Text.draw(string,
                      size=8,
                      gcolor="black",
                      centerx=880 + 155,
                      top=350)

            if ctx.now - self.last_waiting_cycle > 0.5:
                self.last_waiting_cycle = ctx.now
                self.waiting_cycle = (self.waiting_cycle + 1) % 4

        if self.current_popup1:
            self.current_popup1.draw(130 + 155, 80 + 220)

        if self.current_popup2:
            self.current_popup2.draw(880 + 155, 80 + 220)
class Marathon(State):
    def __init__(self) -> None:
        self.gameplay = Gameplay()

        self.gravity = [
            1.00000,
            0.79300,
            0.61780,
            0.47273,
            0.35520,
            0.26200,
            0.18968,
            0.13473,
            0.09388,
            0.06415,
            0.04298,
            0.02822,
            0.01815,
            0.01144,
            0.00706,
        ]

        self.goal = 5

        self.popups: List[Popup] = []
        self.current_popup: Optional[Popup] = None

        self.end_screen = False

        self.finished = False
        self.pause = False

    def is_finished(self) -> bool:
        return self.finished

    def initialize(self) -> None:
        self.gameplay.set_device(ctx.device1)
        self.gameplay.initialize()

    def update(self, switch_state: Callable) -> None:
        if self.gameplay.game_over and not self.end_screen:
            self.end_screen = True
            self.popups.append(Popup("Game over!", color="red"))

        if self.gameplay.game_over and self.gameplay.cancel:
            self.finished = True
            return

        if self.gameplay.cancel:
            if self.gameplay.countdown > 0:
                self.finished = True
                return
            else:
                self.gameplay.game_over = True
                self.gameplay.cancel = False

        self.gameplay.update()

        if self.gameplay.score.lines > 0:
            self.goal -= self.gameplay.score.lines
            self.goal = max(0, self.goal)
            self.gameplay.score.lines = 0

            if self.goal == 0:
                if self.gameplay.level == 15 and not self.end_screen:
                    self.end_screen = True
                    self.gameplay.game_over = True
                    self.popups.append(
                        Popup("You won!", color="green", gcolor="yellow")
                    )
                else:
                    self.gameplay.level += 1
                    self.goal = 5 * self.gameplay.level
                    self.gameplay.fall_interval = self.gravity[
                        self.gameplay.level - 1
                    ]

        self.popups.extend(self.gameplay.get_popups())
        self.gameplay.clear_popups()

        if not self.current_popup and self.popups:
            self.current_popup = self.popups.pop(0)
            self.current_popup.duration *= 2
        elif self.current_popup:
            if not self.current_popup.update():
                self.current_popup = None

    def draw(self) -> None:
        self.gameplay.draw(200, 80)

        Text().draw("Level", centerx=125, top=300)
        Text().draw(
            str(self.gameplay.level),
            centerx=125,
            top=340,
            size=4,
            color="gold",
        )

        Text().draw("Goal", centerx=125, top=450)
        Text().draw(
            str(self.goal), centerx=125, top=490, size=4, color="green"
        )

        if self.current_popup:
            self.current_popup.draw(650, 250, center=False)