본문 바로가기

Go/[Go]Up Down Counting 게임 만들기

난수 생성하기

난수를 생성하기 전 알아야할 내용에 대해 이야기해보겠습니다.

  • 패키지명과 임포트 경로
  • 난수 생성 원리
  • Seed란?
패키지명과 임포트 경로

난수를 생성하기 위해 import 문에 "math/rand"라는 이름으로 rand 패키지를 가져와야합니다.
예시) number := rand.Intn(100) + 1

그러나, 저는 왜 math/rand.Intn()이 아니라 rand.Intn()인지에 대한 의문이 생겼습니다. 직접 math/rand.Intn()을 작성해본 결과 컴파일 에러가 발생한 것을 확인할 수 있었습니다.

그렇다면 왜 math/rand.Intn()이 아니라, rand.Intn()일까요?
-> Go 언어에서 패키지를 import 하기위해서 "fmt"와 같은 문구를 작성하여 사용합니다. 그러나 이때 주의해야할 것은 "fmt"는 임포트 경로일뿐이고 실제 패키지가 아니라는 것입니다.

이해하기 쉽게 예시를 들어 설명하겠습니다.
import(
    "fmt"
    "log"
    "math/rand"
)

해당 import 문을 예시로 말씀드리겠습니다.
import 문에 작성된 패키지들은 실질적으론 임포트 경로 입니다.
즉, 패키지를 가져오기 위한 경로일뿐, 패키지의 이름이 아닌것입니다.
따라서, import "math/rand"라는 것은 임포트 경로를 통해 rand라는 패키지를 가져오는 것입니다.

 

난수 생성 원리

rand.Intn()이라는 함수의 인자값으로 정수를 입력하게 되면 "0 ~ 정수값-1"의 난수를 생성하게 됩니다.
즉, rand.Intn(100) + 1이라는 것은 1~100 사이의 난수를 생성하는 것입니다.

그러나 이때 해당 코드를 실행해보면 난수가 아닌, 일정한 값만이 반복적으로 출력되는 것을 확인하실 수 있을 것입니다. 그 이유는 컴퓨터에서 생성한 난수는 무작위 숫자가 아니기 때문입니다.

그렇다면 어떻게 해야 무작위 숫자인 난수를 생성할 수 있을까요?
프로그램을 실행할 때마다 새로운 숫자를 생성해주기 위해 rand.Seed()라는 함수를 사용하면 해결할 수 있습니다. Seed는 난수 값을 생성하는데 도움을 주는 함수입니다. 그러나, rand.Seed()의 인자값이 고정될 경우엔 생성되는 난수 또한 고정되기 때문에 이를 해결할 필요가 있습니다.

그 방법은 import "time"을 통해 해결할 수 있습니다. time.Now()라는 작업을 통해 초마다 변경되는 값을 얻어 고정적인 값이 아닌, 유동적인 값으로 Seed()의 인자값으로 입력해줄 수 있습니다. 그러나, time.Now()라는 것을 fmt.Println()을 통해 출력해보면 정수값이 아닌, 문자열로 출력되는 것을 확인할 수 있을 것입니다. 따라서 time.Now().Unix()를 통해 정수값을 추출합니다. Unix()는 현재 날짜 및 시간을 정수값으로 반환해주는 함수이기 때문에 Seed()의 인자값으로 적합합니다.

구현 방법은 다음과 같습니다.
package main

import(
	"math/rand"
	"time"
)

func main(){
	seconds := time.Now().Unix()
	rand.Seed(seconds)
	randNum := rand.Intn(100) + 1
}​

 

Seed란?

컴퓨터 프로그램에서 발생하는 무작위 수는 사실 엄격한 의미의 무작위 수가 아닙니다.

어떤 특정한 시작 숫자를 정해 주면 컴퓨터가 정해진 알고리즘에 의해 마치 난수처럼 보이는 수열을 생성합니다.

이러한 시작 숫자를 Seed라고 합니다.