23-java-1차원 배열 심화 복합문제들

jin·2022년 6월 6일
0

1. 더하기 게임

1) 1~10 사이의 숫자를 랜덤으로 7개보여준다. (중복금지)
2) 그안에서 3개의 인덱스를 고를수있게해준다. (중복금지)
3) 숫자를 하나 제시하는데 인덱스3개의 값의 합이
제시된 숫자랑 같으면 정답.
단, 정답은 여러개 일수있다.
4) 반드시 정답의 경우의 수는 있어야한다.
단! 중복으로 값을 고를순없다.
[예]
보기 = {1,5,8,6,4,2,9};
제시어 = 13
정답) 인덱스 ==> 0,2,4 ==> 1 + 8 + 4

잘못된예) 인덱스 ==> 5,5,6 ==> 2 + 2 + 9

Scanner sc = new Scanner(System.in);
Random rnd = new Random();
int num[] = new int[10];
int quiz[] = new int[7];
int index = 0;
while (true) {
	if (quiz[6] != 0) { //끝낼 조건
		break;
	}
	int rNum = rnd.nextInt(10)+1;
	if (num[rNum-1] == 0) {
		num[rNum-1] = rNum;
		quiz[index] = rNum;
		index++;
	}
}
System.out.println(Arrays.toString(quiz));

//		int question = rnd.nextInt(10)+10; // 이해를 잘못한 부분.. 그냥 될줄 알았지... quiz배열에서 중첩안되는걸로 3개 뽑아다 더해야함
int[] question = new int[3];
boolean check = false;
for (int i = 0; i < question.length; ) {
	int rNum = rnd.nextInt(7);
	check = false;
	for (int j = 0; j<question.length; j++) {
		if (question[j] == quiz[rNum]) {
			check = true;
			break;
		}
	}
	if (check == false) {
		question[i] = quiz[rNum];
		i++;
	}
}
System.out.println(Arrays.toString(question));
// 정답인덱스 고르기 = 중복x
int[] answer = new int[3];
for (int i = 0; i < answer.length; ) {
	System.out.print((i+1)+"번째 인덱스 0~6 입력 : ");
	index = sc.nextInt();
	check = false;
	for (int j = 0; j < answer.length; j++) {
		if (quiz[index] == answer[j]) {
			check = true;
			continue;
		}
	}
	if (check == false) {
		answer[i] = quiz[index];
		i++;
	} else {
		System.out.println("이미 선택한 인덱스 \n");
	}
}
System.out.println("선택한 정답 값 : "+Arrays.toString(answer));
int sum = 0;
int result = 0;
for (int i = 0; i < answer.length; i++) {
	sum += answer[i];
	result += question[i];
}
System.out.println("제시어 : " + result);
if (sum == result) {
	System.out.println("정답");
} else {
	System.out.println("오답");
}

문제 자체는 지금까지 했던 문제들을 충분히 이해했으면 사전에 답안을 보지 않고도 풀리는 문제이다. 이 문제에서 처음에 범한 오류는 반드시 경우의 수는 있어야한다 를 알아서 난수에서 범위 지정하라고 오해하여 10~20 난수를 받으면 해결되지 않을까 싶어 처음에 난수를 생성했었다.
이 경우 값이 수가 커지는 경우 등 변화가 생기면 안됐고, quiz 배열의 값들 안에서 중복되지 않는 값 3개를 더해야했었다.

2. 숫자 이동 게임

  1. 아래 배열을 사각형으로 출력한다.
  2. 각숫자는 기능이 있다.
    [1] 숫자8는 플레이어이다.
    [2] 숫자0은 이동할수있는 길이다.
    [3] 숫자1은 이동불가능한 벽이다.
    [4] 숫자3은 골인지점이다.
  3. System.out.println("1.left 2.right 3.up 4.down");
    번호를 입력받고 각 방향으로 한칸씩 이동 가능
  4. left
    {1,1,1,1,1,
    1,0,0,0,1,
    1,8,0,0,1,
    1,0,0,0,3,
    1,1,1,1,1}
  5. 계속 이동하다가 3에 도착하면 종료.
 Scanner sc = new Scanner(System.in); 
		
int[] game = {
		  1, 1, 1, 1, 1,
		  1, 0, 0, 0, 1,
		  1, 0, 8, 0, 1,
		  1, 0, 0, 0, 3,
		  1, 1, 1, 1, 1
		  };

int player = 12; // 현재 플레이어위치 

System.out.println("1.left  2.right 3.up 4.down");
// 배열을 사각형으로 출력하기
for (int i = 0; i < game.length; i++) {
	if (i % 5 == 0 && i !=0) {
		System.out.println();
	}
	System.out.printf("%d ",game[i]);
}
// 3의 인덱스 구하기
int goal = 0;
for (int i = 0; i < game.length; i++) {
	if (game[i] == 3) {
		goal = i;
		break;
	}
}
while (true) {
	if (player == 19) {
		System.out.println("3 도착 \n게임 종료");
	break;
}

int temp = 0;
temp = player;
System.out.println("1.left  2.right 3.up 4.down");
int select = sc.nextInt();
if (select == 1) {
	player -= 1;
} else  if (select == 2) {
	player += 1;
} else if (select == 3) {
	player -= 5;
} else if (select == 4) {
	player += 5;
}
// 1.left  2.right 3.up 4.down ==> left -1 / right +1 / up -5 / down +5
if (game[player] == 0) {
	game[player] = 8;
	game[temp] = 0;
} else if (game[player] == 1) {
	System.out.println("1과 만남 이동x");
	player = temp;
}
for (int i = 0; i < game.length; i++) {
	if (i % 5 == 0 && i !=0) {
		System.out.println();
	}
	System.out.printf("%d ",game[i]);
}
System.out.println("\n");
}

지금까지 배열에 머리를 쥐어짜면서 푼 덕분에 인덱스에 대한 이해가 어느정도 되었는지 스무스하게 풀렸다. 잠깐 고민했던 부분은 3에서 만났을때도 이동을 안했었는데 조건문을 다시 한번 보니 0이 아닐때 이동으로 조건을 지정하여 3이어도 안갔던 것이다. 어디가 문제인지 금방 캐치하여 그렇게 시간이 소비되진 않았다.

3. 틱택토

[틱택토]
조건1) 구글 크롬에 "틱택토" 검색후 게임을 한번하고 아래와같이 만들어보기.
조건2) P1 , P2 를 플레이어가 번갈아가면서 플레이.
조건3) 먼저 한줄을 완성하면 승리
[추천조건] P2 는 com으로 대체해보자.(com은 랜덤으로 플레이)

Random rnd = new Random();
Scanner  sc = new Scanner(System.in);

int[] tic = new int[9];
int p = 0;
int com = 0;
int win = 0;
int turn = 0; 

for (int i = 0; i < tic.length; i++) {
	System.out.printf("%d ", tic[i]);
	if (i % 3 == 2) {
		System.out.println();
	}
}
while (true) {
	if ((tic[0] == 1 && tic[1] == 1 && tic[2] == 1 )|| (tic[0] == 2 && tic[1] == 2 && tic[2]==2)) {
		if (tic[0] == 1) {
			win = 1;
		} else if (tic[0] == 2) {
			win = 2;
		}
	} else if ((tic[3] == 1 && tic[4] == 1 && tic[5] == 1) || (tic[3] == 2 && tic[4] == 2 && tic[5] == 2)) {
		if (tic[3] == 1) {
			win = 1;
		} else if (tic[3] == 2) {
			win = 2;
		}
	} else if ((tic[6] == 1 && tic[7] == 1 && tic[8] == 1) || (tic[6] == 2 && tic[7] == 2 && tic[8] == 2)) {
		if (tic[6] == 1) {
			win = 1;
		} else if (tic[6] == 2) {
			win = 2;
		}
	} else if ((tic[0] == 1 && tic[3] == 1 && tic[6] == 1) || (tic[0] == 2 && tic[3] == 2 && tic[6] == 2)) {
		if (tic[0] == 1) {
			win = 1;
		} else if (tic[0] == 2) {
			win = 2;
		}
	} else if ((tic[1] == 1 && tic[4] == 1 && tic[7] == 1) || (tic[1] == 2 && tic[4] == 2 && tic[7] == 2)) {
		if (tic[0] == 1) {
			win = 1;
		} else if (tic[0] == 2) {
			win = 2;
		}
	} else if ((tic[2] == 1 && tic[5] == 1 && tic[8] == 1) || (tic[2] == 2 && tic[5] == 2 && tic[8] == 2)) {
		if (tic[2] == 1) {
			win = 1;
		} else if (tic[2] == 2) {
			win = 2;
		}
	} else if ((tic[0] == 1 && tic[4] == 1 && tic[8] == 1) || (tic[0] == 2 && tic[4] == 2 && tic[8] == 2)) {
		if (tic[0] == 1) {
			win = 1;
		} else if (tic[0] == 2) {
			win = 2;
		}
	} else if ((tic[2] == 1 && tic[4] == 1 && tic[6] == 1) || (tic[2] == 2 && tic[4] == 2 && tic[6] == 2)) {
		if (tic[2] == 1) {
			win = 1;
		} else if (tic[2] == 2) {
			win = 2;
		}
	}
	if(win == 1 || win == 2) {
		if (win == 1) {
			System.out.println("player 승");
		} else if (win == 2) {
			System.out.println("cpu 승");
		}
		break;
	}
	System.out.println("==============");
	
	boolean check = false;
	//조건문 턴넘기기
	if (turn % 2 == 0) {
		System.out.println("플레이어 턴");
		System.out.print("인덱스 입력 : ");
		p = sc.nextInt();
		for (int i = 0; i < tic.length; i++) {
			if(tic[p] != 0) {
				System.out.println("이미 선택한 인덱스");
				check = true;
				break;
			}
		}
		if (check == true) {
			continue;
		}
		tic[p] = 1;
		turn += 1;
	} else {
		System.out.println("cpu 턴");
		int rNum = rnd.nextInt(9);
		System.out.println("선택 인덱스 : " + rNum);
		for (int i = 0; i < tic.length; i++) {
			if (tic[rNum] != 0) {
				System.out.println("이미 선택한 인덱스");
				check = true;
				break;
			}
		}
		if (check == true) {
			continue;
		}
		tic[rNum] = 2;
		turn +=1;
	}
	for (int i = 0; i < tic.length; i++) {
		System.out.printf("%d ", tic[i]);
		if (i % 3 == 2) {
			System.out.println();
		}
	}
	System.out.println();
}

틱택토의 승리조건은 8가지다. 가로3열, 세로 3열, 왼쪽 대각, 오른쪽 대각
이에 대한 검사를 반복문인가 조건문인가 고뇌의 시간을 가졌다.
지금 1차원 배열 파트인데 이걸로 검사를 한다면 컴퓨터도 비효율적이지 않나? 아무리 생각해도 조건문이 쉽고 간단한데 하지만 그동안 반복문을 배웠는데 반복문을 해야하나 그렇지만 효율이(이하생략
이에 대해 선생님께 질문했더니 반복문을 쓰고 싶다면 2차원 배열의 틱택토 업그레이드인 오목에서 하면 깨달음이 올거라고... 네?
어차피 조건이 8가지뿐이니 복붙의 힘을 빌려 검사하라는 말을 들었다. 하지만 이에 굴하지 않고 반복문으로 조건을 검사하는 코드를 작성했으나 아무리 생각해도 1차원 배열로는 조건문만한 효율이 안나와서 포기했다.

이로써 1차원 배열 챕터가 끝났다. 다음 챕터는 2차원 배열... 와~ 정말~ 신난다~~~

0개의 댓글