Back-End/수업 내용 응용 연습장

[java] 1024게임 (12.02 배열심화 같은수합치기 응용)

Dev-RiQ 2024. 12. 3. 11:30

학원 1달차 (24.12.02)

조건문 / 반복문 / 배열 / 이차원배열 / 문자열 학습 응용

+ 구글 클래스, 메소드 검색 후 기본 습득

 

12.02에 풀어본 배열 심화 문제 내용은 아래와 같다.

package 배열심화2;

import java.util.Arrays;

public class _14같은수합치기 {

	public static void main(String[] args) {

		/*
		 	input 배열의 데이터를 순차적으로 arr에 저장하는데
		 	만약 저장하려는 수와 그 앞의 수가 서로 같으면 합친다 (중첩가능)
		 	마지막 arr 값은?
		 */
		int[] input = { 8, 4, 2, 2, 4, 4, 8 };
		int[] arr = new int[input.length];
		int idx = -1;
		for (int i = 0; i < arr.length; i++) {
			arr[++idx] = input[i];
			while (true) {
				System.out.println(Arrays.toString(arr));
				if (idx > 0 && arr[idx - 1] == arr[idx]) {
					arr[idx - 1] += arr[idx];
					arr[idx--] = 0;
					continue;
				}
				break;
			}
		}
		System.out.println("arr = " + Arrays.toString(arr));
	}

}

 

이거 만들자 마자 딱 떠오른게 1024게임이었다.

 

하지만 역시 기능의 종합은 쉽지 않았다. 예외 조건도 이것저것 추가되고

종료 조건 설정도 까다로웠다.

오 왼 위 아래 이동도 뭔가 비슷해서 합칠 수 있을것 같은데 복잡해질거같아 포기..

2048까지 만드는데 거의 900번이상 움직였다.

2,4,8까지 랜덤으로 나오는데 확률을 정확히 몇으로 할지 몰라 얼추 넣었더니

4096은 만들기 힘들거같아서 포기 ㅎ

출력문 제외하면 그래도 이전보다 보기 편해진 느낌이다!

그래서 그런지 오류 수정하면서 고치는데도 시간이 줄어들었다 (기분탓일지도)

 

package 깔짝;

import java.util.Random;
import java.util.Scanner;

import _01.BACKGROUND;
import _01.FONT;

public class _005_1024 {
	
	public static int rdNum() {
		Random rd = new Random();
		int num = rd.nextInt(100000);
		num = num%100<1 ? 8 : num%10<2 ? 4 : 2;
		return num;
	}
	public static int[] rdIdx() {
		Random rd = new Random();
		int[] idx = {rd.nextInt(4),rd.nextInt(4)};
		return idx;
	}
	public static int[][] rdAdd(int[][] a){
		int[][] rdAdd = new int[4][4];
		rdAdd = a;
		while(true) {
			int[] rd = rdIdx();
			if(a[rd[0]][rd[1]]==0) {
				a[rd[0]][rd[1]] = rdNum();
				break;
			}
		}
		return rdAdd;
	}
	public static boolean rdNonAdd(int[][] a, int[][] b) {
		boolean isMatch = true;
		for(int i = 0 ; i<4;i++) {
			for(int k = 0 ; k<4;k++) {
				if(a[i][k]!=b[i][k]) {
					isMatch = false;
					break;
				}
			}
		}
		return isMatch;
	}
	public static int max = 0;
	public static void maxSet(int[][] a) {
		for(int i = 0 ; i<4;i++) {
			for(int k = 0 ; k<4;k++) {
				if(max<a[i][k]) {
					max = a[i][k];
				}
			}
		}
	}
	public static int score = 0;
	public static void scoreSet(int a) {
		int temp = a;
		int cntDiv2 = 1;
		while(temp != 2) {
			temp /= 2;
			cntDiv2 ++;
		}
		score += Math.pow(2, cntDiv2 + 1);
	}
	public static int[][] start () {
		int[][] startMap = new int[4][4];
		startMap = rdAdd(startMap);
		return startMap;
	}
	public static void showMap(int[][] a) {
		showColor();
		System.out.println("┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓");
		System.out.println("┃                ┃                      ┃");
		System.out.print("┃    1024 GAME   ┃");
		System.out.printf(" 현재 점수 : %7d",score);
		System.out.println("  ┃");
		System.out.println("┃                ┃                      ┃");
		for(int i = 0; i<4;i++) {
			if(i==0) {
				System.out.println("┠━━━━━━━━━┳━━━━━━┻━━┳━━━━━━━━━┳━━━━━━━━━┫");
			}
			for(int k = 0;k<4;k++) {
				System.out.print(k==0? "┃         ┃":"         ┃");
			}
			System.out.println();
			for(int k = 0;k<4;k++) {
				int cnt = showSet(a[i][k]);
				int cnt1 = cnt/2;
				int cnt2 = cnt - cnt/2;
				System.out.print("┃  ");
				for(int j = 0;j<cnt1;j++) {
					System.out.print(" ");
				}
				System.out.print(a[i][k]==0?" ":a[i][k]);
				for(int j = 0;j<cnt2;j++) {
					System.out.print(" ");
				}
				System.out.print(k!=3?"  ":"  ┃");
			}
			System.out.println();
			for(int k = 0;k<4;k++) {
				System.out.print(k==0? "┃         ┃":"         ┃");
			}
			System.out.println();
			System.out.print(i==3? "┠━━━━━━━━━┻━━━━━━━━━┻━━━━━━━━━┻━━━━━━━━━┫":"┠━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━┫");
			System.out.println();
		}
	}
	public static void showKey() {
		System.out.println("┃              ┏━━━━━━━━━┓              ┃");
		System.out.println("┃              ┃    ^    ┃              ┃");
		System.out.println("┃              ┃    W    ┃              ┃");
		System.out.println("┃  ┏━━━━━━━━━┓ ┃         ┃ ┏━━━━━━━━━┓  ┃");
		System.out.println("┃  ┃         ┃ ┗━━━━━━━━━┛ ┃         ┃  ┃");
		System.out.println("┃  ┃ <  A    ┃             ┃    D  > ┃  ┃");
		System.out.println("┃  ┃         ┃ ┏━━━━━━━━━┓ ┃         ┃  ┃");
		System.out.println("┃  ┗━━━━━━━━━┛ ┃         ┃ ┗━━━━━━━━━┛  ┃");
		System.out.println("┃              ┃    S    ┃              ┃");
		System.out.println("┃              ┃    ⅴ    ┃              ┃");
		System.out.println("┃              ┗━━━━━━━━━┛              ┃");
		System.out.print("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
		showColorReset();
	}
	public static void showEnd() {
		showColor();
		System.out.println("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓");
		System.out.println("┃                                       ┃");
		System.out.println("┃              게임 종료                ┃");
		System.out.println("┃                                       ┃");
		System.out.println("┠━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫");
		System.out.println("┃                                       ┃");
		System.out.printf("┃           최대 숫자 : %5d           ┃\n",max);
		System.out.println("┃                                       ┃");
		System.out.printf("┃             점수    : %5d           ┃\n",score-2);
		System.out.println("┃                                       ┃");
		System.out.printf("┃           이동 횟수 : %5d           ┃\n",moveCnt-1);
		System.out.println("┃                                       ┃");
		System.out.println("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
		showColorReset();
	}
	public static int showSet(int a) {
		int cnt = 0;
		if(a/10 == 0) {	cnt = 4;
		}else if(a/100 == 0) { cnt = 3;
		}else if(a/1000 == 0) { cnt = 2;
		}else if(a/10000 == 0) { cnt = 1;}
		
		return cnt;
	}
	public static void showColor() {
		System.out.print(BACKGROUND.WHITE_BRIHT(""));
		System.out.print(FONT.BLACK_BOLD(""));
	}
	public static void showColorReset() {
		System.out.print(FONT.RESET());
	}
	public static int moveCnt = 0;
	public static int[][] move (int[][] a, String b) {
		int[][] map = new int[4][4];
		map = a;
		if(b.equals("a")) {
			map = dragLeft(map);
		}else if(b.equals("d")) {
			map = dragRight(map);
		}else if(b.equals("w")) {
			map = dragUp(map);
		}else if(b.equals("s")) {
			map = dragDown(map);
		}
		if(!rdNonAdd(a,map)) {
			moveCnt++;
			score += 2;
		}
		return map;
	}
	public static int[][] dragLeft(int[][] a) {
		int[][] rsLeft = new int[4][4];
		for(int i = 0;i<rsLeft.length;i++) {
			int sumIdx = -1;
			int idx = -1;
			for(int k = 0;k<rsLeft[i].length;k++) {
				if(a[i][k]==0) {
					continue;
				}
				rsLeft[i][++idx] = a[i][k];
				if(sumIdx!=idx-1&&idx>0&&rsLeft[i][idx-1] == rsLeft[i][idx]) {
					rsLeft[i][idx-1]+=rsLeft[i][idx];
					if(countRepeat == 0) {
						scoreSet(rsLeft[i][idx-1]);
					}
					rsLeft[i][idx--] = 0;
					sumIdx = idx;
				}
			}
		}
		maxSet(rsLeft);
		if(gameOver(a,rsLeft,"Left")) {
			rsLeft = end();
		}else {
			if(!rdNonAdd(a,rsLeft)) {
				rsLeft = rdAdd(rsLeft);
			}
		}
		return rsLeft;
	}
	public static int[][] dragRight(int[][] a) {
		int[][] rsRight = new int[4][4];
		for(int i = 0;i<rsRight.length;i++) {
			int sumIdx = 5;
			int idx = 4;
			for(int k = rsRight.length-1;k>=0;k--) {
				if(a[i][k]==0) {
					continue;
				}
				rsRight[i][--idx] = a[i][k];
				if(sumIdx!=idx+1&&idx<3&&rsRight[i][idx+1] == rsRight[i][idx]) {
					rsRight[i][idx+1]+=rsRight[i][idx];
					if(countRepeat == 0) {
						scoreSet(rsRight[i][idx+1]);
					}
					rsRight[i][idx++] = 0;
					sumIdx = idx;
				}
			}
		}
		maxSet(rsRight);
		if(gameOver(a,rsRight,"Right")) {
			rsRight = end();
		}else {
			if(!rdNonAdd(a,rsRight)) {
				rsRight = rdAdd(rsRight);
			}
		}
		return rsRight;
	}
	public static int[][] dragUp(int[][] a) {
		int[][] rsUp = new int[4][4];
		for(int i = 0;i<rsUp.length;i++) {
			int sumIdx = -1;
			int idx = -1;
			for(int k = 0;k<rsUp[i].length;k++) {
				if(a[k][i]==0) {
					continue;
				}
				rsUp[++idx][i] = a[k][i];
				if(sumIdx!=idx-1&&idx>0&&rsUp[idx-1][i] == rsUp[idx][i]) {
					rsUp[idx-1][i]+=rsUp[idx][i];
					if(countRepeat == 0) {
						scoreSet(rsUp[idx-1][i]);
					}
					rsUp[idx--][i] = 0;
					sumIdx = idx;
				}
			}
		}
		maxSet(rsUp);
		if(gameOver(a,rsUp,"Up")) {
			rsUp = end();
		}else {
			if(!rdNonAdd(a,rsUp)) {
				rsUp = rdAdd(rsUp);
			}
		}
		return rsUp;
	}
	public static int[][] dragDown(int[][] a) {
		int[][] rsDown = new int[4][4];
		for(int i = 0;i<rsDown.length;i++) {
			int sumIdx = 5;
			int idx = 4;
			for(int k = rsDown.length-1;k>=0;k--) {
				if(a[k][i]==0) {
					continue;
				}
				rsDown[--idx][i] = a[k][i];
				if(sumIdx!=idx+1&&idx<3&&rsDown[idx+1][i] == rsDown[idx][i]) {
					rsDown[idx+1][i]+=rsDown[idx][i];
					if(countRepeat == 0) {
						scoreSet(rsDown[idx+1][i]);
					}
					rsDown[idx++][i] = 0;
					sumIdx = idx;
				}
			}
		}
		maxSet(rsDown);
		if(gameOver(a,rsDown,"Down")) {
			rsDown = end();
		}else {
			if(!rdNonAdd(a,rsDown)) {
				rsDown = rdAdd(rsDown);
			}
		}
		return rsDown;
	}
	public static int countRepeat = 0;
	public static boolean gameOver(int[][] a,int[][] b, String c) {
		boolean isOver = true;
		boolean isFull = true;
		int cnt = 0;
		for(int i = 0 ; i<4 ; i++) {
			for(int k = 0 ; k<4 ; k++) {
				if(a[i][k] != b[i][k] || a[i][k] ==0) {
					isFull = false;
					break;
				}
				cnt++;
			}
			if(!isFull) {
				break;
			}
		}
		if(cnt!=16) {
			isOver = false;
		}
		if(!isOver) {
			countRepeat = 0;
		}
		if(isOver && countRepeat < 4) {
			countRepeat++;
			if(c.equals("Down")) {
				dragLeft(a);
			}else if(c.equals("Left")) {
				dragRight(a);
			}else if(c.equals("Right")) {
				dragUp(a);
			}else if(c.equals("Up")) {
				dragDown(a);
			}
		}
		isOver = countRepeat == 4? true: false;
		return isOver;
		
	}	
	public static int[][] end() {
		int[][] endMap = new int[4][4];
		return endMap;
	}	
	public static boolean out(int[][] a) {
		boolean out = true;
		for(int i = 0;i<4;i++) {
			for(int k = 0;k<4;k++) {
				if(a[i][k] != 0) {
					out = false;
					break;
				}
			}
			if(!out) {
				break;
			}
		}
		return out;
	}	
	public static boolean programOut(int[][] a) {
		boolean programOut = false;
		if(out(a)) {
			programOut = true;
			showEnd();
		}
		return programOut;
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int[][] map = start();
		while(true) {
			showMap(map);
			showKey();
			String input = sc.next();
			map = move(map,input);
			if(programOut(map)) {
				break;
			}
		}
		sc.close();			
	}

}