본문 바로가기

Algorithm/BOJ

[BOJ-3190][시뮬레이션] 뱀 - Java

문제 바로가기

 

3190번: 뱀

문제  'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다.

www.acmicpc.net

뱀이 왔다갔다 하는 문제임니다. 문제에서 요구하는 조건만 잘 생각해서 코드를 짜면 됩니다..

import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;

class Dir{
    int y;
    int x;
    Dir(int y, int x){
        this.y = y;
        this.x = x;
    }
}

class Move{
    int sec;
    char dir;
    Move(int sec, char dir){
        this.sec = sec;
        this.dir = dir;
    }
}

class Snake{
    int dir;
    Deque<Dir> body = new LinkedList<>();
    Snake(int dir, Dir cur){
        this.dir = dir;
        this.body.offer(cur);
    }
}

public class Main {
    static int[][] map;
    static int N;
    static Move[] moves;
    static char snakeDir = 1;
    static int[] dy = {-1, 0, 1, 0};    //U R D L
    static int[] dx = {0, 1, 0, -1};
    static Snake snake;

    static boolean isIn(Dir cur) {
        if(0<= cur.y && cur.y < N && 0<= cur.x && cur.x < N) return true;
        else return false;
    }
    //대가리가 q.rear
    static void moveSnake() {
        int time = 0;
        int i = 0;    //moves idx
        while(true) {
            time++;
            Dir next = new Dir(snake.body.getLast().y + dy[snake.dir], 
                            snake.body.getLast().x + dx[snake.dir]);
            if(!isIn(next) || map[next.y][next.x] == 2) {
                System.out.println(time);
                return;
            }

            if(map[next.y][next.x] == 1) {
                snake.body.offer(next);
                map[next.y][next.x] = 2; 
            }
            else {
                map[snake.body.peek().y][snake.body.peek().x] = 0;
                snake.body.poll();
                snake.body.offer(next);
                map[next.y][next.x]= 2; 
            }
            if(i < moves.length) {
                if(time == moves[i].sec) {
                    snake.dir = moves[i].dir == 'D' ? (snake.dir+5) % 4 : (snake.dir+3) % 4;
                    i++;
                }
            }
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        snake = new Snake(1, new Dir(0, 0));
        N = Integer.parseInt(sc.nextLine());
        map = new int[N][N];
        map[0][0] = 2;
        int K = Integer.parseInt(sc.nextLine());

        for(int i = 0; i < K; i++) {
            int y = Integer.parseInt(sc.next()) - 1;
            int x = Integer.parseInt(sc.next()) - 1;
            map[y][x] = 1;
        }
        int L = Integer.parseInt(sc.next());
        moves = new Move[L];
        for(int i = 0; i< L; i++) {
            moves[i] = new Move(Integer.parseInt(sc.next()), sc.next().charAt(0));
        }

        moveSnake();

    }

}

Snake - 뱀의 정보를 담는 클래스입니다. dir은 뱀이 바라보고 있는 방향입니다.
snake.dir = moves[i].dir == 'D' ? (snake.dir+5) % 4 : (snake.dir+3) % 4;

방향은 이렇게 방향을 업데이트 해줍니다.

 

뱀의 몸통은 Deque로 구현했습니다. 첨에 Queue로 짰는데 다음 이동 방향은 Queuerear쪽에서 업데이트해줘야 하므로 Deque로 바꿨습니다..

 

map의 값이 1이면 사과, 2면 뱀의 몸통으로 정했습니다. 처음에는 Dir next를 구하고 snake.body.contains(next)로 몸통에 부딪히는지 확인해주려고 했는데 안되더라구여 ㅜ

가리키는 주소값을 보고 비교를 해서 그릉가... 한번 찾아봐야게씀니다...

 

사과를 먹으면 몸통이 줄지 않기 때문에 nextDeque 맨 뒤에 넣어주면 됩니다. 요 때 next, 즉 뱀 대가리 정보가 맨 뒤에 있기 때문에 Deque를 써주었슴니다 ^>^

사과가 없으면 한 칸씩 이동하기 것이기 때문에 맨 앞에 놈(꼬리쪽)을 빼고 next를 넣어줌으로써 뱀의 이동을 쉽게 구현했습니당 ㅎㅎ

 

 

감사합니다