전체 글 (135)

728x90

09/22~09/24

09/25 수정

 

1. 주제 정하기

  • 조끼리 주제를 정한 뒤, 그 주제를 따로 혹은 같이 만들어보라는 과제를 주셔서 우리 조는 공통 주제로 섯다를 골랐고, 따로 만들기로 했다. 문제는 내가 섯다룰을 모른다는 점이었고, 추가적으로 섯다 룰에는 특수한 패가 있어서 더 어려울 것 같아서 먼저 합으로만 이기는 룰부터 만들어보기로 하고 차근차근 룰을 추가하거나 하는 식으로 진행하게 됐다.
  • 배운 것들은 많지만 이것들로만 만들기엔 어려울 것 같아 구글링도 하면서 해보기로 했다.

 

주제: 섯다
#룰 전부 구현한것 아님!#

 

2. 기본 틀

 2-1) import

import java.security.DrbgParameters.NextBytes;
import java.util.Random;
import java.util.Scanner;
Random random = new Random(); // 랜덤 객체 생성
Scanner sc = new Scanner(System.in);
  • Random: 카드 게임이니 할 때마다 달라지게 하기 위해 넣었다.
  • Scanner: 메뉴 선택 등, 값을 입력받아와야 할 때를 위해 넣었다.

 

 2-2) 변수 선언

int menu = 0;
int m = -1;
boolean run = true;
  • 어떻게 할 지 감을 잡기 전에 당장 넣어둘 수 있는 변수들만 먼저 선언해뒀다.
  • 계속 해보면서 추가적으로 필요한 변수들을 선언할 예정이다.

 

 2-3) 메뉴

System.out.println("============= GameMenu =============");
	while(run) {
	
	if(m == -1) {
		System.out.print("1.게임시작 2.규칙설명 0.게임종료\n메뉴 선택> ");
		menu = sc.nextInt();
	}else {
		System.out.print("1.게임시작 0.게임종료\n메뉴 선택> ");
		menu = sc.nextInt();
	}
	
	if(menu == 1) {
		System.out.println("============ GameStart! ============");
	
	}else if(menu == 2 && m==-1) {
		System.out.println("============= GameRule =============");
		System.out.println(" > 1부터 10까지의 카드가 두 장씩, 총 20장 있습니다.");
		System.out.println(" > 플레이어와 PC는 각 2장 씩 배정받습니다.");
		System.out.println(" > 기본적으로는 배정받은 카드 두 장의 총합이 큰 쪽이 승리합니다.");
		System.out.println(" > 특수한 상황으로는 동일한 숫자의 카드인 경우,\n"
					+ "\t상대보다 총합이 낮아도 승리합니다.");
		System.out.println(" > 양 쪽 모두 동일한 숫자의 카드인 경우,\n"
					+ "\t숫자가 큰 쪽이 승리합니다.");
		System.out.println();
		m = 0;
		
	}else if(menu == 0) {
		run = false;
	}else {
		System.out.println(" > 존재하는 메뉴를 선택해주세요.\n");
		m = -1;
	}
	
}
System.out.println(" > 게임이 종료됩니다.");
System.out.println("====================================");
  • 금요일에 상황에 따라 메뉴가 다르게 출력되는 것을 배우고 써먹어보고 싶어서 규칙 설명 후에 뜨는 메뉴에는 규칙 설명을 없애고, 메뉴 선택을 2로 할 시 존재하는 메뉴를 선택해달라는 안내를 출력하도록 했다.

 

 > 콘솔 창에 뜨는 모습 ㄱ

더보기

 > 첫 화면

 

 > 메뉴에서 1.게임시작 선택 시

  • 아직 아무것도 적어놓지 않아서 맨 처음의 메뉴선택만 계속 반복해서 뜬다.

 

 > 메뉴에서 2.규칙설명 선택 시

  • 규칙 설명이 출력된다.
  • 방금 규칙설명을 출력했는데 또 메뉴에서 규칙설명을 띄울 수 있게 하는 것은 불필요할 것 같아서 1.게임시작과 0.게임종료만 남겨놨다.

 

 > 메뉴에서 0.게임종료 선택 시

  •  게임이 종료된다는 안내 출력 후, 게임이 종료된다.

 

 > 없는 메뉴 선택 시!

  •  존재하지 않는 메뉴라고 출력하고, 다시 메뉴 선택을 할 수 있게 메뉴 안내를 출력했다.

 

 > 주저리 ㄱ

더보기

규칙 설명만 적어놨는데 벌써부터 길어져서 매우 두려웠다..

아직 모르는 것들이 많아서 제대로 할 수 있을진 모르겠지만 대충이나마 완성할 수 있으면 좋을 것 같다..!

 

 

3. 중복없이 랜덤한 숫자를 뽑는 코드 (연습장)

  • 랜덤한 숫자를 뽑는 코드는 수업을 하며 접해본 적은 있지만 중복되는 숫자가 있었다.
  • 게임을 위해서라면 중복되는 숫자가 없어야 할 텐데, 어떻게 해야하는지 모르고 있었기 때문에 몇 번 해보다가 인터넷에 검색해봤다.
  • 한 블로그에 중복없는 랜덤 구현하기 (링크) 라는 글이 있길래 완전 따라서 써보고 제대로 돌아가는지 확인한 다음에 참고를 했다.
//코드
int[] dex = {1,2,3,4,5,6,7,8,9,10};	//10
int[] card1 = new int[2];	//card1~2 0번째 인덱스: pc
int[] card2 = new int[2];	//card1~2 1번째 인덱스: player

for(int i=0; i<card1.length; i++) {
	card1[i] = dex[rd.nextInt(10)];
	card2[i] = dex[rd.nextInt(10)];
	for(int j=0; j<i; j++) {
		if(card1[i] == card1[j] || card2[i] == card2[j]) {
			i--;
		}
	}
}

// 출력
for(int i=0; i<card1.length; i++) {
	if(i == 0) {
		System.out.println("> pc");
	}else if(i == 1) {
		System.out.println("> player");
	}
	System.out.print(card1[i]+" "+card2[i]+"\n");
	System.out.println();
}
  • 1부터 10까지의 카드가 각 두 장씩 있다고 그랬으니 배열 하나에 값을 저장했다.
  • pc와 player로 배열을 저장하는 것보다 첫번째 카드끼리, 두번째 카드끼리 나눠서 저장하는 편이 내가 코드를 쓰기 편할 것 같아서 첫번째 카드 값은 card1 배열에, 두번째 카드 값은 card2 배열에 저장하도록 했다.
  • 콘솔창에는 아래 사진처럼 출력된다.

 

 > 시도의 흔적 ㄱ

더보기

 > 검색하기 전에 도전

  • 내가 만들어둔 배열 안에 있는 랜덤이긴 하지만, 중복의 값이 나올 수 있어서 실패했다.
  • 다른 방법들도 모두 중복을 제거하진 못했다.

 

  > 검색하고 난 후의 시도들

  • 제대로 중복이 아니게 나오긴 하지만, 0도 같이 나와서 실패
  • 확인해보니 그저 +1을 안 써서 그런거였다.
  • 근데 이렇게 하면 한 사람 같은 숫자 두 장을 가지게 할 수 없어서 +1을 해준다고 해도 룰에 맞지 않는 코드였다.

 

  • 제대로 +1을 적용해서 사용했지만, 콘솔창에 출력됐듯이 중복되는 숫자가 3개의 숫자가 나올 수 있었다.

 

  • 드디어 중복값 3개가 안 나오게 잘 나오게 되었다!
  • 그런데 코드를 조금 수정하면 좀 더 괜찮을 것 같아서 수정하기로 했다.
  • 아직 룰을 세세하게 만지 않아, 같은 숫자를 두번씩 넣을 필요가 없을 것 같아서 삭제했다.

 

 > 주저리 ㄱ

더보기

중복없이 랜덤 숫자를 뽑는 방법이 생각보다 간단했다. 저런 방법을 분명 수업 중에 써봤던 것 같은데..검색하기 전에 떠올리지 못한 것을 아직 코드들이 익숙치 못하다는 자기합리화를 하면서 지나갔다..

보고나서 응용하면서 시도한 것도 중복이 나와서 머리가 아팠다. 분명 중복이 나오지 않을 것이라고 확신하면서 돌렸는데 같은 숫자가 3개 나오는 것을 보고 확신하면 안 된다는 것을 다시 한 번 깨닫게 되었다.

사실 지금도 되는 이유는 확실히 모르겠다. 이것도 오류가 있지 않을까? 싶다. 일단 지금은 수십번 돌려도 제대로 나오니 괜찮겠지..하고 넘어가는 중이다..

분명 이것보다 더 나은 코드가 있겠지만 내 머리로는 이게 한계였다.

 

 

4. 룰을 적용한 코드 (연습장)

 4-1) 합이 큰 쪽이 승리

int pc = 0;
int player = 0;
  • 우선 합을 구하기 위해 새로운 변수를 지정했다.
  • 출력만 한다면 pc의 손패 값은 (card1[0]+card2[0]), player의 손패 값은 (card1[1]+card2[1])으로 해도 되겠지만, 룰을 적용해 승패를 나누기 위해서는 변수를 사용하는 것이 편할 것이라고 판단했다.

 

pc = card1[0]+card2[0];
player = card1[1]+card2[1];

if(pc > player) {
	System.out.println("player 패!");
}else if(pc < player) {
	System.out.println("player 승리!");
}else {
	System.out.println("무승부");
}
  • 위의 3. 중복없이 랜덤한 숫자를 뽑는 코드를 돌린 뒤, pc와 player 변수에 첫번째, 두번째 카드의 합을 대입했다.
  • 만약 pc의 카드 합 값이 player의 카드 합 값보다 클 경우, pc 승리 / player 패
  • 만약 player의 카드 합 값이 pc의 카드 합 값보다 클 경우, pc 패 / player 승리
  • 만약 pc의 카드 합 값과 player의 카드 합 값이 같다면, 무승부

 

 4-2) 두 카드가 같은 숫자인 쪽이 승리 (단, 양 측 모두 같은 숫자라면 값이 큰 쪽이 승리)

if(card1[0]==card2[0] && card1[1]==card2[1]) {
	System.out.println("pc와 player 모두 갖고있는 두 카드가 동일한 숫자이므로,\n"
				+ "숫자가 큰 쪽이 승리합니다.");
	if (pc > player) {
		System.out.println("pc 승리!\nplayer 패!");
	} else if (pc < player) {
		System.out.println("pc 패!\nplayer 승리!");
	} 
}
  • 만약 pc와 player 모두 갖고있는 두 카드가 동일한 숫자일 경우, 숫자가 큰 쪽이 승리한다.

pc와 player 모두 갖고있는 두 카드가 동일하지만, player의 숫자가 크므로 player 승리

 

else if(card1[0]==card2[0] || card1[1]==card2[1]) {
	if(card1[0]==card2[0]) {
		System.out.println("pc가 갖고있는 두 카드가 동일한 숫자이므로,");
		System.out.println("pc 승리!\nplayer 패!");
	}else if (card1[1]==card2[1]) {
		System.out.println("player가 갖고있는 두 카드가 동일한 숫자이므로,");
		System.out.println("pc 패!\nplayer 승리!");
	}
}
  • 만약 pc가 갖고 있는 두 카드가 동일한 숫자일 경우, player의 값이 크더라도 pc가 승리한다.
  • 그렇지 않고 player가 갖고 있는 두 카드가 동일한 숫자일 경우, pc의 값이 크더라도 player가 승리한다.

pc의 카드 합이 더 크지만, player의 카드가 동일하기 때문에 player가 승리

 

else {
	if (pc > player) {
		System.out.println("pc 승리!\nplayer 패!");
	} else if (pc < player) {
		System.out.println("pc 패!\nplayer 승리!");
	} else {
		System.out.println("무승부");
	}
	System.out.println();
}

pc와 player 모두 갖고있는 두 카드가 동일하지 않아, 두 카드의 합이 큰 pc 승리

 

 

5. 룰을 적용한 코드를 정리해서 기본 틀에 넣기

 5-1) 추가로 선언해둘 변수

// 새로 선언한 변수
int pc = 0;
int player = 0;

 

 5-2) 안내 문구(간단한 꾸밈새) 출력

System.out.println("============ GameStart! ============");
System.out.println(" > 패를 섞는 중입니다.\n\n\t*\n\n\t*\n\n\t*\n");

 

 5-3) 첫번째 패 뽑기

System.out.println(" > 첫번째 패를 뽑으시려면 숫자키를 아무거나 입력해주세요.");
System.out.print("패뽑기> ");
int select = sc.nextInt();

for (int i = 0; i < card1.length; i++) {
	card1[i] = dex[rd.nextInt(10)];
	card2[i] = dex[rd.nextInt(10)];
	for (int j = 0; j < i; j++) {
		if (card1[i] == card1[j]) {
			i--;
		}
	}
}
System.out.println(" > 첫번째 패: "+card1[1]);
System.out.println();

 

  • 패 뽑는 것을 따로 한 장씩 하면 재미있을거 같아서 나눠놨다.
  • player가 첫번째 패를 뽑으면 pc도 같이 뽑게 된다.
  • 이때, player는 pc의 패를 알 수 없다.

 

 5-4) 두번째 패 뽑기

System.out.println(" > 두번째 패를 뽑으시려면 숫자키를 아무거나 입력해주세요.");
System.out.print("패뽑기> ");
select = sc.nextInt();

for (int i = 0; i < card1.length; i++) {
	card2[i] = dex[rd.nextInt(10)];
	for (int j = 0; j < i; j++) {
		if (card2[i] == card2[j]) {
			i--;
		}
	}
}
System.out.println(" > 두번째 패: "+card2[1]);
System.out.println();
  • 첫번째 패 뽑기와 동일하게 player가 패를 뽑으면 pc도 같이 뽑게 된다.

 

 5-5) pc와 player의 손패 합

System.out.println("\n > 결과를 확인하시려면 숫자키를 아무거나 입력해주세요.");
System.out.print("결과 확인> ");
select = sc.nextInt();

pc = card1[0] + card2[0];
player = card1[1] + card2[1];
System.out.println("pc 손패 합> " + pc); // pc의 카드 총합
System.out.println("player 손패 합> " + player); // player의 카드 총합
  • 아무래도 섯다 기반이다 보니 베팅을 넣어야 할 것 같아서 결과 확인도 따로 키를 눌러야 작동하도록 해놨다.
  • 결과 확인을 위해 아무 키나 입력하면, 선언해둔 변수에 pc와 player의 패를 각각 합한 값을 대입한다.
  • 각각의 손패 합을 출력한다.

 

 5-6) 승패 결과

if(card1[0]==card2[0] && card1[1]==card2[1]) {
	System.out.println("pc와 player 모두 갖고있는 손패가 동일한 숫자이므로,\n");
	if (pc > player) {
		System.out.println("pc 승리!\nplayer 패!");
	} else if (pc < player) {
		System.out.println("pc 패!\nplayer 승리!");
	} 
}else if(card1[0]==card2[0] || card1[1]==card2[1]) {
	if(card1[0]==card2[0]) {
		System.out.println("pc가 갖고있는 손패가 동일한 숫자이므로,\n");
		System.out.println("pc 승리!\nplayer 패!");
	}else if (card1[1]==card2[1]) {
		System.out.println("player가 갖고있는 손패가 동일한 숫자이므로,\n");
		System.out.println("pc 패!\nplayer 승리!");
	}
}else {
	if (pc > player) {
		System.out.println("pc 승리!\nplayer 패!");
	} else if (pc < player) {
		System.out.println("pc 패!\nplayer 승리!");
	} else {
		System.out.println("무승부");
	}
	System.out.println();
}
  • 손패에 따라, 손패의 합 값에 따라 if문을 이용해 룰을 적용했다.
  • 만약 pc와 player의 모두 갖고있는 손패가 동일한 숫자일 경우, 손패 숫자가 큰 쪽이 승리한다.
    • ex) pc의 손패: 1, 1 / player의 손패: 2, 2
    • player의 승리
  • 그렇지 않고 pc(혹은 player)가 갖고있는 손패만 동일한 숫자일 경우, 동일한 손패를 가지고 있는 쪽이 승리한다.
    • ex) pc의 손패: 1, 1 / player의 손패: 10, 7
    • pc의 승리
  • 그렇지 않고 양측 모두 갖고있는 손패가 동일한 숫자가 없을 경우, 손패의 합이 큰 쪽이 승리한다.
    • ex) pc의 손패: 3, 5 / player: 7, 6
    • player의 승리
    • 단, 숫자 합이 같은 경우, 무승부가 된다.

 

 > 주저리 ㄱ

더보기

타이틀을 뭐라고 적어야 할 지 모르겠다...

 

 

6. 베팅 추가

 6-1) 잔액 및 충전 추가

  • 변수 변경
int m = 0;
  • 상황에 따라 메뉴가 다르게 출력되는 메뉴를 다르게 하려다보니 베팅 시스템을 추가하면서 여러가질 고치게 됐다.
  • 그러다가 변수의 초기화 값도 변경하게 됐다.

 

  • 메뉴 선택 변경 및 추가
if(m == 0) {
	System.out.printf("============= GameMenu ============="
			+ "\n > 잔액: %,d원\n",wallet);
	System.out.print("1.게임시작 2.규칙설명 3.충전 0.게임종료\n메뉴 선택> ");
	menu = sc.nextInt();
}else if(m == -1) {
	System.out.print("1.게임시작 2.규칙설명 0.게임종료\n메뉴 선택> ");
	menu = sc.nextInt();
}
  • 첫화면에서 현재 잔액을 확인할 수 있도록 메뉴 밑에 잔액을 추가했다.
  • 메인에서 선택할 메뉴와 규칙설명에서 선택할 메뉴는 이미 만들어뒀으니, 충전 화면에서 선택할 메뉴를 비슷한 구성으로 추가해놨다.

 

  • 규칙 설명 메뉴의 조건 변경
else if(menu == 2 && (m==-1 || m==0))
  • 원래 menu가 2이고, m이 -1일때 실행한다는 조건이었는데, 충전 메뉴가 생기면서 m이 -1이거나, 0일때 실행으로 변경했다.

 

  • 충전 메뉴 추가
else if(menu==3 && m==0 || (menu==2 && (m!=0 || m!=-1))) {
	System.out.printf("============ Game Money ============"
			+ "\n > 현재 잔액: %,d원\n",wallet);
	System.out.print(" > 충전하시겠습니까?\n1.예 2.아니오\n메뉴 선택> ");
	int select = sc.nextInt();
	if(select == 1) {
		System.out.println("      -------------------------");
		System.out.print(" > 충전할 금액을 입력해주세요.\n충전 할 금액> ");
		int inmoney = sc.nextInt();
		System.out.println("\n > 충전이 성공적으로 완료되었습니다.");
		System.out.printf(" > 충전한 금액: %,d원\n",inmoney);
		wallet+=inmoney;
		System.out.printf(" > 충전 후 금액: %,d원\n\n",wallet);
	}else if(select != 2) {
		System.out.println(" > 존재하는 메뉴를 선택해주세요.\n");
	}
	m = -1;
	
}
  • m이 0이고 menu가 3일때, 실행한다.
  • m이 0이나 -1이 아니고 menu가 2일때, 실행한다.
  • 현재 잔액을 출력하고, 충전하겠냐는 답변을 받아온다.
  • 1을 입력받으면 충전을 진행하고, 2가 아닐 때 존재하는 메뉴를 선택해달라는 말을 출력한다.
    (1을 거르지 않은 이유는 1 선택 시 위에서 이미 걸러지기 때문이다.)

 > 콘솔창에 뜨는 모습 ㄱ

더보기
  • 충전 할 때의 화면

 

  • 충전 안 할 때의 화면

 

 > 주저리 ㄱ

더보기

메뉴 선택을 메인 화면일때, 설명 화면일때, 충전화면일때를 나눠놓으려고 하니까 너무 헷갈렸다.

if문에 menu==3 && m==0 || menu==2 && m!=0 && m!=-1 이런거 적을때가 가장 헷갈렸다. 쉽게 알아봐야 좋은 코딩아닌가..ㅠㅠ 아직 나에겐 이정도가 한계였다.

그나마 컴 메모장이나 일반 노트에 이렇게 하겠다! 하고 적어놓고 해서 잊어먹지 않고 할 수 있었던 것 같다.

 

 6-2) 규칙설명 수정

  • 출력 문구 외엔 따로 코드를 수정하진 않아서 콘솔 출력창 캡쳐로 대신했다.

 

 6-3) 베팅

  • 변수 선언
int bet = 0;
  • 베팅금을 저장해두기 위해 새로운 변수를 선언했다.

 

  • 베팅하기
System.out.println(" > 손패 확인: "+card1[1] + " " + card2[1]);
				
for(int i=0; i<1; i++) {
	System.out.println(" > 베팅하시겠습니까?\n"
			+ " > 아니오 선택 시, 최소 베팅금인 1,000원이 베팅됩니다."
			+ "\n1.예 2.아니오\n메뉴 선택> ");
	System.out.print("메뉴 선택> ");
	select = sc.nextInt();
	if(select == 1) {
		System.out.println("      베팅금 선정-----------------------");
		for(int j=0; j<1; j++) {
			System.out.printf(" > 현재 잔액: %,d원",wallet);
			System.out.print("\n > 베팅하실 금액을 입력해주세요.\n베팅 금액> ");
			bet = sc.nextInt();
			if(bet<1000) {
				System.out.println(" > 최소 베팅 금액은 1,000원입니다.");
				j--;
			}						
		}						
		wallet -= bet;
		System.out.println("      베팅 완료!------------------------");
		System.out.printf(" > 베팅 후 잔액: %,d원",wallet);
	}else if(select == 2) {
		System.out.println(" > 최소 베팅금인 1,000원이 베팅됩니다.");
		bet = 1000;
		wallet -= bet;
		System.out.printf(" > 베팅 후 잔액: %,d원",wallet);
	}else {
		System.out.println(" > 존재하는 메뉴를 선택해주세요.\n");
		i--;
	}
}
  • player의 손패만 확인한다.
  • for문 안의 for문
    • 바깥 for문에서는 존재하는 메뉴를 선택하지 않을 시, 계속 반복하도록 했다.
    • 안쪽 for문에서는 베팅금을 1천원 미만으로 입력하면 계속 반복하도록 했다.

 

  • 승패에 따른 베팅금 나누기
if(card1[0]==card2[0] && card1[1]==card2[1]) {
	System.out.println("pc와 player 모두 갖고있는 손패가 동일한 숫자이므로,\n");
	if (pc > player) {
		System.out.println("pc 승리!\nplayer 패!\n"
				+ " > player의 패배로 베팅금을 잃으셨습니다.");
	} else if (pc < player) {
		System.out.println("pc 패!\nplayer 승리!"
				+ " > player의 승리로 베팅금의 반을 획득하셨습니다.");
		System.out.printf("베팅한 금액: %,d원\n획득한 금액: %,d원\n",bet,bet/2);
		wallet += bet;
		wallet += bet/2;
	} 
}else if(card1[0]==card2[0] || card1[1]==card2[1]) {
	if(card1[0]==card2[0]) {
		System.out.println("pc가 갖고있는 손패가 동일한 숫자이므로,\n");
		System.out.println("pc 승리!\nplayer 패!\n"
				+ " > player의 패배로 베팅금을 잃으셨습니다.");
	}else if (card1[1]==card2[1]) {
		System.out.println("player가 갖고있는 손패가 동일한 숫자이므로,\n");
		System.out.println("pc 패!\nplayer 승리!"
				+ " > player의 승리로 베팅금의 반을 획득하셨습니다.");
		System.out.printf("베팅한 금액: %,d원\n획득한 금액: %,d원\n",bet,bet/2);
		wallet += bet;
		wallet += bet/2;
	}
}else {
	if (pc > player) {
		System.out.println("pc 승리!\nplayer 패!\n"
				+ " > player의 패배로 베팅금을 잃으셨습니다.");
	} else if (pc < player) {
		System.out.println("pc 패!\nplayer 승리!"
				+ " > player의 승리로 베팅금의 반을 획득하셨습니다.");
		System.out.printf("베팅한 금액: %,d원\n획득한 금액: %,d원\n",bet,bet/2);
		wallet += bet;
		wallet += bet/2;
	} else {
		System.out.println("무승부"
				+ " > 베팅하신 금액을 돌려받으셨습니다.");
		System.out.printf("베팅한 금액: %,d원\n",bet);
		wallet += bet;
	}
	System.out.println();
}
  • 승패 결과에 따라 베팅금을 돌려받으면서 상금을 획득하거나, 베팅금을 잃거나, 베팅금만 돌려받도록 했다.

 

 > 주저리 ㄱ

더보기

for문 안에 for문을 만들었다는 것을 까먹고 왜 for문인데 i가 안 되는지 잠깐 고민했다. 내가 내 코드를 모르면 안 되는데..

 

 


 

어려웠던 점 메모

 

1. 중복없는 랜덤 숫자 뽑기

 

2. 상황에 따른 메뉴 출력

  • 상황이 2개가 아닌 3개로 생각하고 하려니 너무 헷갈렸다. -1일때의 상황과 그 외의 상황만 다루면 되는 것에서 -1일때, 0일때, 그 외의 상황일때로 딱 하나의 상황만 추가됐는데 너무 헷갈려서 여러번 검수를 해야했다.

 

 


 

전체 피드백

  • 처음부터 끝까지 혼자 생각하고 코드를 짜려다보니 어려웠지만, 룰을 간단하게 설정했더니 생각보다 어렵지 않았던 것 같다. 비록 섯다의 룰을 전부 구현하진 못했지만 랜덤한 패를 중복없이 뽑아 그 패의 합이나 상황을 보고 승패를 결정하는 것까지는 구현해서 기뻤다.
  • 블로그랑 코딩이랑 같이 하려고 하니까 수정하거나 추가한 것을 까먹고 못적은 것도 있는 것 같다.
  • 금요일에 선생님이 보여주신 것처럼 네모박스라던가 넣어서 꾸밈을 넣고 싶었는데 한국어로 검색하니 그런지 잘 안 나와서 포기했다. 나중에는 꾸밈을 넣어보고싶다!
  • 마지막에 연습했던 클래스에서 게임을 저장할 클래스로 옮기면서 몇개가 고치기 전으로 돌아가서 수정한 점이 꽤 있다..복사해올 때에는 귀찮다고 확인도 없이 한 번에 옮기지 말고 꼭 두세번은 확인해본 이후에 옮길 것!

 

 + 불필요한 코드가 많아서 그런가 아니면 출력되는 글을 많이 적어서 그런가 조장님이 짜신 코드의 두배는 되는 것 같다ㅠ

 

 >  전체 코드 ㄱ

더보기

25일 수정 

카드게임_최종.txt
0.01MB

 


 

우선 내가 돌려봤을 때는 오류 없이 돌아갔는데, 내가 찾지 못한 오류가 있을 것 같다..

카드게임.txt
0.01MB
package day07;

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

public class game {
	

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Random rd = new Random(); // 랜덤 객체 생성
		Scanner sc = new Scanner(System.in);
		
		// 변수 선언
		int[] dex = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 10
		int[] card1 = new int[2]; // card1~2 0번째 인덱스: pc
		int[] card2 = new int[2]; // card1~2 1번째 인덱스: player
		int pc = 0; // pc의 카드 총합
		int player = 0; // player의 카드 총합
		int wallet = 10000;	// 잔액
		int bet = 0; //베팅금
		int menu = 0;
		int m = 0;
		boolean run = true;
		
		
		while (run) {

			if (m == 0) {
				System.out.printf("============= GameMenu =============" + "\n\t\t\t잔액: %,d원\n", wallet);
				System.out.print("1.게임시작 2.규칙설명 3.충전 0.게임종료\n메뉴 선택> ");
				menu = sc.nextInt();

			} else if (m == -1) {
				System.out.print("1.게임시작 2.규칙설명 0.게임종료\n메뉴 선택> ");
				menu = sc.nextInt();
			} else {
				System.out.print("1.게임시작 2.충전 0.게임종료\n메뉴 선택> ");
				menu = sc.nextInt();
			}
			System.out.println();

			if (menu == 1 && wallet < 1000) {
				System.out.println(" > 잔액이 부족합니다.\n > 게임 플레이에는 잔액이 최소 1,000원이 필요합니다.\n");

			} else if (menu == 1) {
				System.out.println("============ GameStart! ============");
				System.out.println(" > 패를 섞는 중입니다.\n\n\t*\n\n\t*\n\n\t*\n");

				// 첫번째 패 뽑기
				System.out.println(" > 첫번째 패를 뽑으시려면 숫자키를 아무거나 입력해주세요.");
				System.out.print("패뽑기> ");
				int select = sc.nextInt();

				for (int i = 0; i < card1.length; i++) {
					card1[i] = dex[rd.nextInt(10)];
					card2[i] = dex[rd.nextInt(10)];
					for (int j = 0; j < i; j++) {
						if (card1[i] == card1[j]) {
							i--;
						}
					}
				}
				System.out.println(" > 첫번째 패: " + card1[1]);
				System.out.println();

				// 두번째 패 뽑기
				System.out.println(" > 두번째 패를 뽑으시려면 숫자키를 아무거나 입력해주세요.");
				System.out.print("패뽑기> ");
				select = sc.nextInt();

				for (int i = 0; i < card1.length; i++) {
					card2[i] = dex[rd.nextInt(10)];
					for (int j = 0; j < i; j++) {
						if (card2[i] == card2[j]) {
							i--;
						}
					}
				}
				System.out.println(" > 두번째 패: " + card2[1]);
				System.out.println();

				// 베팅
				System.out.println(" > 손패 확인: " + card1[1] + " " + card2[1]); // player의 손패

				for (int i = 0; i < 1; i++) {
					System.out.print(" > 베팅하시겠습니까?\n" + " > 아니오 선택 시, 최소 베팅금인 1,000원이 베팅됩니다." + "\n1.예 2.아니오\n메뉴 선택> ");
					select = sc.nextInt();

					if (select == 1) {
						System.out.println("      베팅금 선정-----------------------");
						for (int j = 0; j < 1; j++) {
							System.out.printf(" > 현재 잔액: %,d원", wallet);
							System.out.print("\n > 베팅하실 금액을 입력해주세요.\n베팅 금액> ");
							bet = sc.nextInt();
							if (bet < 1000) {
								System.out.println(" > 최소 베팅 금액은 1,000원입니다.");
								j--;
							}
						}
						wallet -= bet;
						System.out.println("      베팅 완료!------------------------");
						System.out.printf(" > 베팅 후 잔액: %,d원", wallet);
					} else if (select == 2) {
						System.out.println(" > 최소 베팅금인 1,000원이 베팅됩니다.");
						bet = 1000;
						wallet -= bet;
						System.out.printf(" > 베팅 후 잔액: %,d원", wallet);
					} else {
						System.out.println(" > 존재하는 메뉴를 선택해주세요.\n");
						i--;
					}
				}

				// 결과
				System.out.println("\n > 결과를 확인하시려면 숫자키를 아무거나 입력해주세요.");
				System.out.print("결과 확인> ");
				select = sc.nextInt();

				System.out.println("=========== GameReault ===========");

				pc = card1[0] + card2[0];
				player = card1[1] + card2[1];
				System.out.println("pc 손패> " + card1[0] + " " + card2[0] + "/ 합: " + (card1[0] + card2[0]));
				System.out.println("player 손패> " + card1[1] + " " + card2[1] + "/ 합: " + (card1[1] + card2[1]));
				// 승패
				if (card1[0] == card2[0] && card1[1] == card2[1]) { // 만약 pc와 player 모두 갖고 있는 손패가 동일한 숫자일 경우
					System.out.println("pc와 player 모두 갖고있는 손패가 동일한 숫자이므로,\n");
					if (pc > player) {
						System.out.println("pc 승리!\nplayer 패!\n" + " > player의 패배로 베팅금을 잃으셨습니다.");
					} else if (pc < player) {
						System.out.println("pc 패!\nplayer 승리!" + " > player의 승리로 베팅금의 반을 획득하셨습니다.");
						System.out.printf("베팅한 금액: %,d원\n획득한 금액: %,d원\n", bet, bet / 2);
						wallet += bet;
						wallet += bet / 2;
					}
				} else if (card1[0] == card2[0] || card1[1] == card2[1]) { // 만약 pc(혹은 player)가 갖고있는 손패가 동일한 숫자일 경우
					if (card1[0] == card2[0]) {
						System.out.println("pc가 갖고있는 손패가 동일한 숫자이므로,\n");
						System.out.println("pc 승리!\nplayer 패!\n" + " > player의 패배로 베팅금을 잃으셨습니다.");
					} else if (card1[1] == card2[1]) {
						System.out.println("player가 갖고있는 손패가 동일한 숫자이므로,\n");
						System.out.println("pc 패!\nplayer 승리!" + " > player의 승리로 베팅금의 반을 획득하셨습니다.");
						System.out.printf("베팅한 금액: %,d원\n획득한 금액: %,d원\n", bet, bet / 2);
						wallet += bet;
						wallet += bet / 2;
					}
				} else { // 만약 양측 모두 갖고있는 손패가 동일한 숫자가 없을 경우
					if (pc > player) {
						System.out.println("pc 승리!\nplayer 패!\n" + " > player의 패배로 베팅금을 잃으셨습니다.");
					} else if (pc < player) {
						System.out.println("pc 패!\nplayer 승리!" + " > player의 승리로 베팅금의 반을 획득하셨습니다.");
						System.out.printf("베팅한 금액: %,d원\n획득한 금액: %,d원\n", bet, bet / 2);
						wallet += bet;
						wallet += bet / 2;
					} else {
						System.out.println("pc와 player의 손패 합이 같으므로 무승부입니다."
								+ " > 베팅하신 금액을 돌려받으셨습니다.");
						System.out.printf("베팅한 금액: %,d원\n", bet);
						wallet += bet;
					}
					System.out.println();
				}

			} else if (menu == 2 && (m == -1 || m == 0)) {
				System.out.println("============= GameRule =============");
				System.out.println("      게임 규칙-----------------------\n"
						+ " > 1부터 10까지의 패가 두 장씩, 총 20장 있습니다.\n"
						+ " > 플레이어와 PC는 각 2장 씩 배정받습니다.\n"
						+ " > 기본적으로는 배정받은 패 두 장의 총합이 큰 쪽이 승리합니다.\n"
						+ " > 특수한 상황으로는 동일한 숫자의 패인 경우,\n"
						+ "\t상대보다 총합이 낮아도 승리할 수 있습니다.\n"
						+ " > 양 쪽 모두 동일한 숫자의 패인 경우,\n"
						+ "\t숫자가 큰 쪽이 승리합니다.\n"
						+ "      베팅-------------------------\n"
						+ " > player는 손패를 확인하고, 베팅을 결정 할 수 있습니다.\n"
						+ " > 베팅 시 이겼을 경우, 베팅한 금액과 그 금액의 반을 얻으실 수 있습니다.\n"
						+ "\t졌을 경우, 베팅금을 잃게 됩니다.\n"
						+ " > 베팅금은 최소 1,000원이며,\n"
						+ "\tplayer의 잔액보다 큰 금액을 걸 수 없습니다.");
				System.out.println();
				m = 1;

			} else if (menu == 3 && m == 0 || (menu == 2 && (m != 0 || m != -1))) {
				System.out.printf("============ Game Money ============"
							+ "\n > 현재 잔액: %,d원\n", wallet);
				for(int i=0; i<1; i++) {
					System.out.print(" > 충전하시겠습니까?\n1.예 2.아니오\n메뉴 선택> ");
					int select = sc.nextInt();
					if(select == 1) {
						System.out.println("      -------------------------");
						System.out.print(" > 충전할 금액을 입력해주세요.\n충전 할 금액> ");
						int inmoney = sc.nextInt();
						System.out.println("\n > 충전이 성공적으로 완료되었습니다.");
						System.out.printf(" > 충전한 금액: %,d원\n",inmoney);
						wallet+=inmoney;
						System.out.printf(" > 충전 후 금액: %,d원\n\n",wallet);
					}else if(select != 2) {
						System.out.println(" > 존재하는 메뉴를 선택해주세요.\n");
						i--;
					}
				}
				m = -1;

			} else if (menu == 0) {
				run = false;
			} else {
				System.out.println(" > 존재하는 메뉴를 선택해주세요.\n");
				m = 0;
			}

		}
		System.out.println(" > 게임이 종료됩니다.");
		System.out.println("====================================");
		
		
	}

}

 


728x90

'프로그래밍 > +a' 카테고리의 다른 글

미니 팀 프로젝트 사전 준비 (파이썬)  (2) 2024.01.01
slPro 2차 일지  (0) 2023.12.28
slPro 1차 일지  (1) 2023.12.27
Java_주말 복습: 문제 다시 풀어보기  (0) 2023.10.01
Java_주말 복습: 문제 다시 풀어보기  (0) 2023.10.01
728x90

 

수업내용 정리 (Java)

 

1. 복습!

 1-1) a 배열에서 짝수의 합과 홀수의 개수 출력

// 문제) a 배열에서 짝수의 합과 홀수의 개수 출력
int[] a = {45,78,54,48,6};

int a1 = 0;
int a2 = 0;

for(int i=0; i<a.length; i++) {
	if(a[i]%2 == 0) {
		a1 += a[i];
	}else {
		a2++;
	}
}
  • for문이 i가 a 배열의 크기보다 작을 동안 돌아간다.
  • a 배열의 i번째 배열이 2로 나눴을 때 나머지가 없는 경우, a1에 i번째 배열의 값을 더한다.
  • 그렇지 않을 경우, a2에 1씩 더한다.

 

 1-2) 반복하면서 숫자를 입력받는데, 짝수만 b 배열에 저장하기. (*홀수만 입력 시 무한반복)

// 문제2) 반복하면서 숫자를 입력받는데 짝수만 b 배열에 저장하기 *홀수만 입력 시 무한반복
int[] b = new int[5];

for(int i=0; i<b.length; i++) {
	System.out.print("숫자 입력> ");
	int num = sc.nextInt();
	if(num%2 == 0) {
		b[i] = num;
	}else {
		i--;
	}
}
  • for문이 i가 b 배열의 크기보다 작을 동안 돌아간다.
  • 숫자 하나를 한 변수에 저장해두고 그 변수가 2로 나눴을 때, 나머지가 0이라면 b 배열의 i번째 인덱스에 저장한다.
  • 그렇지 않다면, i를 1씩 뺀다.

 

 1-3) 인덱스를 한 칸씩 땡기기

// 고난이도 문제) 인덱스를 한 칸씩 땡기기
int[] a = {45,78,54,48,6};
// 내가 한 방법!
int num1 = a[0];
for(int i=0; i<a.length; i++) {
	if(i == a.length-1) {
		a[i] = num1;
	}else {
		a[i] = a[i+1];
	}
}
  • 변수를 하나 만들어 a의 0번째 인덱스 값을 저장해둔다.
  • for문이 i가 a 배열의 크기보다 작은 만큼 돌아간다.
  • for문을 마지막으로 돌릴 때 a 배열의 [i]번 인덱스에 변수에 저장해둔 값을 대입한다.
  • 그렇지 않을 경우, a 배열의 i번째 인덱스에 i+1번째 인덱스 값을 대입한다.
// 선생님이 하신 방법 1
int temp = 0;
for(int i=0; i<a.length; i++) {
	if(i==0) {
		temp = a[i];
	}else{
		a[i-1] = a[i];
		if(i == a.length-1) {
			a[i] = temp;
		}
	}	
}
  • 변수를 하나 만들어둔다.
  • for문이 i가 a 배열의 크기보다 작은 만큼 돌아간다.
  • i가 0일때, 만들어둔 변수에 a의 i번 인덱스 값을 대입한다.
  • 그렇지 않을때, a의 i-1번 인덱스에 i번 인덱스를 저장한다.
    • 만약 i가 a 배열의 크기보다 1 작다면, a의 i번 인덱스에 변수 값을 대입한다.
// 선생님이 하신 방법 2
for(int i=1; i<a.length; i++) {
	int temp = a[i];
	a[i] = a[i-1];
	a[i-1] = temp;
}
  • for문이 i가 a 배열의 크기보다 작은 만큼 돌아간다.
  • 변수 하나를 지정하면서 a의 i번 인덱스 값으로 초기화한다.
  • a의 i번 인덱스에는 a의 i-1번 인덱스 값을 대입한다.
  • a의 i-1번 인덱스에는 변수의 값을 대입한다.

 

 

2. 예제_sign

 2-1) import

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy년MM월dd일 hh:mm:ss");
Scanner sc = new Scanner(System.in);
  • DateTimeFormatter
    날짜를 받아올 수 있다.
  • Scanner
    콘솔창에서 입력받아올 수 있다.

 

 2-2) 변수 선언

String[] name = new String[10];	// 이름
String[] id = new String[10];	// 아이디
String[] pw = new String[10];	// 비밀번호
String[] date = new String[10];	// 회원가입 날짜
int cnt = 0;
int loginIndex = -1;
  • loginIndex: 의미없는 값 -1 / 인덱스 값을 담아야 하는데 인덱스는 0부터 시작하기 때문에

 

 2-3) 기본 틀

while(true) {
	System.out.println("========= 홈페이지 ==========");
	if(loginIndex == -1) {
		System.out.print("1.회원가입 2.로그인 3.회원목록 0.종료\n메뉴선택> ");
	}else {
		System.out.printf("1.정보수정 2.로그아웃 3.내정보(%s님) 0.종료\n메뉴선택> ",name[loginIndex]);
	}
	
	int menu = sc.nextInt();
	
	if(menu == 1) {
		if(loginIndex == -1) { // 회원가입

				}else { //정보수정
                
				}
			}else if(menu == 2) { // 로그인
				if(loginIndex == -1) {

					}
				}else { //로그아웃

				}
			}else if(menu == 3) { // 회원목록
				if(loginIndex == -1) {

					}
				}else { //내정보
				}
			}else if(menu == 0) { // 종료
				break;
			}
			
			System.out.println();
		}
		System.out.println("프로그램 종료");
  • 메뉴는 0부터 3까지 있다.
    • 로그인 시 메뉴가 바뀐다.
  • 0은 종료이기 때문에 break;를 넣어 while문을 나간다.

 

 2-4) 메뉴 선택에서 1을 입력 

  • 로그인 상태가 아닐 때, 회원가입
System.out.println("=====> 회원 가입");
System.out.print("회원가입 할 이름을 입력해주세요.\n이름 입력> ");	
name[cnt] = sc.next();
System.out.print("회원가입 할 아이디를 입력해주세요.\n아이디 입력> ");
id[cnt] = sc.next();
System.out.print("회원가입 할 비밀번호를 입력해주세요.\n비밀번호 입력> ");
pw[cnt] = sc.next();
String now = dtf.format(LocalDateTime.now());
date[cnt] = now;
System.out.println("\n"+name[cnt]+"님 회원가입을 축하드립니다.");
cnt++;
  • 이름, 아이디, 비밀번호를 각각 name, id, pw의 cnt번 인덱스에 넣고, 저장한 시각을 String now를 통해 date의 cnt번 인덱스에 저장한다.
  • 저장이 완료되면 cnt를 1씩 추가한다.

 

  • 로그인 상태일 때, 정보수정
System.out.print("1.아이디 변경 2.비밀번호 변경\n메뉴 선택> ");
int menu2 = sc.nextInt();
if(menu2 == 1) {
	System.out.println("수정할 아이디를 입력해주세요.");
	System.out.print("수정할 아이디> ");
	id[loginIndex] = sc.next();
}else if(menu2 == 2) {
	System.out.println("수정할 비밀번호를 입력해주세요.");
	System.out.print("수정할 비밀번호> ");
	pw[loginIndex] = sc.next();
}
  • 아이디를 변경할건지, 비밀번호를 변경할건지 메뉴를 선택받는다.
    • 1일 경우, id 배열의 loginIndex번 인덱스의 아이디를 입력받은 값으로 대입한다.
    • 2일 경우, id 배열의 loginIndex번 인덱스의 비밀번호를 입력받은 값으로 대입한다.

 

 2-5) 메뉴 선택에서 2을 입력

  • 로그인 상태가 아닐 때, 로그인
System.out.println("=====> 로그인");
System.out.print("아이디 입력> ");
String inId = sc.next();
System.out.print("비밀번호 입력> ");
String inPw = sc.next();
boolean find = false;				// 기억할 것!
for(int i=0; i<cnt; i++) {
	if(inId.equals(id[i]) && inPw.equals(pw[i])) {
		System.out.println("로그인 성공!");
		loginIndex = i;
		find = true;
		break;
	}
}
if(!find) {
	System.out.println("로그인 실패..");
}
  • 아이디와 비밀번호를 각각 inId, inPw에 입력받는다.
  • boolean 타입을 이용해 false를 지정해둔다.
  • for문이 i가 cnt보다 작을 동안에 돌아간다.
    • 만약 inId와 inPw가 id와 pw의 i번 값과 같다면, 로그인 성공! 을 출력한다.
    • loginIndex에 i 값을 대입한다.
    • find는 true를 대입한다.
    • break를 걸어서 for문을 빠져나간다.
  • !find

 

  • 로그인 상태일 때, 로그아웃
System.out.println("로그아웃이 성공적으로 완료됐습니다.");
loginIndex = -1;
  • 로그아웃이 완료됐다는 말을 출력한다.
  • loginIndex에 -1를 대입한다.

 

 2-6) 메뉴 선택에서 3을 입력

  • 로그인 상태가 아닐 때, 회원목록
System.out.println("=====> 회원 목록");
System.out.println("이름\t아이디\t비밀번호\t가입일\n===================================");
for(int i=0; i<cnt; i++) {
	System.out.printf("%s\t%s\t%s\t%s\n",
			name[i], id[i], pw[i], date[i]);
}
  • 이름, 아이디, 비밀번호, 가입일 순으로 출력한다.

 

  • 로그인 상태일 때, 내정보
System.out.println("=====> 회원 정보");
System.out.println("이름\t아이디\t비밀번호\t가입일\n===================================");
System.out.printf("%s\t%s\t%s\t%s\n",
		name[loginIndex], id[loginIndex], pw[loginIndex], date[loginIndex]);
  • name, id, pw, date의 loginIndex번 인덱스 값만 출력한다.

 


 

질문한 내용이나 어려웠던 점 메모

1. 2-5) boolean을 이용한 코드

boolean find = false;
for(int i=0; i<cnt; i++) {
	if(inId.equals(id[i]) && inPw.equals(pw[i])) {
		System.out.println("로그인 성공!");
		loginIndex = i;
		find = true;
		break;
	}
}
if(!find) {
	System.out.println("로그인 실패..");
}
  • !find 다시 물어볼것
  • 내가 했던 방법은 마지막 반복일 때 아이디와 비밀번호가 일치하지 않다면 로그인 실패를 띄우게 하는 방법이었는데, 오늘 다시 해보니 1, 3번째는 되는데 2번째 아이디와 비밀번호로 로그인 시도 시 맞게 했는데도 로그인 실패가 떴다. 내 계산대로라면 되어야 할 텐데 안 되어서 해결은 나중에 하더라도 이 방법을 외우는 것이 나을 것 같다. 이해가 어렵다면 일단 이해하기 전에 외우기!

 


 

전체 피드백

 

 


728x90
728x90

 

수업내용 정리 (Java)

 

1. 복습 +a

 1-1) 변수 선언, 초기화, 대입

int a;
a = 1;
a = 2;

int b = 0;
  • 변수 선언: int a;
    (변수는 생성되지 않음!)
  • 초기화: a = 1;
    처음 변수에 값을 집어넣어서 변수가 생성됨
  • 대입: a = 2;
    변수 안 값을 다른 값으로 대체
  • int ab = 0;
    변수 선언과 초기화를 동시에 하는 것

 

 

2. 반복문_foreach

int[] a = {1,3,5,7,9};
// 인덱스로 확인하는 방법
for(int i=0; i<a.length; i++) {
	System.out.println(a[i]);
}
// foreach
for(int i : a) {
	System.out.println(i);
}
  • 인덱스로 확인하는 방법
    • i번째 배열에 있는 값을 출력
  • foreach
    • 배열을 순서대로 i에 대입
    • i의 타입은 배열의 타입으로 적어야 한다.

 ex)

String[] b = {"홍길동", "이순신", "심청이"};
for(String i : b) {
	System.out.println(i);
}

 

 

3. 예제_grade

 3-1) 변수 선언

Scanner sc = new Scanner(System.in);
		
String[] name = new String[10];	// 학생이름
int[] kor = new int[10];	// 국어점수
int[] eng = new int[10];	// 영어점수
int[] mat = new int[10];	// 수학점수
int[] total = new int[10];	// 총점
double[] avg = new double[10];	// 평균
char[] grade = new char[10];	// 학점
int cnt = 0;			// 학생을 등록할 때마다 1 증가
  • cnt를 지정해야 학생을 몇번 등록했는지 코드에 저장해두고 나중에 에러가 나지 않는다.
  • ex
    • for(int i=0; i<cnt; i++): 등록된 학생 수보다 적은 동안에 돌아가는 for문
    • for(int i=0; i<name.length; i++): name의 크기보다 적은 동안에 돌아가는 for문
      즉, 학생을 몇명 등록했는지와 상관없이 name의 크기만큼 돌아가는 for문
      학생을 name의 크기보다 적게 등록하고 name[i]로 했을 경우, 에러가 난다.

 

 3-2) 기본틀

while(true) {
	System.out.println("==========학사관리시스템==========");
	System.out.println("1.학생등록 2.학생리스트 3.검색 0.종료");
	System.out.print("메뉴선택> ");
	int menu = sc.nextInt();
	
	if(menu == 1) {
		
	}else if(menu == 2) {
		
	}else if(menu == 3) {
				
	}else if(menu == 0) {
		break;
	}else {
		System.out.println("존재하지 않는 메뉴입니다.");
	}
	
	System.out.println();
}
System.out.println("프로그램 종료");
System.out.println("=============================");
  • 메뉴는 0부터 3까지 있다.
  • 0은 종료이기 때문에 break;를 넣어 while문을 나간다.
  • 0~3 이외의 메뉴가 없기 때문에 else로 존재하지 않는 메뉴라는 말을 출력한다.

 

 3-3) 메뉴 선택에서 1을 입력했다면, 1. 학생등록

if(menu == 1) {
		System.out.print("학생이름> ");
		name[cnt] = sc.next();
		System.out.print("국어점수> ");
		kor[cnt] = sc.nextInt();
		System.out.print("영어점수> ");
		eng[cnt] = sc.nextInt();
		System.out.print("수학점수> ");
		mat[cnt] = sc.nextInt();
		total[cnt] = kor[cnt]+eng[cnt]+mat[cnt];
		avg[cnt] = total[cnt] / (double)3; 	// (double)total[0] / 3; 으로도 가능
		char a = ' ';
		if(avg[cnt] >= 90) {
			a = 'A';
		}else if(avg[cnt] >= 80) {
			a = 'B';
		}else if(avg[cnt] >= 70) {
			a = 'C';
		}else if(avg[cnt] >= 80) {
			a = 'D';
		}else if(avg[cnt] < 60) {
			a = 'F';
		}
		grade[cnt] = a;
		System.out.println(name[cnt]+" 학생 등록완료!");
		cnt++;
}
  • name, kor, eng, mat에 정보가 입력되면 total에 kor, eng, mat을 더해 저장하고, avg에 total의 평균을 저장한다.
  • 평균이 90, 80, 70, 60, 60미만인가에 따라 A, B, C, D, F를 a에 저장 후 grade에 대입
  • 학생 등록이 완료되면 cnt 1 추가

 

 3-4) 메뉴 선택에서 2를 입력했다면, 2. 학생 리스트

else if(menu == 2) {
	System.out.println("이름\t국어\t영어\t수학\t총점\t평균\t학점");
	System.out.println("==================================================");
	for(int i=0; i<cnt; i++) {
		System.out.printf("%s\t%d\t%d\t%d\t%d\t%.2f\t%c\n",
				name[i], kor[i], eng[i], mat[i], total[i], avg[i], grade[i]);
}
  • 등록된 학생들의 이름, 국어, 영어, 수학, 총점, 평균, 학점 순으로 출력한다.

 

 3-5) 메뉴 선택에서 3을 입력했다면, 3. 검색    // 질문! ( i == cnt-1 )

else if(menu == 3) {
	System.out.print("검색할 학생 이름> ");
	String searchName = sc.next();
	//				내가 한 방법
	for(int i=0; i<cnt; i++) {
	if(searchName.equals(name[i])) {
		System.out.println("이름\t국어\t영어\t수학\t총점\t평균\t학점");
		System.out.println("==================================================");
		
		System.out.printf("%s\t%d\t%d\t%d\t%d\t%.2f\t%c\n",
				name[i], kor[i], eng[i], mat[i], total[i], avg[i], grade[i]);
		break;
	}else if(i==cnt-1) {
		System.out.println("리스트에 존재하지 않는 학생입니다.");
	}
}
  • 콘솔창에서 학생 이름을 받아오면 for문을 통해 입력받아온 이름과 name 배열 안에 있는 이름을 비교해서(.equals()) 동일할 경우, 정보를 출력한다.
  • name 배열에서 찾을 수 없는 경우, 리스트에 존재하지 않는 학생입니다. 를 출력한다.
// 				다른 방법! (선생님이 하신 방법)
boolean find = false;

for(int i=0; i<cnt; i++) {
	if(searchName.equals(name[i])) {
		System.out.println("이름\t국어\t영어\t수학\t총점\t평균\t학점");
		System.out.println("==================================================");
		
		System.out.printf("%s\t%d\t%d\t%d\t%d\t%.2f\t%c\n",
				name[i], kor[i], eng[i], mat[i], total[i], avg[i], grade[i]);
		find = true;
		break;
	}
}
if(find == false) { // !find
	System.out.println("리스트에 존재하지 않는 학생입니다.");
}

 

  • boolean을 이용해 find를 false로 선언 및 초기화해두고, 입력받아온 이름이 name 배열 안에 있으면 find를 true로 바꾸고 반복을 멈춘다.
  • 입력받아온 이름이 name 배열 안에 없으면 find가 false이므로 두번째 if의 조건을 충족해서 리스트에 존재하지 않는 학생입니다. 를 출력한다.

 

 

4. 예제_account

 4-1) import

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy년MM월dd일 hh:mm:ss");
Scanner sc = new Scanner(System.in);
  • DateTimeFormatter
    날짜를 받아올 수 있다.
  • Scanner
    콘솔창에서 입력받아올 수 있다.

 

 4-2) 변수 선언

String[] name = new String[10];		// 예금주
String[] account = new String[10];	// 계좌번호
int[] balance = new int[10];		// 잔액
String[] joinDate = new String[10];	// 가입날짜
int cnt = 0;

 

 4-3) 기본 틀

while(true) {
	System.out.println("=============은행=============");
	System.out.println("1.계좌생성 2.입금 3.출금 4.계좌목록 0.종료");
	System.out.print("메뉴 선택> ");
	int menu = sc.nextInt();
	
	if(menu == 1) {
		
	}else if(menu == 2) {
		
	}else if(menu == 3) {
		
	}else if(menu == 4) {
		
	}else if(menu == 0) {
		break;
	}
	
	System.out.println();
}
System.out.println("프로그램 종료");
  • 메뉴는 0부터 3까지 있다.
  • 0은 종료이기 때문에 break;를 넣어 while문을 나간다.

 

 4-4) 메뉴 선택에서 1을 입력했다면, 1. 계좌 생성

if(menu == 1) {
	System.out.print("이름을 입력해주세요.\n이름 입력> ");
	name[cnt] = sc.next();
	System.out.print("계좌번호를 입력해주세요.\n계좌번호 입력> ");
	account[cnt] = sc.next();
	System.out.print("초기 잔액을 입력해주세요.\n잔액 입력> ");
	balance[cnt] = sc.nextInt();
	
	String now = dtf.format(LocalDateTime.now());
	
	joinDate[cnt] = now;
	
	System.out.println(name[cnt]+"님 계좌생성 완료되었습니다.");
	cnt++;	
}
  • name, account, balance에 정보가 입력되면 입력한 시간을 String now로 불러오고, now를 joinDate에 저장한다.
  • 계좌 생성이 완료되면 cnt에 1을 추가한다.

 

 4-5) 메뉴 선택에서 2를 입력했다면, 2. 입금

else if(menu == 2) {
	System.out.print("입금할 계좌번호를 입력해주세요.\n입금할 계좌번호> ");
	String inAccount = sc.next();
	for(int i=0; i<cnt; i++) {
		if(inAccount.equals(account[i])) {
			System.out.print("입금할 금액을 입력해주세요.\n입금할 금액> ");
			int inMoney = sc.nextInt();
			System.out.println("성공적으로 입금이 되었습니다.");
			System.out.printf("입금 전 잔액: %,d원\n",balance[i]);
			balance[i] += inMoney;
			System.out.printf("입금 후 잔액: %,d원",balance[i]);
			break;
		}else if(i == cnt-1) {
			System.out.println("존재하지 않는 계좌입니다.");
		}
	}
}
  • 입금할 계좌번호를 입력받아오고 그 값이 account 배열 안에 있을 경우, 입금할 금액을 입력받고, 입금 전, 후의 잔액을 출력하고 break로 for문을 빠져나간다.
  • account 배열 안에 없을 경우, 존재하지 않는 계좌입니다. 를 출력한다.

 

 4-6) 메뉴 선택에서 3을 입력했다면, 3. 출금

else if(menu == 3) {
	System.out.println("출금할 계좌번호를 입력해주세요.\n출금할 계좌번호> ");
	String outAccount = sc.next();
	for(int i=0; i<cnt; i++) {
		if(outAccount.equals(account[i])) {
			System.out.print("출금할 금액을 입력해주세요.\n출금할 금액> ");
			int outMoney = sc.nextInt();
			if(balance[i] < outMoney) {
				System.out.println("잔액이 부족합니다.");
			}else {
				System.out.println("성공적으로 출금이 되었습니다.");
				System.out.printf("출금 전 잔액: %,d원\n",balance[i]);
				balance[i] -= outMoney;
				System.out.printf("출금 후 잔액: %,d원",balance[i]);
			}
		}else if(i == cnt-1) {
			System.out.println("존재하지 않는 계좌입니다.");
		}
	}
}
  • 출금할 계좌번호를 입력받아오고 그 값이 account 배열 안에 있을 경우, 출금할 금액을 입력받고, 계좌 안에 남아있는 잔액보다 적을 경우에는 출금 전, 후의 잔액을 출력하고 break로 for문을 빠져나간다.
  • account 배열 안에 있지만 입력받은 출금 금액이 계좌 잔액보다 클 경우, 잔액이 부족합니다. 를 출력한다.
  • account 배열 안에 없을 경우, 존재하지 않는 계좌입니다. 를 출력한다.

 

 4-7) 메뉴 선택에서 4를 입력했다면, 4. 계좌 목록

else if(menu == 4) {
	System.out.println("예금주\t계좌번호\t잔액\t\t가입날짜");
	System.out.println("============================");
	for(int i=0; i<cnt; i++) {
		System.out.printf("%s\t%s\t%,d원\t%s\n",name[i],account[i],balance[i],joinDate[i]);
	}
}
  • 등록된 계좌들을 예금주, 계좌번호, 잔액, 가입날짜 순으로 출력한다.
  • cnt보다 적을 때 동안 반복하여 출력

 

 


 

질문한 내용이나 어려웠던 점 메모

 

3-5) : 왜 cnt가 아니라 cnt-1을 붙여야 하는지 (관련: 4-5, 4-6)

for(int i=0; i<cnt; i++)
else if(i==cnt-1) {
	System.out.println("리스트에 존재하지 않는 학생입니다.");
}
  • for문에 i가 cnt보다 작은 만큼 돈다고 그랬으니 else if의 조건을 i==cnt라고 해버리면 for문의 조건문에 부합하지 않으므로 for문을 돌지 않는다. 그렇기 때문에 else if는 아예 조건을 성립할 수 없게 된다.
  • else if의 조건을 i==cnt-1이라고 하면, for문의 조건인 i가 cnt보다 작을 동안. 즉, cnt보다 1적을 때까지니까 for문의 마지막 반복일 때 else if를 실행하라는 조건이 된다.
  • 질문한 이유: for문의 미자막 반복이면 실행한다는 조건을 넣어야 해서 i==cnt 라는 조건을 걸었더니 아예 실행되지 않았다. 해결하긴 했으나 왜 이게 되는지 몰랐다.

 

 


 

전체 피드백

  • for문을 아직 완벽하게 이해하지 못한 것 같다. 자꾸 cnt보다 작을 때 동안 반복한다라고 알고는 있는데 cnt와 같은 값이어도 돌 것이라고 생각할 때가 있다. 선생님이 if(int i=0; i<2; i++)이라면 i의 값은 3이 된대서 이 설명을 듣고 종종 헤매는 것 같다. 그러지 않도록 많이 if문을 이용한 문제를 보는 것도 괜찮을 것 같다.
  • 코드 제대로 보기!!!

 


728x90
202230920
728x90

 

수업내용 정리 (Java)

 

1. 복습

// 문제3) while문을 통해 반복적으로 숫자를 입력받다가 0이 입력되면 반복문 종료

int a = 1;

while(a != 0) {
	System.out.print("숫자입력> ");
	a = sc.nextInt();
}
System.out.println("종료");
  • int에 의미없는 값을 넣을 때는 보통 0 또는 -1을 넣는다.

 

 

2. 배열_예제

 2-1)

int[] a = {4,6,23,43,65}

 

// 문제2) a 배열의 짝수의 합 출력
int sum = 0;

for(int i=0; i<a.length; i++){
	if(a[i]%2 == 0){
    	sum += a[i];
    }
}
System.out.println("짝수의 합: "+sum)
  • for문 조건: i가 a의 크기보다 작은 동안 i가 1씩 더해지면서 반복한다.
  • 만약 a의 i번째 인덱스 값을 2로 나눴을 때, 나머지가 0이면 sum에 a의 i번 인덱스 값을 더한다.

 

// 문제3) a배열의 홀수의 개수 출력
int sum = 0;

for(int i=0; i<a.length; i++) {
	if(a[i]%2 != 0) {
    	sum++;
    }
}
  • for문 조건: i가 a의 크기보다 작은 동안 i가 1씩 더해지면서 반복한다.
  • 만약 a의 i번째 인덱스 값을 2로 나눴을 때, 나머지가 0이 아니면 sum에 1씩 더한다.

 

// 문제4) a 배열의 인덱스가 짝수인 값의 합 출력
int sum = 0;

for(int i=0; i<a.length; i++) {
	if(i%2 == 0) {
    	sum += a[i];
    }
}
  • for문 조건: i가 a의 크기보다 작은 동안 i가 1씩 더해지면서 반복한다.
  • 만약 i가 2로 나눴을 때, 나머지가 0이라면 a 배열의 i번 인덱스 값을 sum에 더한다.

 

 

 2-2) 반복하면서 a 배열에 값을 입력하는데, 입력한 값이 인덱스가 한 칸씩 밀려서 들어가고 마지막으로 입력한 값은 0번째 인덱스에 넣기

int[] a = new int[10];

for(int i=0; i<a.length; i++) {
	System.out.print("숫자입력> ");
    if(i == a.length-1) {
    	a[0] = sc. nextInt();
    }else {
    	a[i+1] = sc.nextInt();
    }
}
  • for문 조건: i가 a의 크기보다 작은 동안 i가 1씩 더해지면서 반복한다.
  • 만약 i가 a.length보다 1 작을 때라면, a 배열의 0번 인덱스에 입력받은 값을 넣는다.
  • 그렇지 않다면, i+1번 인덱스에 입력받은 값을 넣는다.
// 다른 분이 짠 코드
for(int i=1; i<=a.length; i++) {
	if(i==a.length) {
		i=0;
		System.out.print("숫자입력> ");
		a[i] = sc.nextInt();
		break;
	}
	System.out.print("숫자입력> ");
	a[i] = sc.nextInt();
}
  • for문 조건: i가 1부터 시작하고, i가 a의 크기보다 작거나 같은 동안 i가 1씩 더해지면서 반복한다.
  • 만약 i가 a의 크기와 같다면, i에 0을 대입하고, 입력받아온 값을 a[i]에 넣고, for문을 나간다.
  • 입력받아온 값을 a의 i번 인덱스에 넣는다.
  • for문으로 계속 반복하다가 if문에 걸릴 때, if문을 실행하고 break로 for문을 나가므로 0번 인덱스의 값이 변경된다.

 

 

 2-3) 입력을 반복해서 받는데, 짝수만 a 배열에 저장

int[] a = new int[10];
		
for(int i=0; i<a.length; i++) {
	while(true) {
		System.out.print("숫자입력> ");
		int answer = sc.nextInt();
		if(answer%2 == 0) {
			a[i] = answer;
			break;
		}
	}
}
  • while문을 통해 answer라는 변수를 만들어 숫자를 입력받고, 그 값이 2로 나눴을 때 나머지가 0인 경우에만 a 배열에 차례대로 저장하고 while문을 나간다.
// 다른 분이 짠 코드 1
for(int i=0; i<a.length; i++) {
	System.out.print("숫자입력> ");
	a[i] = sc.nextInt();
	if (a[i]%2 != 0) {
		i--;
	}
}
  • 입력받은 값을 a 배열에 바로 저장하지만, i번 인덱스의 값이 2로 나눴을 경우 나머지가 0이 아닌 경우에 i를 1 빼고 다시 for문으로 돌아가 동일한 i번 인덱스에 값을 재설정하게 된다.
// 다른 분이 짠 코드 2
for(int i=0; i<a.length; i++) {
	System.out.print("숫자입력> ");
	int num = sc.nextInt();
	if(num%2 == 0) {
		a[i] = num;
	}else {
		i--;
	}
}
  • num이라는 새로운 변수를 지정해서 입력받아올 값을 여기에 저장한다.
  • 이때 만약 num을 2로 나눴을 때 나머지가 0이라면, i번 인덱스에 num 값을 저장한다.
  • 그렇지 않다면, i를 1 뺀다.
  • else에서 i를 빼면서 다시 num에 값을 저장하고 그 값이 2로 나눴을 때 나머지가 0일 때까지 반복한다.

 

 

 2-4) a 배열의 0번째 인덱스에 모든 값 누적

int[] a = {4,6,23,43,6};

for(int i=1; i<a.length; i++) {
	a[0] += a[i];
}
  • 0번 인덱스는 이미 담겨있으므로, i를 1부터 시작하게 해서 1번 인덱스부터 마지막 인덱스까지 누적해서 합한다.

 


 

질문한 내용이나 어려웠던 점 메모

 

1. a.length: 두 for문이 동일하게 10번 돌아가는 이유

// 1)
int[] a = new int[10];

for(int i=0; i<a.length; i++) {
	System.out.println(i);
}
// 2)
for(int i=0; i<=9; i++) {
	System.out.println(i);
}
  • - 1) 인덱스 번호는 0부터 9까지지만 크기가 10이기 때문에 10번 돌아간다.
    - 2) i가 0부터 9가 될 때까지 10번 돌아간다.
  • 질문한 이유: 인덱스는 9까지인데 왜 a.length를 사용할 때 작거나 같을때(<=)가 아닌 작을 때(<) 동안 반복한다고 해야 10번이 돌아가는지 이해가 안 갔다.

 


 

전체 피드백

  • 사실 1.복습에서 이전에 배웠던 코드로 쓰려고 했는데 적어둔 코드를 안 보고 하려다보니 boolean이 기억이 안 나서 꼼수를 부리다가 나온건데 칭찬을 받아서 얼떨떨했다..
  • 이게 될 리가 있나? 하는 코드를 써봤는데 제대로 굴러가서 원하는 대로 출력이 됐다. 처음부터 안 된다고 단정짓지 말고 안 된다고 생각이 되어도, 꼼수라고 생각되더라도 해보는 것이 좋을 것 같다!
  • 그냥 코드로 이걸 만들어보세요 하면 고민하면서 조금 만들어보겠는데 쉬는 겸 선생님이 코드를 보여주시면 구조를 생각해서 답을 생각해내는 퀴즈에선 답을 잘 못맞추겠다..계속 틀려서 답을 안 내면 그게 정답이어서 너무 슬펐다.
    답을 못맞추는 데에는 코드에 대한 이해도도 있지만, 코드를 잘못 보는 것도 있어서 코드를 제대로 보도록 노력해야겠다.

 

 안 될 것 같아도 일단 해보기!
 코드 제대로 보기!

 


728x90
1 ··· 8 9 10 11 12 13 14 ··· 27