본문 바로가기

알고리즘/코드트리

싸움땅[G2]

목차

    https://www.codetree.ai/training-field/frequent-problems/problems/battle-ground/description?page=1&pageSize=20

     

     

    package codeTree;
    
    /*
     https://www.codetree.ai/training-field/frequent-problems/problems/battle-ground/description?page=1&pageSize=20
     G1 싸움땅
     
    dr dc 중 에러나서 디버깅에 30분 썼음
    총 2시간 50분 
    + 20분, 또 문제 제대로 안 읽어서 히든테케 틀렸다. 진짜 지문 제대로 읽어야 할 듯
     */
    
    import java.util.*;
    import java.io.*;
    
    public class G1_BattleField {
    	static int N, M, K;
    	static Field[][] map;
    	
    	static List<Player> playerList = new ArrayList<>(); //플레이어 리스트 조회
    	
    	static final int[] DR = {-1, 0, 1, 0}; //U R D L
    	static final int[] DC = {0, 1, 0, -1}; //0 1 2 3 .. +2 % 4하면 될듯
    	
    	public static void main(String[] args) throws Exception {
    		setting(); //입력 받기
    		
    		while(K > 0) {
    			move(); //플레이어 순차 이동
    			K--;
    		}
    		
    		print(); //출력
    	}
    
    	private static void print() {
    		for(int i = 0; i < playerList.size(); i++) {
    			System.out.print(playerList.get(i).point + " ");
    		}
    		
    	}
    
    	static void move() {
    		for(int i = 0; i < playerList.size(); i++) {
    			move_pickOne(i); //플레이어 순차 이동 
    		}
    	}
    	
    	static void move_pickOne(int no) {
    		//해당 플레이어 이동(D)
    		Player now = playerList.get(no);
    		int nr = now.r + DR[now.d];
    		int nc = now.c + DC[now.d];
    		
    		//격자 벗어날 경우 정반대 방향으로 변경
    		if(cantGo(nr, nc)) {
    			now.d = (now.d + 2) % 4;
    			nr = now.r + DR[now.d];
    			nc = now.c + DC[now.d];
    		}
    		//아닐 경우 해당 방향으로 이동
    //		System.out.println(no + " 이동 : " + now.r + " " + now.c + " 에서 -> " + nr + nc);
    		now.r = nr;
    		now.c = nc;
    		
    		//해당 플레이어가 있는지 확인
    		if(checkThisPlace(nr, nc, no)) {
    //			System.out.println(" 배틀 : " +now.no+"가 " + now.r + " " + now.c + "로 이동하며 배틀 진행");
    			battle(now); //있다면 배틀
    		}
    		else {
    			getGun(now); //없다면 총 주움(교체)
    		}
    		
    		
    	}
    	
    	static void battle(Player now) {
    		//라이벌 찾기
    		Player rival = new Player(); //라이벌
    		for(int i = 0; i < playerList.size(); i++) {
    			Player p = playerList.get(i);
    			if(p.r == now.r && p.c == now.c && p.no != now.no) {
    				rival = p;
    				break;
    			}
    		}
    		//배틀
    		int nowPower = now.power + now.gun;
    		int rivalPower = rival.power + rival.gun;
    		int reward = Math.abs(nowPower - rivalPower);
    		
    		//내가 이김
    		if(nowPower > rivalPower || (nowPower == rivalPower && now.power > rival.power)) {
    			now.point = now.point + reward;
    			loseAction(rival);
    			getGun(now);
    		}
    		else { //라이벌이 이김
    			rival.point = rival.point + reward;
    			loseAction(now);
    			getGun(rival);
    		}
    	}
    
    	
    	static void loseAction(Player loser) {
    		int r = loser.r;
    		int c = loser.c;
    		
    		//총이 있다면 버리기
    		if(loser.gun != 0) {
    			map[r][c].guns.add(loser.gun); //넣기
    			loser.gun = 0; //버리기
    		}
    		
    		//이동
    
    		while(true) {
    			int nr = r + DR[loser.d];
    			int nc = c + DC[loser.d];
    			
    			if(cantGo(nr, nc) || checkThisPlace(nr, nc, loser.no)) { //격자 밖이거나 사람이 있음
    				int d = loser.d;
    				d++;
    				d %= 4; //나누기
    				loser.d = d; //갱신
    				continue; //다음 방향
    			}
    			//괜찮다면 이동
    			loser.r = nr; 
    			loser.c = nc;
    			
    			//이동한 곳에서 총 줍기
    			getGun(loser);
    			return;
    		}
    	}
    	
    	static void getGun(Player now) {
    		int r = now.r;
    		int c = now.c;
    		//총이 있다면 확인한다
    		if(map[r][c].guns.size() > 0) {
    			int gun = map[r][c].guns.poll(); //바닥에 있는 총
    			
    			//총 없으면 줍는다
    			if(now.gun == 0) {
    				now.gun = gun;
    			}
    			else { //있다면 비교한다
    				if(now.gun >= gun) map[r][c].guns.add(gun); //다시 버리고 감
    				else {
    					map[r][c].guns.add(now.gun); //내 총 두고감
    					now.gun = gun; //주움
    				}
    			}
    		}
    	}
    	
    	static boolean checkThisPlace(int r, int c, int no) {
    		for(int i = 0; i < playerList.size(); i++) {
    			Player now = playerList.get(i);
    			if(r == now.r && c == now.c && no != now.no) return true;
    		}
    		return false;
    	}
    	
    	
    	static void log() {
    		for(int i = 0; i < N; i++) {
    			for(int j = 0; j < N; j++) {
    				System.out.print(map[i][j].guns.peek() + "\t");
    			}
    			System.out.println();
    		}
    		System.out.println("=============================");
    	}
    	
    	static void setting() throws Exception {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		StringTokenizer st = new StringTokenizer(br.readLine());
    		N = Integer.parseInt(st.nextToken());
    		M = Integer.parseInt(st.nextToken());
    		K = Integer.parseInt(st.nextToken());
    		
    		//초기화
    		map = new Field[N][N];
    		for(int i = 0; i < N; i++) {
    		    for(int j = 0; j < N; j++) {
    		        map[i][j] = new Field();
    		    }
    		}
    		
    		//총 넣기
    		for(int i = 0; i < N; i++) {
    			st = new StringTokenizer(br.readLine());
    			for(int j = 0; j < N; j++) {						
    				int val = Integer.parseInt(st.nextToken());
    				if(val == 0) continue; //총 없음
    				map[i][j].guns.add(val);
    			}
    		}
    		
    		//플레이어 넣기 + 리스트에 추가하기
    		for(int i = 0; i < M; i++) {
    			st = new StringTokenizer(br.readLine());
    			int r = Integer.parseInt(st.nextToken()) - 1;
    			int c = Integer.parseInt(st.nextToken()) - 1;
    			int d = Integer.parseInt(st.nextToken());
    			int power = Integer.parseInt(st.nextToken());
    			playerList.add(new Player(i, r, c, d, power)); //리스트에 추가
    		}
    	}
    	
    	static boolean cantGo(int r, int c) {
    		if(r < 0 || c < 0 || r >= N || c >= N) return true;
    		return false;
    	}
    }
    
    class Field {
    	PriorityQueue<Integer> guns = new PriorityQueue<>(new Comparator<Integer>() {
    		@Override
    		public int compare(Integer o1, Integer o2) {
    			return o2 - o1;
    		}
    	});
    }
    
    class Player {
    	int r, c, d, power, point, no;
    	int gun;
    	Player(int no, int r, int c, int d, int power) {
    		this.r = r;
    		this.c = c;
    		this.d = d;
    		this.power = power;
    		this.no = no;
    	}
    	public Player() {
    		// TODO Auto-generated constructor stub
    	}
    }

     

    '알고리즘 > 코드트리' 카테고리의 다른 글

    팩맨[G1]  (1) 2023.11.02
    예술성[G3]  (0) 2023.11.02
    나무박멸[G4] (틀림 - 널포인터 이슈가 있는 듯)  (0) 2023.11.02
    코드트리빵[G2]  (0) 2023.11.02
    메이즈 러너[G3] [실패]  (0) 2023.11.02