結果

問題 No.769 UNOシミュレータ
ユーザー ThetaTheta
提出日時 2022-12-07 16:15:43
言語 Python3
(3.12.2 + numpy 1.26.4 + scipy 1.12.0)
結果
AC  
実行時間 1,075 ms / 2,000 ms
コード長 3,612 bytes
コンパイル時間 87 ms
コンパイル使用メモリ 12,928 KB
実行使用メモリ 40,960 KB
最終ジャッジ日時 2024-04-21 23:35:30
合計ジャッジ時間 9,641 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 32 ms
10,880 KB
testcase_01 AC 35 ms
10,880 KB
testcase_02 AC 35 ms
11,008 KB
testcase_03 AC 33 ms
11,136 KB
testcase_04 AC 36 ms
11,136 KB
testcase_05 AC 35 ms
11,008 KB
testcase_06 AC 34 ms
11,136 KB
testcase_07 AC 35 ms
11,008 KB
testcase_08 AC 35 ms
11,136 KB
testcase_09 AC 66 ms
12,032 KB
testcase_10 AC 65 ms
11,904 KB
testcase_11 AC 66 ms
12,032 KB
testcase_12 AC 345 ms
18,944 KB
testcase_13 AC 336 ms
18,944 KB
testcase_14 AC 358 ms
18,944 KB
testcase_15 AC 691 ms
29,440 KB
testcase_16 AC 696 ms
29,568 KB
testcase_17 AC 702 ms
29,568 KB
testcase_18 AC 1,073 ms
40,832 KB
testcase_19 AC 1,064 ms
40,832 KB
testcase_20 AC 1,066 ms
40,960 KB
testcase_21 AC 1,075 ms
40,960 KB
testcase_22 AC 32 ms
11,008 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

from abc import abstractclassmethod, abstractmethod
from enum import Enum


class Player:
    def __init__(self) -> None:
        self.used = 0
        self.drawn = 0

    def use(self):
        self.used += 1

    def draw(self, num: int):
        self.drawn += num


class ICard:
    pass


class Game:
    def __init__(self, players: int) -> None:
        self.current_turn = 0
        self.previous_player_idx = None
        self.players = [Player() for _ in range(players)]
        self.current_direction_assc = True
        self.draw_stack = 0
        self.field_surface = None

    def force_draw_from_pile(self):
        if self.draw_stack:
            self.draw_from_pile(self.draw_stack)
            self.draw_stack = 0
            self.next_turn()

    def draw_from_pile(self, num: int = 1):
        self.players[self.current_turn].draw(num)

    def add_draw_stack(self, num: int):
        self.draw_stack += num

    def use_card(self, card: ICard):
        self.players[self.current_turn].use()
        self.update_used_card(card)
        self.previous_player_idx = self.current_turn

    def next_turn(self, diff: int = 1):
        if self.current_direction_assc:
            self.current_turn = (self.current_turn + diff) % len(self.players)
        else:
            self.current_turn = (self.current_turn - diff) % len(self.players)

    def skip(self):
        self.next_turn(2)

    def reverse(self):
        self.current_direction_assc ^= True

    def update_used_card(self, card: ICard):
        self.field_surface = card

    @property
    def previous_player(self):
        if self.previous_player_idx is None:
            return
        return self.players[self.previous_player_idx]


class Card(ICard):
    @abstractmethod
    def effect(self, game: Game):
        pass

    @classmethod
    def isinstance(cls, other):
        return isinstance(other, cls)


class NumberCard(Card):
    def effect(self, game: Game):
        game.force_draw_from_pile()
        game.use_card(self)
        game.next_turn()


class SkipCard(Card):
    def effect(self, game: Game):
        game.force_draw_from_pile()
        game.use_card(self)
        game.skip()


class ReverseCard(Card):
    def effect(self, game: Game):
        game.force_draw_from_pile()
        game.use_card(self)
        game.reverse()
        game.next_turn()


class DrawTwoCard(Card):
    def effect(self, game: Game):

        if not (game.field_surface is None or game.field_surface.isinstance(self)):
            game.force_draw_from_pile()

        game.use_card(self)
        game.add_draw_stack(2)
        game.next_turn()


class DrawFourCard(Card):
    def effect(self, game: Game):
        if not (game.field_surface is None or game.field_surface.isinstance(self)):
            game.force_draw_from_pile()

        game.use_card(self)
        game.add_draw_stack(4)
        game.next_turn()


def card_create(card_type: str) -> Card:
    match card_type:
        case "number":
            return NumberCard()
        case "drawtwo":
            return DrawTwoCard()
        case "drawfour":
            return DrawFourCard()
        case "skip":
            return SkipCard()
        case "reverse":
            return ReverseCard()
        case _:
            raise ValueError


def main():
    N, M = map(int, input().split())
    card_logs = [card_create(input()) for _ in range(M)]

    game = Game(N)

    for card in card_logs:
        card.effect(game)

    print(game.previous_player_idx + 1,
          (game.previous_player.used - game.previous_player.drawn))


if __name__ == "__main__":
    main()
0