코드트리 - 싸움땅 (Python)

Kim Yongbin·2024년 10월 15일
0

코딩테스트

목록 보기
155/162
import sys

# Solution
class Player:
    def __init__(self, idx, x, y, d, stat):
        self.idx = idx
        self.x = x
        self.y = y
        self.d = d
        self.stat = stat
        self.gun = 0

    def get_attk(self):
        return self.stat + self.gun

    def __lt__(self, other):
        if self.get_attk() == other.get_attk():
            return self.stat < other.stat
        return self.get_attk() < other.get_attk()

    def __repr__(self):
        return f"{self.idx}"

# step 1: player 이동
def player_move(player):
    dir = dirs[player.d]
    nx, ny = player.x + dir[0], player.y + dir[1]

    if not in_range(nx, ny):
        player.d = (player.d + 2) % 4
        dir = dirs[player.d]
        nx, ny = player.x + dir[0], player.y + dir[1]

    player_map[player.x][player.y] = 0
    player.x = nx
    player.y = ny

    if player_map[nx][ny] > 0:
        other = player_dict[player_map[nx][ny]]
        player_map[nx][ny] = 0
        fight(player, other)
    else:
        update_gun(player)

# step 2-1: player 결투
def fight(player1, player2):
    player_list = [player1, player2]
    player_list.sort()

    loser, winner = player_list
    player_score[winner.idx] += winner.get_attk() - loser.get_attk()

    lose(loser)
    win(winner)

# step 2-1-1: 승자
def win(winner):
    update_gun(winner)

# step 2-1-2: 패자
def lose(loser):
    x, y = loser.x, loser.y
    if loser.gun > 0:
        gun_map[x][y].append(loser.gun)
        loser.gun = 0

    for i in range(4):
        dx, dy = dirs[(loser.d + i) % 4]
        nx, ny = x + dx, y + dy
        if in_range(nx, ny) and player_map[nx][ny] == 0:
            loser.d = (loser.d + i) % 4
            loser.x = nx
            loser.y = ny
            update_gun(loser)
            return

# step 2-2: gun 업데이트
def update_gun(player):
    x, y = player.x, player.y
    gun_list = gun_map[x][y]

    if player.gun > 0:
        gun_list.append(player.gun)

    if gun_list:
        player.gun = max(gun_list)
        gun_list.remove(player.gun)

    player_map[x][y] = player.idx

def in_range(x, y):
    return 0 <= x < n and 0 <= y < n

# main
n, m, k = map(int, sys.stdin.readline().split())
player_map = [[0] * n for _ in range(n)]
player_dict = {}
gun_map = [[[] for _ in range(n)] for _ in range(n)]
player_score = [0] * (m + 1)
dirs = [[-1, 0], [0, 1], [1, 0], [0, -1]]

# set gun map
for i in range(n):
    row = list(map(int, sys.stdin.readline().split()))
    for j, g in enumerate(row):
        if g != 0:
            gun_map[i][j].append(g)

# set player
for i in range(m):
    x, y, d, s = map(int, sys.stdin.readline().split())
    player = Player(i + 1, x - 1, y - 1, d, s)
    player_dict[i + 1] = player
    player_map[x - 1][y - 1] = i + 1

for _ in range(k):
    for p_id in range(1, m + 1):
        player = player_dict[p_id]
        player_move(player)

print(*player_score[1:])
profile
반박 시 여러분의 말이 맞습니다.

0개의 댓글