본문 바로가기
온라인 저지/SWEA

[SWEA/Java] 1873 상호의 배틀필드

by ahj 2022. 2. 5.
import java.io.BufferedReader;
import java.io.InputStreamReader;
 
public class Solution {
 
    public static void main(String[] args) throws Exception {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder ans = new StringBuilder();
 
        int T;
        T = Integer.parseInt(in.readLine());
        int height, width, commandCount;
        String[] hw;
        char[] commandList, grid[];
        for (int test_case = 1; test_case <= T; test_case++) {
            hw = in.readLine().split(" ");
            height = Integer.parseInt(hw[0]);
            width = Integer.parseInt(hw[1]);
            grid = new char[height][width];
            for (int i = 0; i < height; i++) {
                grid[i] = in.readLine().toCharArray();
            }
            commandCount = Integer.parseInt(in.readLine());
            commandList = new char[commandCount];
            commandList = in.readLine().toCharArray();
            int[] pos = findCurrent(grid);
            int index_longitude = pos[0];
            int index_latitude = pos[1];
            for (char el : commandList) {
                if (el != 'S') {
                    if (el == 'U') {
                        grid[index_longitude][index_latitude] = '^';
                        if (index_longitude - 1 >= 0 && grid[index_longitude - 1][index_latitude] == '.') {
                            grid[index_longitude][index_latitude] = '.';
                            grid[index_longitude - 1][index_latitude] = '^';
                            index_longitude -= 1;
                        }
                    } else if (el == 'D') {
                        grid[index_longitude][index_latitude] = 'v';
                        if (index_longitude + 1 < height && grid[index_longitude + 1][index_latitude] == '.') {
                            grid[index_longitude][index_latitude] = '.';
                            grid[index_longitude + 1][index_latitude] = 'v';
                            index_longitude += 1;
                        }
                    } else if (el == 'L') {
                        grid[index_longitude][index_latitude] = '<';
                        if (index_latitude - 1 >= 0 && grid[index_longitude][index_latitude - 1] == '.') {
                            grid[index_longitude][index_latitude] = '.';
                            grid[index_longitude][index_latitude - 1] = '<';
                            index_latitude -= 1;
                        }
                    } else if (el == 'R') {
                        grid[index_longitude][index_latitude] = '>';
                        if (index_latitude + 1 < width && grid[index_longitude][index_latitude + 1] == '.') {
                            grid[index_longitude][index_latitude] = '.';
                            grid[index_longitude][index_latitude + 1] = '>';
                            index_latitude += 1;
                        }
                    }
                } else {
                    int delta = 0;
                    if (grid[index_longitude][index_latitude] == '^') {
                        while (index_longitude + delta >= 0) {
                            if (grid[index_longitude + delta][index_latitude] == '*'
                                    || grid[index_longitude + delta][index_latitude] == '#') {
                                if (grid[index_longitude + delta][index_latitude] == '*') {
                                    grid[index_longitude + delta][index_latitude] = '.';
                                }
                                break;
                            }
                            delta--;
                        }
                    } else if (grid[index_longitude][index_latitude] == 'v') {
                        while (index_longitude + delta < height) {
                            if (grid[index_longitude + delta][index_latitude] == '*'
                                    || grid[index_longitude + delta][index_latitude] == '#') {
                                if (grid[index_longitude + delta][index_latitude] == '*') {
                                    grid[index_longitude + delta][index_latitude] = '.';
                                }
                                break;
                            }
                            delta++;
                        }
                    } else if (grid[index_longitude][index_latitude] == '<') {
                        while (index_latitude + delta >= 0) {
                            if (grid[index_longitude][index_latitude + delta] == '*'
                                    || grid[index_longitude][index_latitude + delta] == '#') {
                                if (grid[index_longitude][index_latitude + delta] == '*') {
                                    grid[index_longitude][index_latitude + delta] = '.';
                                }
                                break;
                            }
                            delta--;
                        }
                    } else if (grid[index_longitude][index_latitude] == '>') {
                        while (index_latitude + delta < width) {
                            if (grid[index_longitude][index_latitude + delta] == '*'
                                    || grid[index_longitude][index_latitude + delta] == '#') {
                                if (grid[index_longitude][index_latitude + delta] == '*') {
                                    grid[index_longitude][index_latitude + delta] = '.';
                                }
                                break;
                            }
                            delta++;
                        }
                    }
                }
            }
            ans.append("#").append(test_case).append(" ");
            for (char[] row : grid) {
                for (char el : row) {
                    ans.append(el);
                }
                ans.append("\n");
            }
 
        }
        in.close();
        System.out.println(ans);
    }
 
    private static int[] findCurrent(char[][] grid) {
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[i].length; j++) {
                if (grid[i][j] == '^' || grid[i][j] == 'v' || grid[i][j] == '<' || grid[i][j] == '>') {
                    return new int[] { i, j };
                }
            }
        }
        return null;
 
    }
 
}

경우의 수 다 따져줘서 짜느라고 길이도 엄청 길어지고 틀렸을 때 오류 수정도 그지같이 오래 걸렸다. 코테에서는 당연히 어떻게 해서든 맞추는 게 가장 중요하겠지만, 이렇게 너무 그지 같이 짜면 오답일 때 수정하기에 시간이 너무 오래 걸린다... 애초부터 추상화 잘 해서 코드 짜는 연습이 되어야 할 것 같다.

하지만 암튼 문제 볼 때부터 왠지 진짜 게임 객체처럼 method들을 만들어서 활용하고 싶었다. 수업 때 같이 실습하면서 이렇게 구현하는구나 배웠다.

 

이하 수업 내용을 토대로 refactor한 버전

import java.io.BufferedReader;
import java.io.InputStreamReader;
 
public class Solution {
    static int[][] delta = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; // 사방 탐색 위한 array
    static int current_x, current_y, height, width;
    static char[][] grid;
 
    public static void main(String[] args) throws Exception {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder ans = new StringBuilder();
 
        int T;
        T = Integer.parseInt(in.readLine());
        String[] hw;
        char[] commandList;
        for (int test_case = 1; test_case <= T; test_case++) {
            hw = in.readLine().split(" ");
            height = Integer.parseInt(hw[0]);
            width = Integer.parseInt(hw[1]);
            grid = new char[height][width];
            for (int i = 0; i < height; i++) {
                grid[i] = in.readLine().toCharArray();
 
                for (int j = 0; j < width; j++) {
                    switch (grid[i][j]) {
                    case '^':
                    case 'v':
                    case '<':
                    case '>':
                        current_x = j;
                        current_y = i;
                        break;
                    }
                }
            }
            commandList = new char[Integer.parseInt(in.readLine())];
            commandList = in.readLine().toCharArray();
            for (char el : commandList) {
                switch (el) {
                case 'U':
                    grid[current_y][current_x] = '^';
                    move(0);
                    break;
                case 'D':
                    grid[current_y][current_x] = 'v';
                    move(1);
                    break;
                case 'L':
                    grid[current_y][current_x] = '<';
                    move(2);
                    break;
                case 'R':
                    grid[current_y][current_x] = '>';
                    move(3);
                    break;
                case 'S':
                    shoot();
                    break;
                }
            }
            ans.append("#").append(test_case).append(" ");
            for (char[] row : grid) {
                for (char el : row) {
                    ans.append(el);
                }
                ans.append("\n");
            }
 
        }
 
        in.close();
        System.out.println(ans);
    }
 
    private static void shoot() {
        int dir = 0;
 
        switch (grid[current_y][current_x]) {
        case '^':
            dir = 0;
            break;
        case 'v':
            dir = 1;
            break;
        case '<':
            dir = 2;
            break;
        case '>':
            dir = 3;
            break;
        }
 
        int ny = current_y;
        int nx = current_x;
 
        while (true) {
            ny += delta[dir][0];
            nx += delta[dir][1];
 
            if (!isIn(ny, nx))
                return;
            if (grid[ny][nx] == '*') { 
                grid[ny][nx] = '.';
                return;
            } else if (grid[ny][nx] == '#')
                return;
        }
 
    }
 
    private static void move(int dir) {
        int ny = current_y + delta[dir][0];
        int nx = current_x + delta[dir][1];
 
        if (!isIn(ny, nx))
            return;
 
        if (grid[ny][nx] == '.') {
            grid[ny][nx] = grid[current_y][current_x];
            grid[current_y][current_x] = '.';
 
            current_y = ny;
            current_x = nx;
        }
 
    }
 
    private static boolean isIn(int ny, int nx) {
        return (ny >= 0 && nx >= 0 && ny < height && nx < width);
    }
}

이런 식으로 static 전역으로 그 자체를 변경 시켜가면서 method 돌릴 생각을 못했다. 이렇게 하면 너무 자바처럼 짜지 않을 수 있는 것 같다.

무엇보다도 switch-case..!!!!!!

제발 배웠으면 잘 좀 써보자. 백날 if-else만 쓰지 말고. switch-case로 하니까 가독성도 사는 것 같고 길이도 짧아지는 것 같다. if문 안이 너무 길면 왠지 모르게 더러워 보인다.

또한 flag처럼 각 상황이랑 번호, array를 잘 연동해서 써보기

 

오늘의 포인트

1. if-else만 말고 switch-case도 익숙해지자

2. 반복되는 부분을 줄이는 방법으로 각 case별 번호를 저장해두고 -> flag. 이를 이용해서 구현해보자

3. 너무 결과 뽑기에만 치중하면 수정하기 어렵다...

4. 더러워질 수 있는 부분, 반복 되는 부분은 method로 뽑아보는 연습을 많이많이 하자

 

 

'온라인 저지 > SWEA' 카테고리의 다른 글

[SWEA/Java] 9229 한빈이와 Spot Mart  (0) 2022.02.10
[SWEA/Java] 1218 괄호 짝짓기  (0) 2022.02.09
[SWEA/Java] 1225 암호생성기  (0) 2022.02.08
[SWEA/Java] 1218 괄호 짝짓기  (0) 2022.02.07
[SWEA/Java] 1208 Flatten  (0) 2022.02.04

댓글