13 Apr 2024

[Java] 코드트리: 싸움땅

인기 게임인 싸움땅은 다음과 같은 방식으로 진행됩니다. 게임은 n * n 크기의 격자에서 진행되며, 각각의 격자에는 무기들이 있을 수 있습니다. 초기에는 무기들이 없는 빈 격자에 플레이어들이 위치하며 각 플레이어는 초기 능력치를 가집니다. 각 플레이어의 초기 능력치는 모두 다릅니다. 게임은 다음과 같은 방식으로 진행됩니다.

아래 그림에서 빨간색 배경의 숫자는 총의 경우 공격력을, 플레이어의 경우 초기 능력치를 의미하며, 노란색 배경의 숫자는 플레이어의 번호를 의미합니다.

하나의 라운드는 다음의 과정에 걸쳐 진행됩니다.

1-1. 첫 번째 플레이어부터 순차적으로 본인이 향하고 있는 방향대로 한 칸만큼 이동합니다. 만약 해당 방향으로 나갈 때 격자를 벗어나는 경우에는 정반대 방향으로 방향을 바꾸어서 1만큼 이동합니다.

2-1. 만약 이동한 방향에 플레이어가 없다면 해당 칸에 총이 있는지 확인합니다. 총이 있는 경우, 해당 플레이어는 총을 획득합니다. 플레이어가 이미 총을 가지고 있는 경우에는 놓여있는 총들과 플레이어가 가지고 있는 총 가운데 공격력이 더 쎈 총을 획득하고, 나머지 총들은 해당 격자에 둡니다.

2-2-1. 만약 이동한 방향에 플레이어가 있는 경우에는 두 플레이어가 싸우게 됩니다. 해당 플레이어의 초기 능력치와 가지고 있는 총의 공격력의 합을 비교하여 더 큰 플레이어가 이기게 됩니다. 만일 이 수치가 같은 경우에는 플레이어의 초기 능력치가 높은 플레이어가 승리하게 됩니다. 이긴 플레이어는 각 플레이어의 초기 능력치와 가지고 있는 총의 공격력의 합의 차이만큼을 포인트로 획득하게 됩니다.

2-2-2. 진 플레이어는 본인이 가지고 있는 총을 해당 격자에 내려놓고, 해당 플레이어가 원래 가지고 있던 방향대로 한 칸 이동합니다. 만약 이동하려는 칸에 다른 플레이어가 있거나 격자 범위 밖인 경우에는 오른쪽으로 90도씩 회전하여 빈 칸이 보이는 순간 이동합니다. 만약 해당 칸에 총이 있다면, 해당 플레이어는 가장 공격력이 높은 총을 획득하고 나머지 총들은 해당 격자에 내려 놓습니다.

2-2-3. 이긴 플레이어는 승리한 칸에 떨어져 있는 총들과 원래 들고 있던 총 중 가장 공격력이 높은 총을 획득하고, 나머지 총들은 해당 격자에 내려 놓습니다.

위 과정을 1번부터 n번 플레이어까지 순차적으로 한 번씩 진행하면 1 라운드가 끝나게 되고, 그 결과는 다음과 같습니다.

1번 라운드에 걸쳐 전체 플레이어가 획득한 포인트는 1번 사람부터 n번 사람까지 순서대로 [1, 0, 0, 0]입니다.

위의 과정을 한번더 반복하여 나온 2번 라운드 결과는 다음과 같으며, 2번 라운드 이후 획득한 포인트 역시 1번 라운드와 동일하게 [1, 0, 0, 0]이 됩니다.

k 라운드 동안 게임을 진행하면서 각 플레이어들이 획득한 포인트를 출력하는 프로그램을 작성해보세요.

입력 형식

첫 번째 줄에 n, m, k가 공백을 사이에 두고 주어집니다. n은 격자의 크기, m은 플레이어의 수, k는 라운드의 수를 의미합니다.

이후 n개의 줄에 걸쳐 격자에 있는 총의 정보가 주어집니다. 각 줄에는 각각의 행에 해당하는 n개의 수가 공백을 사이에 두고 주어집니다. 숫자 0은 빈 칸, 0보다 큰 값은 총의 공격력을 의미합니다.

이후 m개의 줄에 걸쳐 플레이어들의 정보 x, y, d, s가 공백을 사이에 두고 주어집니다. (x, y)는 플레이어의 위치, d는 방향, s는 플레이어의 초기 능력치를 의미하고 각 플레이어의 초기 능력치는 모두 다릅니다. 방향 d는 0부터 3까지 순서대로 ↑, →, ↓, ←을 의미합니다.

각 플레이어의 위치는 겹쳐져 주어지지 않으며, 플레이어의 초기 위치에는 총이 존재하지 않습니다.

  • 2 ≤ n ≤ 20
  • 1 ≤ m ≤ min(n2,30)
  • 1 ≤ k ≤ 500
  • 1 ≤ 총의 공격력 ≤ 100,000
  • 1 ≤ s ≤ 100
  • 1 ≤ x, y ≤ n

출력 형식

k 라운드 동안 게임을 진행하면서 각 플레이어들이 획득한 포인트를 공백을 사이에 두고 출력하세요.

풀이 방법

단순 구현 문제

생각해봐야 하는 점

I. 플레이어 이동

  1. 격자를 벗어나면 정반대로 방향 변경
    • 격자 반대편은 무조건 공간이 있기 때문에 방향 바꾸어 1칸만 이동하면 됨

II. 총 확인

1) 가지고 있는 총 중 가장 쎈 총만을 가져오기 때문에 우선순위 큐를 사용해 현재 위치에 있는 총들의 공격력을 내림차순 정렬


2차원 배열 MAP과, 플레이어 배열을 사용해서 문제를 해결하였다. K라운드동안 진행하면 되는 시뮬레이션 게임이다.

(a) movePlayer 메소드 [문제 내 1-1번 행동]

  1. 사람을 이동시킴
  2. 길이 없다면 사람의 방향을 180도 돌림(길이 막힌곳의 반대편은 무조건 갈 수 있음)

(b) findPlayerOrGun 메소드 [문제 내 2-1번 행동]

  1. 사람 배열과 편의점 배열 전체를 순회하며 i번 사람과 i번 편의점 위치를 확인한다. 동일하면 i번 편의점 방문처리 및 MAP에 방문처리를 해줬다.

(c) fight 메소드 [문제 내 2-2-1, 2-2-2, 2-2-3번 행동]

  1. 초기 공격력 + 총의 공격력 합을 비교
  2. 큰 사람이 승리, 같으면 초기 능력치가 같은 사람이 승리
  3. 패배자(loser)는 총을 놓고, 자신이 바라보는 방향으로 이동함. 갈 수 없다면 90도 우회전하고 이동한 곳에 총이 있다면 큰 것을 줍고 본인 것을 내려놓음
  4. 승리자(winner)는 현재 위치에 있는 총 중 강력한 것을 갖고 본인 것을 내려놓음(한 칸에는 총이 여러 개 있을 수 있음)

특별한 알고리즘이 들어가 있지 않아서 비교적 빠르게 해결할 수 있었다.

걸린 시간: 2시간 20분

풀이 코드

Thank You For Reading
SeungJun Jeon

점점 강해지고 있습니다.

comments powered by Disqus