게임 프로그래밍 | C++ | 랜덤

2024. 3. 22. 13:14·개발/C++

개요

저희 학교에선 자료구조 시간에서 C++ 문법을 배우고 게임 프로그래밍 시간에 배운 C++ 문법을 사용해서 게임을 만듭니다.

물론 아직까지 게임이라곤 숫자 야구라거나 업다운 게임이라거나 유사 검강화하기 같은 콘솔 텍스트 게임이지만요...

 

이번에 게임 프로그래밍 수업에서 배웠던 랜덤에 대해 적어보려고 합니다.

 

 


 

 

rand()

 

C++에선 기본적으로 rand 함수를 제공합니다.

#include <iostream>

using namespace std;

int main()
{
	int randNum = rand();
	cout << randNum; // 실행결과 41
}

0~999999... 까지의 숫자를 반환하는데 다시 실행해봐도 출력은 계속해서 41로 같은값이 나옵니다.

 

어? 이러면 안되는거 아닌가?

이러면 이게 랜덤인게 맞나요? 반쪽짜리 아닌가?

 

rand 함수에 매개변수가 들어가는지 확인해봤는데 그것도 아닙니다.

 

 


 

 

srand()

rand 의 값은 srand 에 들어가는 시드에 따라 달라진다고 합니다.

srand 에서 무슨 시드를 넣으면 rand 에선 그 시드에 해당하는 난수표에서 숫자를 순서대로 뽑아오는 것이죠.

 

기본으로는 시드가 1로 지정되어 있습니다.

 

시드를 2로 바꾼 후에 rand를 실행해보면...

#include <iostream>

using namespace std;

int main()
{
	srand(2);
	int randNum = rand();
	cout << randNum; // 출력 결과 : 45
}

와우!! 정말 신기하게도 값이 바뀌었습니다.
근데 Seed를 2로 바꾼다고 반쪽짜리 랜덤이 완성되진 않습니다.

 

그래서 srand()에 계속해서 변하는 값을 넣어주는 것으로 반쪽짜리 랜덤을 그나마 랜덤처럼 보이게 해줄 수 있습니다.

 

사실 완벽한 난수란건 없어요.

 

 

 


 

 

time()

C++로 한정짓지 않고 크게 봤을때 현실에서도 계속해서 변하는 값은 충분히 찾을 수 있습니다.

부제에서 보이듯이 시간이죠.

 

시간은 큰 단위로 년부터 시작해서 달, 일, 시간, 분, 초... 이렇게 세세하게 나눌 수 있지만
C++에선 time()이라는 함수로 초에 접근할 수 있습니다.

time()은 제가 글을 쓰는 지금도 계속해서 초를 세고 있습니다.

 

찾아보면 1970년 1월 1일 0시 0분 0초부터 지금 현재까지 경과한 시간을 초로 나타낸 것이라고 합니다.

그렇기 때문에 1초마다 값이 바뀌죠.

그러면 이걸 srand에 넣어주면 1초마다 Seed가 바뀌는 랜덤이 완성되지 않을까요?

 

#include <iostream>

using namespace std;

int main()
{
	srand(unsigned int(time(NULL)));
	int randNum = rand();
	cout << randNum; // 출력 결과 : 26417
}

계속해서 출력해봐도 출력결과는 계속해서 바뀝니다.

 

 


 

 

원하는 범위의 값을 뽑기 위해선?

선생님께 들은바론 srand라는 함수는 처음에 한번 실행해주면 rand함수가 호출될때마다 호출된다고 합니다.

그러니까 rand()를 호출할떄마다 srand를 호출할 필요는 없다는거죠.

 

그러니

#include <iostream>

using namespace std;

int main()
{
	srand(unsigned int(time(NULL)));
	int randNum = rand();
	cout << randNum; 
}

이 코드를 실행하면 랜덤한 값을 가져올 수 있습니다。

 

하지만! 저는 1 ~ 10, 1 ~ 5 같은 특정한 범위의 난수를 갖고 싶었습니다.

 

특정한 범위의 값을 갖기 위해선 %, 즉 나머지를 구해야 합니다.

 

#include <iostream>

using namespace std;

int main()
{
	srand(unsigned int(time(NULL)));
	int randNum = rand();
	cout << randNum % 10; // 0부터 9까지의 난수 
}

 

랜덤한 수를 10으로 나눈 후 나머지를 구하면 0부터 9까지의 수가 나오겠죠?

이것을 응용하면 시작점이 0이 아닌 범위의 난수를 구할 수 있습니다.

 

#include <iostream>

using namespace std;

int main()
{
	srand(unsigned int(time(NULL)));
	int randNum = rand();
	cout << (randNum % 10) + 1;  // 1부터 10까지의 난수 
}

이런식으로 말이죠.

원하는 범위의 최댓값을 n, 최솟값을 m이라고 하고 식으로 정리하면...

 

randNum % (m + 1 - n) + n

이런 느낌이죠.

 

정말 유용하죠?

 

C#같이 날먹으로 Random.Range(0, 10) 이런식으로 하면 편하지만 C++은 그딴거 없습니다.
야생의 언어이기 때문이죠.

 

 


 

 

마치는 말

사실 랜덤 진도는 저번 주에 다 나갔습니다.

생각해보니 제가 C++을 두 과목에서 공부하는데 자료구조만 적는건 조금 개연성이 없다고 판단했죠.

 

그래서 이번주 배운것도 배움일지 후딱 해치우고 그거 기반으로 쓰러 올겁니다.
언제가 될지는 모르겠어요...

'개발 > C++' 카테고리의 다른 글

자료구조 | C++ | 클래스  (1) 2024.04.05
자료구조/게임 프로그래밍 | C++ | 함수, 포인터  (1) 2024.03.28
자료구조 | C++ | 문자열  (3) 2024.03.17
자료구조 | C++ | 기본 개념  (1) 2024.03.07
자료구조 | C++ | 기초사항  (3) 2024.03.06
'개발/C++' 카테고리의 다른 글
  • 자료구조 | C++ | 클래스
  • 자료구조/게임 프로그래밍 | C++ | 함수, 포인터
  • 자료구조 | C++ | 문자열
  • 자료구조 | C++ | 기본 개념
SundG0162
SundG0162
블로그 프로필은 머핀입니다.
  • SundG0162
    게임개발고수가될거야
    SundG0162
  • 전체
    오늘
    어제
    • 분류 전체보기 (78)
      • 주저리 (3)
        • 잡담 (2)
        • 장현우 (0)
        • 회고록 (1)
      • 개발 (50)
        • CITADEL : 성채 (1)
        • HEXABEAT (1)
        • FRACTiLE (6)
        • UNNAMED (9)
        • Default Defense (10)
        • T-Engine (1)
        • Project EW (0)
        • 졸업작품 (0)
        • Unity (3)
        • C# (4)
        • C++ (13)
        • WinAPI (1)
        • 그 외 (0)
      • 알고리즘 (13)
        • C# (1)
        • C++ (12)
      • 자료구조 (2)
        • C++ (1)
        • C# (0)
        • 공용 (1)
      • 기타 (10)
        • 아트 (6)
        • AI (2)
        • 수학 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    LLM
    코딩
    티스토리챌린지
    생성형ai
    오블완
    유니티
    코딩트리조별과제
    코딩테스트
    C#
    코드트리
    AI
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
SundG0162
게임 프로그래밍 | C++ | 랜덤
상단으로

티스토리툴바