happy coding

[java] 구름톤 10일차. GameJam 본문

coding study

[java] 구름톤 10일차. GameJam

yeoonii 2023. 8. 25. 22:59

문제

플레이어는 GameJam에 참가했다. GameJam은 현장에서 즉석으로 팀을 꾸려 게임의 규칙을 만든 뒤, 생각한 규칙을 코드로 옮겨서 게임을 만들어내는 대회이다.
플레이어가 속한 팀은 보드로 즐길 수 있는 간단한 보드게임을 만들었다. 게임의 진행 방법과 규칙은 다음과 같다.
1. 게임은 한 변의 길이가 N인 격자 보드 위에서 진행한다. 보드는 한 변의 길이가 1인 N^2개의 칸으로 나누어져 있다.
2. 각 칸에는 <command>에 해당하는 방향으로 <count>칸만큼 한 칸씩 이동하라는 지시가 적혀있다.
3. 플레이하는 사람은 처음에 보드의 칸 중 하나에 말을 올려놓는다.
4. 각 칸에 적힌 지시대로 말을 이동한다. 만약 이동 중에 보드 밖으로 나가게 된다면 반대쪽의 첫 번째 칸으로 이동한다. 예를 들어 맨 오른쪽 칸에서 오른쪽으로 이동해야 한다면 해당 행의 맨 왼쪽 칸으로 이동하고, 맨 아래 칸에서 아래쪽으로 이동해야 한다면 해당 열의 맨 위쪽 칸으로 이동하고, 이동 거리가 남아 있다면 계속 이동한다.
5. 만약 이동하다가 자신의 말이 이미 한 번이라도 방문한 칸을 다시 지나야 할 경우에는 게임이 종료된다. 그 외의 경우에는 게임이 종료될 때까지 위의 4번 단계를 반복한다.
6. 게임의 점수는 시작한 칸을 포함하여, 게임이 종료되기 전까지 말이 방문한 서로 다른 칸의 개수이다.
플레이어는 GameJam의 최종 발표 때 게임을 시연해 보기 위해, 구름이와 미리 연습게임을 진행해 보려고 한다. 플레이어와 구름이가 각각의 게임에서 처음에 말을 올려둔 칸이 주어졌을 때, 두 사람 중 누가 더 높은 점수를 획득했는지를 구해보자. 단 플레이어와 구름이는 별개의 게임이다.

입력

출력

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());

        String[] inputs = br.readLine().split(" ");
        int goorm_Y = Integer.parseInt(inputs[0]);
        int goorm_X = Integer.parseInt(inputs[1]);

        inputs = br.readLine().split(" ");
        int player_Y = Integer.parseInt(inputs[0]);
        int player_X = Integer.parseInt(inputs[1]);

        String[][] query_board = new String[N][N];
        for (int i = 0; i < N; i++) {
            query_board[i] = br.readLine().split(" ");
        }

        goorm_Y--;
        goorm_X--;
        player_Y--;
        player_X--;

        solution(N, goorm_Y, goorm_X, player_Y, player_X, query_board);
    }

    public static int getIndex(char direction) {
        switch (direction) {
            case 'L':
                return 0;
            case 'R':
                return 1;
            case 'U':
                return 2;
            case 'D':
                return 3;
            default:
                return -1;
        }
    }

    public static int change(int index, int N) {
        if (index < 0) {
            index = N + (index % N);
        }
        if (index >= N) {
            index = index % N;
        }
        return index;
    }

    public static boolean isVisited(List<int[]> visited, int[] coords) {
        for (int[] visitedCoords : visited) {
            if (visitedCoords[0] == coords[0] && visitedCoords[1] == coords[1]) {
                return true;
            }
        }
        return false;
    }

    public static void solution(int N, int goorm_Y, int goorm_X, int player_Y, int player_X, String[][] query_board) {
        List<int[]> goorm_visited = new ArrayList<>();
        goorm_visited.add(new int[] {goorm_Y, goorm_X, 0});

        List<int[]> player_visited = new ArrayList<>();
        player_visited.add(new int[] {player_Y, player_X, 0});

        boolean goorm_flag = true;
        boolean player_flag = true;

        while (goorm_flag) {
            int[] newCoords = move(goorm_Y, goorm_X, goorm_visited, N, query_board);
            goorm_Y = newCoords[0];
            goorm_X = newCoords[1];
            goorm_flag = (newCoords[2] == 1);
        }

        while (player_flag) {
            int[] newCoords = move(player_Y, player_X, player_visited, N, query_board);
            player_Y = newCoords[0];
            player_X = newCoords[1];
            player_flag = (newCoords[2] == 1);
        }

        if (goorm_visited.size() > player_visited.size()) {
            System.out.println("goorm " + goorm_visited.size());
        } else {
            System.out.println("player " + player_visited.size());
        }
    }

    public static int[] move(int Y, int X, List<int[]> visited, int N, String[][] query_board) {
        int[][] queries = {
                {0, -1},  // 왼쪽
                {0, 1},   // 오른쪽
                {-1, 0},  // 위쪽
                {1, 0}    // 아래쪽
        };
        int move_count = Integer.parseInt(query_board[Y][X].substring(0, query_board[Y][X].length() - 1));
        int[] direction = queries[getIndex(query_board[Y][X].charAt(query_board[Y][X].length() - 1))];

        for (int i = 0; i < move_count; i++) {
            Y = change(Y + direction[0], N);
            X = change(X + direction[1], N);

            int[] newCoords = {Y, X, 0};
            if (!isVisited(visited, newCoords)) {
                visited.add(newCoords);
            } else {
                return new int[] {Y, X, 0};
            }
        }

        return new int[] {Y, X, 1};
    }
}

입력 받기

  • BufferedReader를 사용하여 입력을 받습니다.
  • 먼저 첫 번째 줄에서 N을 읽어옵니다.
  • 다음 줄에서 각각 goorm과 player의 시작 위치를 읽어옵니다.
  • 이후 query_board라는 2차원 배열에 쿼리를 저장합니다.

인덱스 조정과 이동 함수 작성

  • getIndex 함수는 입력 받은 문자에 따라 이동 방향을 인덱스로 변환해줍니다.
  • change 함수는 인덱스가 보드의 범위를 넘어갈 때 조정하여 보드 내에 유지하도록 합니다.

방문 여부 확인 함수

  • visited 리스트에 이미 방문한 좌표인지를 확인하는 함수입니다.

이동 함수 작성

  • 주어진 방향으로 이동하고, 방문한 좌표를 업데이트하는 함수입니다.

해결책 함수 구현

  • 주어진 조건에 따라 goorm과 player의 이동 경로를 계산하여 비교하고, 결과를 출력하는 함수입니다.

메인 함수

  • 메인 함수에서는 입력을 받고, solution 함수를 호출하여 결과를 출력합니다.

 

Comments