728x90
반응형
야구 게임이란 랜덤 한 숫자를 맞추는 간단한 게임이다.
숫자를 맞출때 자리와 숫자가 동시에 맞으면 스트라이크, 자리는 다르지만 숫자를 맞출 때에는 볼로 취급한다.
먼저 게임의 로직은 다음과 같다.
- 게임 시작과 함께 컴퓨터는 랜덤 한 3자리 숫자를 생성한다.
- 플레이어는 랜덤한 숫자를 맞춘다. 이때 사용자가 숫자를 입력하면 스트라이크와 볼, 입력 횟수가 출력된다.
- 가장 짧은 턴 안에 숫자를 맞춘다.
해당 로직은 가장 간단하게 게임을 즐길 수 있는 로직이며, 코드를 조금 더 개선하여 다음 기능을 추가한다.
- 게임 시작/ 재시작 버튼 추가
- AI와의 대결 (이때 컴퓨터는 랜덤 한 숫자를 생성하여 숫자를 맞추게 되며 틀릴 경우 해당 숫자를 배제하여 게임에 참여한다.)
- (2)에서의 알고리즘 구체화
해당 게임은 자바스크립트를 이용해 제작한다.
필자가 직접 코딩한다.
랜덤값 구현하기
먼저 랜덤 한 숫자를 생성해야 한다. 랜덤 값 생성에 대해서는 다음 포스팅을 참조한다.
코드를 본다면 먼저 3개의 배열을 선언 후 첫 번째 요소의 값을 랜덤으로 선정한다.
이후 두 번째와 세 번째는 각각 앞에 있는 숫자와의 중복을 피하기 위해 dif_one()과 dif_two()함수를 이용해 중복을 없앤다.
랜덤 값을 저장할 배열에 중복되지 않는 숫자가 저장된다면 출력에 용이하도록 random_number 변수에 저장한다.
해당 값의 100의 자리가 0인 경우 두 자리로 출력되므로 알고리즘 확인용으로 사용하도록 하자.
<script>
function dif_one(N1,N2){
while(N1 == N2){ //첫번째 난수와 두번째 난수가 다른 숫자일 때까지 반복
N2 = Math.floor(Math.random() * 10);
}
return N2;
}
function dif_two(N1,N2,N3){
while(N3 == N1 || N3 == N2){ //첫번째 난수와 두번째 난수가 다른 숫자일 때까지 반복
N3 = Math.floor(Math.random() * 10);
}
return N3;
}
/*사용자 입력값*/
var ipt_arr = [[0],[0],[0]];
var ipt,rep=0;
/* 랜덤값 */
var random_num = [[0],[0],[0]];
random_num[0] = Math.floor(Math.random() * 10);
random_num[1] = dif_one(random_num[0],random_num[1]);
random_num[2] = dif_two(random_num[0],random_num[1],random_num[2]);
var random_number = num1*100 + num2*10 + num3;
</script>
사용자의 입력값 구현
먼저 스트라이크와 볼 값을 저장할 변수를 선언하고 초기화한다.
사용자의 입력을 저장할 배열을 선언한다. 이때 랜덤 값과 사용자 값에서 배열을 이용한 이유는 배열이 반복을 이용한 비교가 용이하기 때문이다.
<script>
var strike_cnt = 0, ball_cnt = 0;
/*사용자 입력값 선언: 초기 선언*/
var ipt_arr = [[0],[0],[0]],ipt,rep=0;
var ipt = parseInt(prompt("첫 번째 값을 입력하세요. "));
//사용자가 입력한 값 분할
ipt_arr[0] = parseInt(ipt / 100); //123/100 ==> 1
ipt_arr[1] = parseInt(ipt/10%10); //123/10 ==> 12 %10 ==>2
ipt_arr[2] = parseInt(ipt%10)
</script>
게임 포인트 계산하기
랜덤값과 사용자의 입력값이 저장됐다면 이제 비교를 통해 게임 포인트를 계산한다.
이때 스트라이크는 인덱스가 같은 경우 요소의 값이 같다면 증가, 볼인 경우는 인덱스가 다를 때 요소의 값이 같다면 증가한다.
아래 코드는 반복없이 한번 출력 후 종료된다.
<script>
while(1){
strike_cnt = 0; ball_cnt=0;
for(let i=0;i<3;i++) if(ipt_arr[i]==random_num[i]) strike_cnt ++;
for(let i=0;i<3;i++){
for(let j=0;j<3;j++){
if(i!=j) if(ipt_arr[i]==random_num[i]) ball_cnt ++;
}
}
print(random_num[0],random_num[1],random_num[2],ipt_arr[0],ipt_arr[1],ipt_arr[2],strike_cnt,ball_cnt);
break;
}
</script>
다음 포스팅에서 다룰 내용은 아래와 같다.
- 맞출 때까지 반복 => 두 수가 같으면 break 문으로 종료.
- 현재 반복한 횟수 출력
- 시작/ 재시작 버튼 삽입
- 외부 파일 분리로 최적화
현재까지의 코드는 다음과 같다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>야구 게임</title>
<style>
body {
text-align: center;
font-size: 30px;
}
</style>
</head>
<body>
<h1>야구 게임</h1>
<script>
function dif_one(N1,N2){
N2 = Math.floor(Math.random() * 10);
while(1){ //첫번째 난수와 두번째 난수가 다른 숫자일 때까지 반복
if(N1 != N2) break;
else N2 = Math.floor(Math.random() * 10);
}
return N2;
}
function dif_two(N1,N2,N3){
N3 = Math.floor(Math.random() * 10);
while(N3 == N1 || N3 == N2){ //첫번째 난수와 두번째 난수가 다른 숫자일 때까지 반복
N3 = Math.floor(Math.random() * 10);
}
return N3;
}
function print(R1,R2,R3,I1,I2,I3,sc,bc){
document.write("<br><br>랜덤 숫자: "+R1+R2+R3+"<br>");
document.write("입력한 숫자:"+I1+I2+I3+"<br><br>");
document.write("Strike!: "+strike_cnt + "<br>");
document.write("ball: :" + ball_cnt);
}
/* 랜덤값 */
var random_num = [[0],[0],[0]];
random_num[0] = Math.floor(Math.random() * 10);
random_num[1] = dif_one(random_num[0],random_num[1]);
random_num[2] = dif_two(random_num[0],random_num[1],random_num[2]);
//랜덤 값은 생성시 계속 유지
var strike_cnt = 0, ball_cnt = 0;
/*사용자 입력값 선언: 초기 선언*/
var ipt_arr = [[0],[0],[0]],ipt,rep=0;
var ipt = parseInt(prompt("첫 번째 값을 입력하세요. "));
//사용자가 입력한 값 분할
ipt_arr[0] = parseInt(ipt / 100); //123/100 ==> 1
ipt_arr[1] = parseInt(ipt/10%10); //123/10 ==> 12 %10 ==>2
ipt_arr[2] = parseInt(ipt%10)
while(1){
strike_cnt = 0; ball_cnt=0;
for(let i=0;i<3;i++) if(ipt_arr[i]==random_num[i]) strike_cnt ++;
for(let i=0;i<3;i++){
for(let j=0;j<3;j++){
if(i!=j) if(ipt_arr[i]==random_num[i]) ball_cnt ++;
}
}
print(random_num[0],random_num[1],random_num[2],ipt_arr[0],ipt_arr[1],ipt_arr[2],strike_cnt,ball_cnt);
break;
}
</script>
</body>
</html>
실행 결과
728x90
반응형