22. 04. 14 - 가위,바위,보 게임(조건문), Scanner, Array
강사님 Quiz - 가위바위보 게임 만들기 시작!
- 컴퓨터가 랜덤하게 가위바위보 내면 - 내가 낸 것과 비교
- 컴퓨터가 무엇을 냈는지 내가 무엇을 냈는지 출력해준다.
- 지면 다시 시도 - 이기면 종료하도록 해준다.
- 몇 번만에 승리했는지 알려주도록 해준다.
- --
- +@ 매 판마다 다시 할지 종료할지 물어보기 기능 추가
- +@ 게임을 진행하는 동안 몇 번 이겼는지 승리 횟수 체크하는 것으로 변경
풀이 시작
: 가위, 바위, 보를 숫자 1, 2, 3으로 치환해서 풀어볼 것이다.
1. 컴퓨터 패 선택 ( 랜덤 )
- int com = (int)( Math.random()*3 )+1;
- 랜덤 숫자 1~3 생성
2. 기능이 잘 동작하는지 중간중간 테스트하는 습관 필요
- System.out.println( com ) 해보잣
- 1,2,3 사이의 랜덤 숫자 잘 나오는지 확인
3. 사용자의 값 입력받기
- Scanner
4. 결과 출력
- 총 9가지의 경우 발생
- 컴퓨터 가위(바위,보) 냈을 때 3가지(3가지,3가지) 경우
코드 변경
5. 무엇을 냈는지 알려주는 출력문 추가
중복이 많다. – 중복을 제거할 방법 찾아보자
( 컴퓨터 : 가위 ) 이 부분은 바깥쪽 첫 번째 if ( com == 1 ) 통과하면 출력되는 것이다.
3개 부분에서 빼고 위로 올려준다. ( 3개의 출력문을 1개로 줄였다. )
6. 사용자가 승리하면 종료하도록 코드 수정해보자
- 스위치(딸깍딸깍) 역할을 하는 변수
- 스위치가 켜져 있으면 게임이 끝내지 않고, 스위치가 꺼져있으면 게임이 끝나도록
> win이라는 변수 추가
- while – 무한반복이 아닌 win == 0으로 시작
- 사용자가 이기면 win을 1로 바꿀 것이다.
- 그럼 win이 1로 바뀌는 순간 while문 반복 안된다.
- while 문 내부에 break 대신에 win = 1; 로 변경
> 우리가 만든 win 은 켜지거나 꺼지거나 둘 중 하나이다.
- 평소에 가만히 있다가 사용자가 승리하면 켜지는 스위치이다.
- 즉, 스위치 역할을 하는 변수의 값은 0 / 1 두 가지중 하나이다.
- 그래서 보통 이 역할을 하는 변수를 선언할 경우에는
- int 가 아닌 boolean 타입으로 만들어 준다.
> 변수명의 약속!
- boolean 타입 변수 만들경우에는 is를 앞에 붙여준다.
- 무엇인지 명확하게 표현하는 것이 좋다.
내가 true 로 바꿔줌..
강사님은 while ( ! isUserWin ) 으로 이것이 아닐 때로 not 연산자 사용해서 수정함
- 변수의 의미와 같게 , 사용하는 의미와 맞게 조건을 만들어 준 것
- 유저가 이긴 게 참이면 반복 - 그만하도록 하는 반복문이다.
- 유저가 진 것이 참이면 반복하는 반복문
7. 사용자가 승리했을 경우 – 몇 번만에 승리했는지 알려주는 코드 추가
- count 체크 위치 : 유저한테 입력받을 때마다 cnt 증가
- print는 while 문 끝나서 나서
- 바깥쪽에서 승리했을 때 cnt 프린트~ 출력!
- 승리했을 때 cnt 프린트~
8. 게임 한판 한판 할 때마다 더할지 그만할지 선택하도록 해주기
+@ 사용자에게 입력받기 전에 출력문 추가
System.out.println("가위:1, 바위:2, 보자기:3 을 입력하세요");
게임이 다시 할지 말지는 반복문이 다시 돌지 말지를 정하는 것이다.
isUserWin 말고 다른 스위치를 사용해보자
beoolean isGameOver = false;
게임 오버가 아닐 때만 게임 종료 프로그램
- isUserWin = true 했던 거 삭제
- 게임 더 할지 말지 추가
9. 승리 횟수를 알려주도록 cnt 위치 수정
- userWinCnt++ 코드의 위치를
- "사용자 승리"한 경우 각각 3군데에 추가!
스캐너 사용법
스캐너 도구 생성
- Scanner sc = new Scanner(System.in);
스캐너 사용
- 정수 입력받기 : int i = sc. nextInt( );
- 실수 입력받기 : float f = sc . nextFloat( );
- 문자 입력받기 : char c = sc . nextChar( );
- 특정 타입의 데이터를 입력받으려면, nextXXX( ) 해주면 된다~
문자열은 – sc . next( ) / sc . nextLine ( )
- 스캐너를 사용하는 경우 nextLine( )을 더 많이 사용된다.
sc . next( ) / sc . nextLine ( ) 차이점은
- 엔터키를 가져오느냐 안 가져오느냐 차이
- 띄어쓰기 포함하냐 안 하냐 차이
- next( ) 는 띄어쓰기 있으면 거기까지만
- nextLint( ) 은 상관없이 한 줄 다
nextInt( ) 와 nextLine( ) 같이 사용할 때 문제 발생 가능
- nextInt( ) 친구는 스캐너로 1입력시 1만 가져가고 엔터를 안 가져간다. -
- nestLine( ) 친구는 한 줄을 그대로 가져간다 – 엔터키 까지 – 띄어쓰기까지 포함해도
next( )는 공백이나 엔터키 라인으로 구분해서 가져간다.
숫자랑 문자 입력받는 경우 문제 생길 수 있다.
- nextInt( )가 숫자만 가져가고 엔터키 안 가져 간 상황에서
- nextLine( ) 해주면 원래 데이터 못 가져오고 위에 애가 남기고 간 엔터키만 가지고 오는 상황 걸린다.
1 입력하고 문자열 입력하려고 하는데
1 입력하니까 프로그램 끝났다..
이유는?
- nextInt()가 남기고 간 엔터키 가져오고 끝났다.
- 지금은 nextInt( )를 많이 사용하는데 뒤로 갈수록 한 줄 가져오고 거기서 처리해주는 방식으로 많이 사용
버퍼 들어봤어요?
1 하고 엔터키 치면 컴퓨터 안에 버퍼라는 공간(바구니같은)에 들어가 있는 것이라고 보면 된다.
scanner라는 애를 사용하면 이 버퍼라는 공간에서 가져오는 것인데
nextInt()로 가져오면 1만
nextLine() 가져오면 엔터키까지 쭉
배열 시작
int 배열 선언
- int[ ] a; <- 자바느낌 다른 방식도 int a[]; <- c느낌
- 배열을 선언하면 참조형 변수가 생성된다.(기본형 변수X)
- 데이터 값이 들어있는 것이 아니라 주소 값이 들어있는 것이 참조형 변수
배열 생성 및 할당
- int [ ] a = new int[ 4 ]
- new 키워드를 사용하면 동적 메모리 생성 - Heap 메모리에 생성
- 몇 칸짜리 만들지 반드시 지정 필요
배열 초기화 ( = 선언과 동시에 값을 할당 )
- 배열 공간 할당과 동시에 초기값을 기록하는 것이 초기화
- int [ ] a = new int[] { 1,2,3 };
- int [ 3 ] 대신 int[ ] { 1, 2, 3 } 해주면 – 3칸의 공간 만들어주는 동시에 값이 들어간다.
int [] a = { 1, 2, 3 };
int [] a = new int[] { 1, 2, 3 };
2 가지 방법 다 가능 편한 것으로 사용
회사 가면 작성 규칙 정해진대로 사용.
new 키워드 없어도
배열은 무조건 힙 메모리에 생성! - size 때문에 그런다
배열의 인덱스
- 한 칸 한 칸을 요소라고 부른다.
- 0번째 인덱스 , 1번째 인덱스, 2번째 인덱스
- 배열의 길이는 3 – length
- 인덱스는 0부터 2까지 가지고 있다~
배열 길이 체크
- 배열 . length( );
- a . length( );
배열에 접근하기
- 배열 변수 [ 인덱스 ]
- a [ 0 ] ;
- 해당 배열에 특정 인덱스에 접근 가능
- 특정 요소에 접근 가능하다.
왜 0으로 출력?
- 아직 값을 넣어주지 않았다. 생성만 한 상태
- int 형 타입은 jvm 이 기본적으로 0의 값을 넣어준다.
- String 타입은 기본 값 null
접근해서 출력할 수 있다는 것은 – 그곳에 값을 넣어줄 수 있다는 것
- 주소 값에 접근하는 방법 – 그 주소 값을 알고 있는 친구를 통해서 접근
- a라는 변수를 통해서 주소 값을 알 수 있고, a를 통해서 주소 값으로 이동 가능
- 이 주소에 0번째 접근 -> a[ 0 ]
- 없는 공간 a[6] 에 접근하려고 하면 에러 나온다 - exception
- out of bound
배열에 값 입력
출력은 반복문으로 해보자 ~!
+@ 지역변수
- 우리나라안에서 똑같은 이름 사용 불가하다
- 나른 나라에서는 사용 가능하다 - 예시로 설명
- 태어난 곳에서만 { } 살아갈 수 있다.
- 나가면 살지 못한다!
- 네모칸에 있는 int i는 태어난 곳이 main{ } 이다 없어지기 전까지 같은 이름 사용 불가
- for{ int i} for{ int i } 이렇게는 사용 가능하다
배열 문제 시작
Code up : 1403번 : 배열 두 번 출력하기 해결
k개의 숫자를 입력받고 그 숫자들을 두 번 출력하시오.
입력
예) 2 5 7
출력 예)
5
7
5
7
정수 n 받기
- int n = sc.nextInt();
n번 숫자 입력받기 –
- n개만큼 담을 공간 확보 필요
- int [ ] a = new int [ n ]
- 만들어둔 공간에 입력받기
- a[ i ] = sc . nextInt( )
2번 출력하기
- 출력 for 문 2번 써주기
Code up : 1095번 : [기초-1차원배열] 이상한 출석 번호 부르기 3(설명)
정보
선생님은 오늘도 이상한 출석을 부른다.
영일이는 오늘도 다른 생각을 해보았다.
출석 번호를 다 부르지는 않은 것 같은데... 가장 빠른 번호가 뭐였지?
출석 번호를 n번 무작위로 불렀을 때, 가장 빠른 번호를 출력해 보자.
참고
배열에 순서대로 기록해 두면, 기록된 내용을 모두 검사해 가장 작은 값을 찾아내면 된다.
그런데, 가장 작은 값은 어떻게 어떤 것과 비교하고 찾아야 할까?
입력번호를 부른 횟수( n, 1 ~ 10000 )가 첫 줄에 입력된다.
n개의 랜덤 번호(k, 1 ~ 23)가 두 번째 줄에 공백을 사이에 두고 순서대로 입력된다.
출력 출석을 부른 번호 중에 가장 빠른 번호를 1개만 출력한다.
입력 예시
10 10 4 2 3 6 6 7 9 8 5
출력 예시
2
선생님 풀이 방법
- 우리 반이 1번에서 23번까지 있다.
- 메모장을 한 칸 한 칸 쪼갤 것이다.
- 출석 부른 애 체크할 것이다.
- 5번 부르면 5번에 체크
- 3번 부르면 3에다 체크, 3을 또 부르면 체크되어있으니까 변화 X
- 선생님이 출석 다 부르고 나면 1번부터 쭉 보면서 가장 먼저 체크된 애를 찾으면 된다.
review
이번 강의에서 새로웠던 부분
while 문은 참일 때 도는 것이니까 조건이 참이라고 변경해줬는데
내가 설정한 변수명과 조건에 맞게 더 신경 써야겠다고 느꼈다.
유저가 이기는 상황에 반복문을 종료하도록 만들었는데
변수명과 조건을 isUserWin = true;라고 해놓고 반복문을 돌렸다.
빠져나오려면 isUserWin = false; 일 때 빠져나오는 것인데
해석해보면 유저가 이긴 것이 거짓이면 빠져나오는 것이 되는 것이다.
해석의 오류 발생 가능성이 있다고 생각했다.
변수명과 반복문 조건의 중요성에 대해 다시 한번 생각을 하게 되었다.
스캐너 부분에서 nextInt( ) 와 nextLine( ) 을 같이 사용할 때
원하는 결과가 나오지 않거나 에러가 나오는 이유에 대해서도
알 수 있어서 좋았다.
배열 문제 1095번 강사님과 내가 풀이한 것과 차이가 있었다.
다른 수강생들이 풀이한 것도 몇 가지 공유했는데
다들 풀이하는 방법과 문제를 해석하는 것이 다른 점이
신기하기도 하고 풀이에 답은 없구나라고 느꼈다
상황에 맞춰 효율적인 것을 찾는 것이 답이다!