Study/C++

[C++/Console] 테트리스 만들어 보기 - 6 (바닥 충돌, 블럭 랜덤 생성)

2023. 3. 6. 20:30
목차
  1. 바닥  충돌 (또는 블럭 충돌)
  2. 랜덤 블럭 생성
  3. 현재 까지의 진행 프로젝트 다운로드
 

[C++/Console] 테트리스 만들어 보기 - 5 (충돌 판정 - 벽, 블럭)

[C++/Console] 테트리스 만들어 보기 - 4 (플레이어(블럭) 움직임) [C++/Console] 테트리스 만들어 보기 - 3 (화면 출력에 대한 고찰) [C++/Console] 테트리스 만들어 보기 - 2 (키보드 입력 및 블럭) [C++/Console]

eskeptor.tistory.com

지난 시간에는 충돌 판정에 관련하여 알아보았습니다.

오늘은 바닥 충돌(또는 블럭 충돌) 및 블럭 랜덤 생성에 대해서 알아보겠습니다.

 

바닥  충돌 (또는 블럭 충돌)

지난 시간에 이어서 바닥에 충돌하였을 때 감지하는 방법을 알아봅시다.

바닥을 확인하는 CheckBottom 함수를 작성합니다.

void CheckBottom()
{
    if (IsMoveAvailable(0, 1))
        return;

    // 다음 줄로 움직일 수 없다면 현재 블럭을 포함하여 맵에 저장
    memcpy_s(g_nArrMapBackup, sizeof(int) * MAP_WIDTH * MAP_HEIGHT, g_nArrMap, sizeof(int) * MAP_WIDTH * MAP_HEIGHT);

    // 플레이어의 위치를 초기 위치로 변경
    g_player.SetPosition(START_POS_X, START_POS_Y);
    // 플레이어의 블럭 설정
    g_player.SetBlock(1);
    // 플레이어의 블럭 방향 설정
    g_player.SetDirection(CPlayer::eDirection::Dir0);

    g_prevPlayerData = g_player;
}

 이 CheckBottom 함수는 

int main(void)
{
    InitGame();

    while (true)
    {
        InputKey();
        CalcPlayer();

        CheckBottom();        // <-- Player가 움직인 이후에 바닥 확인
        Render(3, 1);

        ClearScreen();
        BufferFlip();
        Sleep(1);
    }

    DestroyGame();

    return 0;
}

CalcPlayer 함수 다음에 수행합니다.

(플레이어가 움직인 이후에 바닥을 확인하는 매커니즘입니다.)

 

이렇게 수정하고 실행하게 되면

이렇게 바닥 또는 더 이상 내려가지 못하는 곳으로 가게 되면 다음 블럭으로 넘어가게 됩니다.

 

랜덤 블럭 생성

이제 블럭을 랜덤으로 생성할 수 있도록 코드를 작성하여 봅시다.

그 전에 C++에서 사용하는 랜덤 함수에 대해서 알아봅시다.

크게 2가지가 있습니다.

// C언어 기반 rand 함수 사용
#include <stdlib.h>         // 랜덤 함수(srand, rand)가 있는 헤더 파일
#include <time.h>           // 시간 함수(time)가 있는 헤더 파일

srand(time(NULL));          // 랜덤 시드 설정 (time(NULL)은 1970.1.1의 시간 값을 반환)
int nRand = rand() % 10;    // 0 ~ 9까지 랜덤 값을 반환

C언어 기반의 랜덤 함수와

 

// C++11 기반의 랜덤 함수 (MT19937 사용)
#include <random>               // 랜덤 함수가 들어있는 헤더파일

std::random_device rdDevice;    // 랜덤 시드용 디바이스
std::mt19937 gen(rdDevice());   // 난수 생성 엔진(메르센 트위스터) 초기화
std::uniform_int_distribution<int> dist(0, 9);   // 0 ~ 9 랜덤 값 생성
int nRandom = dist(gen);        // 랜덤 값 생성

C++11에서 제공하는 랜덤 함수가 있습니다.

 

이 방법들 중 후자의 방법(C++11 기반)을 사용하도록 하겠습니다.

 

먼저 stConsole 구조체에 랜덤 관련 변수를 추가합니다.

// Console Structure
struct stConsole
{
    // 생략 ....

    // Random Seed
    random_device rdDevice;
    // Random Generation
    mt19937 rdGen;
    // Random Distribution (블럭)
    uniform_int_distribution<int> rdBlockDist;
    // Random Distribution (블럭의 방향)
    uniform_int_distribution<int> rdDirDist;

    stConsole()
        : hConsole(nullptr), hBuffer{ nullptr, }, nCurBuffer(0)
        , rdGen(rdDevice()), rdBlockDist(0, 6), rdDirDist(CPlayer::eDirection::Dir0, CPlayer::eDirection::Dir270)
    {}
};

 

그리고 랜덤으로 블럭을 생성하는 RandomBlock 함수와 랜덤으로 블럭의 방향을 생성하는 RandomDirection 함수를 작성합니다.

/**
블럭 랜덤 생성
*/
int RandomBlock()
{
    return g_console.rdBlockDist(g_console.rdGen);
}

/**
블럭의 방향 랜덤 생성
*/
int RamdomDirection()
{
    return g_console.rdDirDist(g_console.rdGen);
}

 

이제 모든 상황에서 블럭을 랜덤한 방향으로 생성하도록 해봅시다.

// InitGame 함수 변경
void InitGame(bool bInitConsole = true)
{
    // Initialize Player Data
    {
        g_player.SetPosition(START_POS_X, START_POS_Y);
        g_player.SetXPositionRange(-1, MAP_WIDTH);
        g_player.SetYPositionRange(0, MAP_HEIGHT);
        
        // 블럭 랜덤 생성
        g_player.SetBlock(RandomBlock());
        // 블럭 방향 랜덤 생성
        g_player.SetDirection((CPlayer::eDirection)RamdomDirection());
        
        g_player.SetGameScore(0);
        g_player.SetGameOver(false);

        g_prevPlayerData = g_player;
    }
    
    // 생략 ....
}

InitGame 함수에서 블럭을 랜덤으로 생성하도록 변경 합니다.

 

// CheckBottom 함수 변경
void CheckBottom()
{
    if (IsMoveAvailable(0, 1))
        return;

    memcpy_s(g_nArrMapBackup, sizeof(int) * MAP_WIDTH * MAP_HEIGHT, g_nArrMap, sizeof(int) * MAP_WIDTH * MAP_HEIGHT);

    g_player.SetPosition(START_POS_X, START_POS_Y);
    // 블럭 랜덤 생성
    g_player.SetBlock(RandomBlock());
    // 블럭 방향 랜덤 생성
    g_player.SetDirection((CPlayer::eDirection)RamdomDirection());

    g_prevPlayerData = g_player;
}

CheckBottom 함수에서 블럭을 랜덤으로 생성하도록 변경 합니다.

 

이제 실행하여 봅시다.

이렇게 바닥 또는 블럭에 충돌했을 때 다음 블럭으로(랜덤하게) 나오도록 하였습니다.

 

다음 시간에는 자동으로 블럭이 내려오도록 하고 라인을 형성하였을 때 지워지면서 점수가 올라가도록 해보겠습니다.

 

현재 까지의 진행 프로젝트 다운로드

TetrisCpp_6편.7z
0.01MB

저작자표시 비영리 변경금지 (새창열림)

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

[C++/Console] 테트리스 만들어 보기 - 7 (자동 하강, 블럭 회전, 라인 클리어)  (1) 2023.04.17
[C++11] unordered_map  (0) 2023.03.20
[C++/Console] 테트리스 만들어 보기 - 5 (충돌 판정 - 벽, 블럭)  (0) 2023.02.20
[C++/Console] 테트리스 만들어 보기 - 4 (플레이어(블럭) 움직임)  (0) 2023.02.09
[C++/Console] 테트리스 만들어 보기 - 3 (화면 출력에 대한 고찰)  (0) 2023.02.02
  • 바닥  충돌 (또는 블럭 충돌)
  • 랜덤 블럭 생성
  • 현재 까지의 진행 프로젝트 다운로드
'Study/C++' 카테고리의 다른 글
  • [C++/Console] 테트리스 만들어 보기 - 7 (자동 하강, 블럭 회전, 라인 클리어)
  • [C++11] unordered_map
  • [C++/Console] 테트리스 만들어 보기 - 5 (충돌 판정 - 벽, 블럭)
  • [C++/Console] 테트리스 만들어 보기 - 4 (플레이어(블럭) 움직임)
Eskeptor
Eskeptor
Eskeptor
Hello World
Eskeptor
전체
오늘
어제
  • 분류 전체보기 (138)
    • Computer (5)
      • Linux (1)
      • Hardware (2)
      • Software (0)
      • Tips (1)
      • Website (0)
    • Mobile (1)
      • Application (1)
    • Study (108)
      • Android (9)
      • C언어 (45)
      • C++ (17)
      • Unity 5(유니티5) (11)
      • Qt 프로그래밍 (2)
      • MFC (12)
      • C#, Winform (12)
    • My World (24)
      • OpenPad(Android) (12)
      • 한글 패치 (1)
      • C#으로 만든 귀요미들 (5)
      • MFC로 만든 귀요미들 (6)
    • Life Goes On (0)
      • Hip Hop (0)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • 슈팅게임
  • 메모장
  • Unity
  • Java
  • 배열
  • C언어
  • openpad
  • MFC
  • 자료구조
  • 포인터
  • c++11
  • 기본
  • Android
  • 기초
  • C#
  • Tetris
  • 자바
  • 만들기
  • 안드로이드
  • 강의
  • 강좌
  • 오픈패드
  • 유니티
  • C++
  • 프로그래밍
  • 초보
  • 왕초보
  • 테트리스
  • 알고리즘
  • 비행기

최근 댓글

최근 글

hELLO · Designed By 정상우.
Eskeptor
[C++/Console] 테트리스 만들어 보기 - 6 (바닥 충돌, 블럭 랜덤 생성)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.