컴퓨터와 가위바위보 게임

Ji Hyeok Im·2023년 3월 2일
0

Javascript

목록 보기
6/17

자바스크립트를 이용해 사용자가 가위, 바위, 보 셋 중 하나를 입력하고 버튼을 클릭하면

내가 낸 카드와 컴퓨터가 무작위로 낸 카드를 비교해서 결과문을 출력하는 다음과 같은 웹 페이지를 만드려고 한다.

가위바위보 로직 만들기

나는 가위, 바위, 보 셋 중 하나를 input창에 입력한다.

컴퓨터는 가위, 바위, 보 셋 중 하나를 무작위로 생성한다.

이 때 나와 컴퓨터가 각각 셋 중 하나를 (이하 카드로 칭한다) 냈을 때의 결과를 총 경우의 수로 따지면 3 * 3의 9가지이다.

이 9가지 결과의 경우의 수를 3 * 3 표로 만들면 다음과 같다.

표의 각 셀은 내가 낸 카드와 컴퓨터가 낸 카드, 그에 따른 승, 무, 패의 결과 정보를 가지고 있다.

바위에 0, 가위에 1, 보에 2라는 정수값을 주고 9가지 결과에 각각 'a' 부터 'i' 라는 값을 주면

나와 컴퓨터의 가위바위보는 다음과 같이 중첩배열인 rspArr[x][y] 의 형식으로 나타낼 수 있다.

var rspArr = [ ['a','b','c'],['d','e','f'],['g','h','i'] ];

rspArr[x][y] 에서 x는 내가 낸 카드의 정수값이면서 배열의 인덱스가 되고,

y는 컴퓨터가 낸 카드의 정수값이면서 중첩된 배열의 인덱스가 되며,

rspArr[x][y]의 값이 되는 배열 요소 'a' ~ 'i' 는 가위바위보의 결과를 의미한다.

예컨대 rspArr[0][0] == 'a' 이므로 내가 낸 카드가 바위(0), 컴퓨터가 낸 카드가 바위(0)일떄 결과는 'a'(무승부)가 된다.

9가지 결과를 표로 확인해 보면 다음과 같다.

이제 나의 input과 컴퓨터가 랜덤으로 생성한 값을 배열 인덱스에 대입해 배열 rspArr[x][y] 의 값에 따라 게임 결과를 다르게 출력하도록 코드를 구현하면 되겠다.

코드 구현하기

먼저 문자열을 입력할 input 요소와 onclick 속성으로 가위바위보 게임을 수행할 함수의 실행문을 가진 button 요소를 만들고 그 아래에 게임 결과를 출력할 공간을 div 요소로 만들어 둔다.

그리고 script 태그 내에 전역변수로 사용할 변수들을 선언한다.

일단 내가 입력한 카드의 값을 담을 변수 myNum을 함수 생성 전에 미리 선언하고 값이 함수 내부로 전달되기 전이므로 null로 초기화해둔다.

배열변수 rspArr도 함수 실행시 값을 불러올 수 있게 미리 선언한다.

다음으로 가위바위보 게임을 수행할 함수 rspGame()를 생성하고 실행블록 안에 실행문들을 작성한다.

먼저 rspGame() 함수 실행 시점(버튼 클릭 시)에 값이 생기면서 게임 결과 확인 전에 불러와야 하는 변수를 지역변수로 선언한다.

변수 comNum는 자바스크립트가 제공하는 랜덤 함수를 통해 0, 1, 2의 정수값을 반환받는 변수로,

버튼을 클릭할 때마다 컴퓨터가 내는 카드가 달라지려면 rspGame() 함수가 실행될 때마다 값을 새로 읽어오도록 해야 하기 때문에

함수 내부에 지역변수로 선언한다.

또한 input 요소에 입력한 문자열의 value 속성을 담을 변수 rspInput과

결과를 출력할 div 요소의 innerHTML 속성을 담을 변수인 rspResult도 선언해둔다.

변수 rspInput이 선언되었으므로 내가 입력한 문자열 "가위", "바위", "보"의 값을 여기에 담을 수 있다.

그러나 문자열을 그대로 담으면 배열의 인덱스가 될 수 없으므로

문자열을 0, 1, 2로 변환하는 기능을 수행하는 if - else if 문을 작성한다.

이 시점에서 나와 컴퓨터가 낼 카드는 모두 0, 1, 2 중 하나의 정수값을 가지고,

결과를 확인하는 과정은 이 정수값들을 배열 rspArr의 인덱스로 대입해 이루어진다.

그러나 결과문에서는 나와 컴퓨터가 낸 카드가 무엇인지 확인해야 하며,

임의로 준 숫자 0 이 표시되는 것보다는 "바위"라는 문자열로 확인하는 것이 직관적이다.

즉, 결과문의 시점에서는 정수값이 다시 "가위", "바위" 또는 "보"라는 문자열로 바뀌어 있어야 한다.

위의 문제를 해결하기 위해 결과 확인이 끝난 후 실행되어 정수값을 다시 문자열로 변환하는 기능을 수행할 함수 numToStr()를 생성한다.

매개변수 x를 가지는 함수 numToStr()은 if - else if 문을 통해 변수 x를 문자열로 변환하고 그 값을 반환하도록 작성한다.

그 후 함수 numToStr() 에 인수로 변수 myNum, comNum을 각각 전달해 결과 출력시에 사용할 수 있도록

변수 myStr, comStr를 선언한다.

(생각해보니 최초에 input에 입력한 rspInput이 문자열이기 때문에 변수 myStr은 선언할 필요가 없었다.)

그 아래 최종적으로 if - else if 문을 통해 결과를 확인한다. 조건문을 || (또는)으로 연결해서

rspArr[myNum][comNum] 의 값을 승,무,패가 같은 결과끼리 묶는다.

마지막 else if 문은 조건식을 빼고 else 문으로 적어도 결과는 같다.

실행문에서는 변수 rspResult의 innerHTML 속성에 대입될 결과문을 작성한다.

여기서 문자열로 변환된 변수 comStr을 불러옴으로써 컴퓨터가 낸 카드가 무엇인지 알 수 있게 되고, 게임 결과를 확인하게 된다.

에러 수정하기

input창에 바위, 가위, 보가 아닌 text를 입력하는 경우 함수 내부에서 변수 rspInput에 대한 if - else if 조건문을 만족하지 못해

변수 myNum에 정수값을 대입할 수 없어서 undefined 에러가 발생한다.

이를 방지하기 위해 입력받은 문자열을 정수값으로 변환하는 if - else if 조건문의 마지막에 else 문을 추가해 안내 메시지를 출력하도록 한다.

그러나 메시지 출력으로 함수 실행이 중단되는 것은 아니므로

마지막 조건문이 실행되면서 myNum의 값을 불러오지 못해서 여전히 에러가 발생한다.

마지막 조건문 위에 if 문 하나를 덧씌워 입력문이 바위, 가위, 보 셋 중 하나일 때만 조건을 평가하도록 수정한다.

실행 화면



추가 - 덧셈 로직

나와 컴퓨터의 가위, 바위, 보에 같은 값을 주는 것이 아니라 다른 값을 주면,

배열을 이용하지 않고 보다 간단하게 조건문을 구성할 수 있다.

나의 가위, 바위, 보에 정수값 1, 2, 3을, 컴퓨터의 가위, 바위, 보에 정수값 3, 2, 1을 각각 준다.

나의 카드값과 컴퓨터의 카드값을 결과가 같은 것끼리 묶고 묶은 값끼리 더하면 다음과 같다.

비기는 경우 : (1,3) (2,2) (3,1) => 합계는 항상 4

내가 이기는 경우 : (1,1) (2,3) (3,2) => 합계는 2 또는 5

컴퓨터가 이기는 경우 : (1,2) (2,1) (3,3) => 합계는 3 또는 6

위 규칙을 이용해 if - else if - else 문을 만들면 다음과 같다.

조건식이 현격하게 압축된 것을 확인할 수 있다.

profile
Programming study

0개의 댓글