프로그래밍/Lua

Lua 를 이용한 가위바위보 게임 만들기

내꿈은자동화 2017. 2. 16. 23:22

코드에 대한 설명은 파란색으로 되어있다.


자료형, 구문 등에 대해 나눠서 설명하려고 했는데 그런 방식보다는 프로그램 하나를 만들면서 그 안에 필요한 기능들에 대해 수행하는 것이 더 좋다고 본다.


이번 글에서는 Lua 를 이요해서 (컴퓨터와 대결하는) 가위바위보 게임을 만들어 볼 것이다.


코드는 앞의 글에서 소개한 Visual Studio Code 를 이용하여 작성할 것이다.


글의 순서는 

1. 가위바위보 게임에 대한 간단한 소개

2. 게임의 시작과 변수 설정

3. 가위바위보 승무패 알고리즘



1. 가위바위보 게임은


<그림 1> 가위바위보


파란색 화살표 방향으로 이기고 빨간색 화살표 방향으로 지는 것이다.

(보는 바위한테 이긴다.)



2. 게임의 시작과 변수 설정


Lua 프로그램은 cmd 창에서 실행한다. 그렇기 때문에 실행을 해준 뒤 cmd 창에 글자를 써서 프로그램이 잘 실행되었는지 알아보아야 한다. (여기서는 가위바위보 게임이 시작되었다는 것을 알려줄 것이다.)


RSP.lua 파일을 생성한다. (RockScissorPaper.lua)


코드에서 처음 나오는 것이 가장 먼저 실행된다.


<그림 2> 게임의 시작을 알려주는 문구


<그림 2> 의 print 함수는 print("쓰고자 하는 문자") 형태로 쓴다. 

print 안에 변수를 사용하고 싶다면 print("쓰고자 하는 문자"..변수.."") 의 형태로 사용하면 된다.

<그림 2> 와 같이 입력한 후 프로그램을 실행하면 Rock Scissor Paper 이란 글자가 출력될 것이다.


이제 변수를 설정해 보자. 


먼저 어떤 변수들을 사용해야 할지 정하자.

1) 플레이어 점수 (PlayerScore)

2) 컴퓨터 점수 (ComScore)

3) 플레이어가 낸 것 (가위바위보 중) (PlayerRSP)

4) 컴퓨터가 낸 것 (ComRSP)


<그림 3> 변수 선언


<그림 3> 과 같이 게임에서 사용하게 될 변수를 선언하고 초기화한다. (변수에 처음으로 값을 할당해주는 것을 '초기화' 라고 한다.)


(게임을 만들면서 변수를 더 추가할 수 있다.)


3. 함수를 이용한 게임 생성


변수를 선언해 주었다면 이제 RSP 게임의 순서를 짜야한다.


라운드 설정 -> 게임 -> 프로그램 종료의 형태로 진행할 것이다.


<그림 4> 라운드 설정


<그림 4> 는 라운드 설정이다.


여기서는 '함수', '입력', 'while', '나머지연산', 'print', 'not 연산' 이 사용되었다.


함수의 사용법은 다음과 같다.

function 함수명 (함수의 매개변수)
    함수 내용
end

여기서 매개변수는 함수 외부에서 불러져와서 함수 내에서 사용될 변수이다.


함수 안에 round = io.read("*n") 라는 문장이 있다. 이것은 round 라는 변수에 값을 입력해준다는 것인데, "*n" 을 넣어줬기 때문에 입력값을 숫자 값으로 받을 수 있다. (프로그램을 작성할 때 '문자의 1' 과 '숫자의 1'은 다르다.)


while 문은 '조건이 거짓이 아닐 때' 작동한다.

while 조건 do
    조건이 참일 때 실행될 코드
end

이번 게임에서 라운드가 '홀수' 가 되어 항상 승부가 나는 형태로 만들고 싶기 때문에 조건에 (round%2) ~= 1 을 넣었다.

여기서 round%2 는 round 값을 2로 나누었을 때의 나머지를 뜻하고 '~=' 는 참이 아니라는 뜻이다. (not operator)

(대부분의 프로그래밍 언어에서 '==' 는 '참(true)', '!=' 는 '거짓(false)' 인데 Lua 에서는 '~=' 이 거짓이다.)


여기까지가 라운드 설정이다.

해당 코드를 입력한 후 function 밖 변수를 선언한 곳 밑에 SetRound() 를 넣게 되면 라운드를 설정하는 문구가 출력된다. 


<그림 5> SetRound 함수를 만든 후 실행했을 때의 모습


이제 라운드를 설정했으니 RSP 게임을 구성해볼 것이다.

게임 또한 함수 내에 구성할 것이다.


<그림 6> RSPGame 함수


이번 함수에서는 '지역 변수', '랜덤 함수', 'if 문', '비교 연산자' 를 추가적으로 사용할 것이다.


먼저 함수에서 while 안 부분과 바깥 부분을 볼 수 있는데 while 안이 가위바위보 게임을 하는 부분, 바깥이 승부가 난 후 누가 이겼는지 알려주는 부분이다.


while 의 조건은 '플레이어와 컴퓨터 둘 다 절반 이하의 라운드를 승리했다.' 이다. (라운드가 홀수이기 때문에 해당 조건을 만족하면 아직 승부가 나지 않은 것이다.)


while 바깥 부분을 먼저 살펴보겠다.

승부가 난 경우 while 문을 빠져나와서 if 문으로 들어가게 된다. 

if 문의 사용법은 다음과 같다.

if 조건A then
    조건 A가 참일 때 실행될 코드
elseif 조건B then
    조건 A가 거짓이나 조건 B가 참일 때 실행될 코드
else
    조건 A와 B 가 거짓일 때 실행될 코드
end

elseif 와 else 는 원할 때 사용하면 되며 else 는 항상 맨 마지막에 와야한다. (else 다음에 elseif 오면 에러)


위 코드에서 if 문을 이용하여 PlayerScore와 ComScore를 비교해 누가 이겼는지 알아본다.


이제 while 문 안을 살펴볼 것이다.

while 문의 조건은 앞에서 말했듯이 '플레이어와 컴퓨터 둘 다 절반 이하의 라운드를 승리했다.' 이다.

15 번째 줄에서 가위바위보가 각각 무엇인지 플레이어에게 알려준다.

이제 플레이어와 컴퓨터가 가위바위보를 내어야 한다.

플레이어는 입력을 통해 값을 얻게 되고 컴퓨터는 랜덤함수를 통해 값을 얻게 된다.


프로그램에서 랜덤함수는 '랜덤 표' 내의 특정 수를 입력하게 된다.

가령 math.random(3) 을 입력하게 되면 1~3 까지의 수 중에서 랜덤으로 값이 나온다고 생각할 수 있지만 math.random(3) 은 특정 '랜덤 표' 에서 랜덤한 값이 나오기 때문에 항상 같은 값이 나온다. (math.random(3) 의 경우 1이 나온다.)

그렇기 때문에 우리는 'Random Seed' 를 변경해 '랜덤 표' 를 바꿔주는 작업을 해야한다.


17 번째 줄에서 math.randomseed(os.time()) 는 현재 OS (Operating System, 컴퓨터의 운영체계)의 시간을 랜덤 시드로 바꾸어 임의의 랜덤값을 도출해내는 것이다. (물론 여기서도 특정 시간 단위로 바뀌기 때문에 그 시간 내에서 같은 '랜덤 표' 를 갖는다.)


(이 코드에서는 플레이어의 입력값이 1~3을 벗어날 때에 대한 제한을 19~20번째 줄에 두었다.)

플레이어가 가위바위보 중 하나를 내면 컴퓨터도 이에 맞게 가위바위보 중 하나를 내게 되고 누가 이겼는지, 컴퓨터가 무엇을 내었는지, 그리고 현재 점수가 몇 대 몇인지 까지 나오게 된다. (비교연산자를 통한 비교)



이까지 코드를 작성하면 게임이 잘 된다. 하지만 라운드가 끝났을 때 바로 게임이 종료되어 버린다.


그 때 특정 상황에서는 게임을 종료하고 아니면 계속 게임이 실행되어 있는 상태로 만들어 보자.


프로그램 종료


프로그램 종료 이전에 Lua 의 프로그램 진행 순서를 한번 알아볼 필요가 있다. Lua 에는 함수를 제외한 다른 코드가 다 실행된 후 프로그램이 종료되는 형태이다. 그렇기 때문에 게임을 계속 진행하고 싶다면 while 문을 이용하여 그 안에 라운드 설정과 RSPGame 를 넣어야 한다.

<그림 7> while 안에 함수를 넣은 형태


<그림 7> 과 같이 while 안에 SetRound, RSPGame 함수를 넣으면 '조건' 이 '거짓이 아닌 경우' 계속 실행된다. (다른 프로그래밍 언어에서 while 문의 조건은 0,1 등의 숫자를 입력하면 0은 거짓 나머지 숫자는 참이었는데 Lua 에서는 조건문 등의 비교를 통해서 false 가 나올때만 while 문을 만족하지 않는다.)


프로그램의 종료를 위해서 FinishGame 함수를 작성하고 게임이 끝났을 때 특정 행위를 하면 StopVariable 값을 1로 바꾸어 break 를 통해 while 문을 빠져나가 프로그램을 종료해 보자.

(break 는 루프(while 이나 for)를 빠져나가는 역할을 수행한다.)


<그림 8> FinishGame 함수


<그림 8> 은 프로그램을 종료하는 함수이다. 값을 입력받는데 27을 입력받게 되면 <그림 7> 에서 보았던 StopVariable 값을 1로 바꿔준다.


이렇게 가위바위보 게임을 만들어 cmd 창을 통해 실행하면 결과는 다음과 같다.


<그림 9> 프로그램 실행 결과


(생각보다 컴퓨터는 강력하다.)


여기까지가 이 글의 끝이고 코드는 파일로 첨부해 두겠다.

RSP.lua



생각보다 글로 작성하는게 가독성이 좋지 않아 다음번엔 ppt 형태로 작성하는 것도 고려해 보겠다.



요즘 초등학교 교과과정에 프로그래밍이 추가되고 있는 추세라는데 무작정 어려운 것부터 배우면 머리아플 수 있으니 간단한 게임을 만드는 것부터 해본다면 재미있게 프로그래밍 공부를 할 수 있을 것이다.



<참고 문헌>


<그림>

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

Lua - 프로그램 실행  (0) 2017.02.05
Lua 소개 및 설치  (0) 2017.02.05