[C++ 기초] 콘솔게임, 난수, unsigned, 객체지향 개요(Class)

라멘커비·2023년 12월 20일
0

CPP 입문

목록 보기
7/25

콘솔창(CMD)

과거에 Dos(Disk operating system)라는 시스템이 있었다. 아무런 운영체제도 없던 시절에 있었다. 명령 줄 기반의 시스템이었다.

우리가 VS에서 F5를 누르면 내 프로그램이 콘솔창을 포함하는 것이 아니고
예를 들어 123을 출력하는 프로그램을 실행시키면 내 프로그램이 콘솔창에 "123 출력해줘"라고 명령하는 것이다.

콘솔창을 사용하다보면 다양한 프로그램들(cls, dir 등의 명령어들이 exe파일임)을 사용할 수 있는데, 이것들은 윈도우에 환경변수로 등록되어 있어서 폴더와 상관없이 사용할 수 있다.

콘솔게임

게임을 만들 때 주의해야할 점

  • 한 함수가 2가지 목적을 가지면 안된다. 특히 랜더링과 로직은 분리하는 게 좋다.
    만약 그런 함수가 있다면 1가지 목적을 가진 함수 2개를 따로 만든 후 모아서 만드는게 유리하다.
// 실제 데미지를 데이터적으로 주는 함수
void DamageLogic(const int& _Att, int& _DefHp)
{
    // 축약연산자라고 부르기도 한다.
    // - 뿐만 아니라 더하기 나누기 곱하기 비트단위등등 거의 모든 연산의
    // 축약 연산자가 존재한다.
    _DefHp -= _Att;
    // _DefHp = _DefHp - _Att;
}
// 공격의 행동을 화면에 랜더링하는 함수
void DamageRender(const char* _Name, const int& _Att)
{
    printf_s("%s 가 %d의 공격력으로 공격했습니다.\n", _Name, _Att);
}

사용할 때 두 개의 함수를 묶어도 된다.

void Damage(const char* _Name, const int& _Att, int& _DefHp)
{
    DamageRender(_Name, _Att);
    DamageLogic(_Att, _DefHp);
}
  • 게임의 main 루프라는 것을 만들고 거기에서 모든 일이 벌어진다.
    이때 한 번의 루프가 도는 것을 프레임이라고 한다.

#include <conio.h>

#include <conio.h>을 활용한다.

  • _getch() : 아무키나 눌릴 때까지 기다려준다.
  • system() : 콘솔창에 명령을 요청한다.
    • ex) system("cls"); // 콘솔창 비우기

간단한 TextRpg

코드

#include <iostream>
#include <conio.h>

int StringCount(const char* const _Ptr)
{
    int Count = 0;
    while (_Ptr[Count])
    {
        ++Count;
    }
    return Count;
}

// const를 붙인 이유
// 보여주기만 하는 함수, 수정할 목적이 없는 함수
void StatusRender(const char* _Name, int _Att, int _Hp) {
    //int NameSize = StringCount(_Name);
    //int NameSize = strlen(_Name);
    int NameSize = printf_s("%s ", _Name); // 출력하면서 이름 글자수도 알아낼 수 있음.

    // 콘솔창은 특수문자를 통해서 특수한 출력기호를 사용할 수 있는데, 전부다 \(역슬래시)를 사용해서 표현한다.
    // \n <= 콘솔창에서 1글자로 본다.
    // \r
    for (int i = 0; i < 50 - NameSize; i++) {
        printf_s("-");
    }
    printf_s("\n"); // 라인을 바꾸라는 의미.
    printf_s("공격력 %d\n", _Att);
    printf_s("체력 %d\n", _Hp);

    for (int i = 0; i < 50; i++) {
        printf_s("-");
    }
    printf_s("\n");
}

// 실제 데미지를 데이터적으로 주는 함수
void DamageLogic(const int& _Att, int& _DefHp)
{
    // 축약연산자라고 부르기도 한다.
    // - 뿐만 아니라 더하기 나누기 곱하기 비트단위등등 거의 모든 연산의
    // 축약 연산자가 존재합니다.
    _DefHp -= _Att;
    // _DefHp = _DefHp - _Att;
}
// 공격의 행동을 화면에 랜더링하는 함수
void DamageRender(const char* _Name, const int& _Att)
{
    printf_s("%s 가 %d의 공격력으로 공격했습니다.\n", _Name, _Att);
}

void Damage(const char* _Name, const int& _Att, int& _DefHp)
{
    DamageRender(_Name, _Att);
    DamageLogic(_Att, _DefHp);
}

int main()
{
    // 존재하게 하기 위해 상태를 만들었다.
    char PlayerName[100] = "Fighter";
    int PlayerHp = 100;
    int PlayerAtt = 10;

    char MonsterName[100] = "Orc";
    int MonsterHp = 50;
    int MonsterAtt = 5;

    // 몬스터나 플레이어를 눈에 보이게 만들기
    StatusRender(PlayerName, PlayerHp, PlayerAtt);
    StatusRender(MonsterName, MonsterHp, MonsterAtt);

    while (true) {
        {
            int Input = _getch();

            system("cls");
            DamageLogic(PlayerAtt, MonsterHp);

            StatusRender(PlayerName, PlayerAtt, PlayerHp);
            StatusRender(MonsterName, MonsterAtt, MonsterHp);

            DamageRender(PlayerName, PlayerAtt);
        }

        {
            int Input = _getch();

            system("cls");
            DamageLogic(MonsterAtt, PlayerHp);

            StatusRender(PlayerName, PlayerAtt, PlayerHp);
            StatusRender(MonsterName, MonsterAtt, MonsterHp);

            DamageRender(PlayerName, PlayerAtt);
            DamageRender(MonsterName, MonsterAtt);
        }
    }

    return 0;
}

실행 화면


아무 키나 클릭하면 공격이 순서대로 진행된다..

난수

난수 : 정의되지 않은 수가 나오는 것.
특정 공식에 따라서 어떠한 수를 변형시킨 수가 나오는 것.

매번 다른 수가 나오려면 시드밸류가 바뀌어야 한다.
한 번 바뀐 시드밸류가 또 바뀔 필요는 없다.

rand(), srand()

C스타일의 난수는 rand()함수로 뽑을 수 있다.
rand() 함수는 난수를 뽑아준다.
srand()로 난수 계산식의 Seed값을 바꿔줄 수 있다.

	int  Value = 0;
	__int64 Address = reinterpret_cast<__int64>(&Value);

	// 시드값 바꾸기
	srand(Address);

	for (int i = 0; i < 5; i++)
	{
		int Number = rand();
		printf_s("%d\n", Number);
	}

Signed와 Unsigned

  • 0b000000000000000000000000000000
    맨 앞 비트를 부호비트라고 부른다. Int는 32비트이므로 2의 32승까지의 양수를 표현할 수 있지만 부호비트때문에 31승까지밖에 표현하지 못한다. 음수는 2의 31승 + 1만큼의 음수를 표현할 수 있다.
    그럴 때 부호비트도 양수표현으로 사용하고 싶다고 붙이는 키워드가 있다.

    부호비트를 사용하면 signed
    부호비트를 사용하지 않으면 unsigned를 붙여줘야 한다. (부호비트 사용하지 않고 양수로 표현)

(반대로 음수도 음수로 표현해야 한다고 붙이는 키워드가 있다.)

  • 평소에 쓰는 int는 사실 signed int가 생략된 것이었다.

  • unsigned int에 -1을 넣어주면 부호가 없을 때의 양수 최댓값이 된다.

typedef

typedef는 자료형에 별명을 붙이는 것이다.

// typedef는 자료형에 별명 붙이기 이다.
typedef unsigned int uint;

int main() {
	uint UValue = 20;

	return 0;
}
  • uint랑 size_t랑 색이 같다. size_t도 사실 자료형 별명임.

    F12 눌러서 정의로 가서 보면 size_t는 unsigned __int64임을 알 수 있다.

    F12 : size_t나 함수같은 프로그래머가 만든 선언이 따로 존재하는 경우, 커서를 두고 F12를 누르면 그 선언으로 이동. (프로젝트를 만약 처음 켰다면 느릴 수 있다)

  • typedef를 또 typedef할 수 있다.

typedef unsigned int uint;
typedef uint pint;
typedef pint dint;

uint, pint, dint 중 뭘 써도 똑같다.

객체지향 프로그래밍(OOP)

프로그래밍 패러다임의 1가지 종류이다. 각 프로그래밍 언어는 추구하는 이상이 있다. C++ 객체지향 언어라는 표현은 잘못됐다. 객체지향"도" 할 수 있는 언어다. C++은 멀티패러다임 언어이다.

객체(Object)라는 개념만을 사용해서 코딩하는 것을 객체지향이라고 한다.
객체지향에는 전역이라는 개념이 존재하면 안된다. 모든 것이 개념 안에 묶여있어야 한다.

객체와 개념

개념이 메모리화된 것을 객체라고 부른다.

예시(비유)
int ← 정수라는 개념
int Value = 0; ← 객체
........................................................................................
몬스터 ← 개념
Monster111 이라고 한 마리 만듦 ← 객체

자료형을 개념이라고 본다.
정수라는 개념만으로는 아무것도 할 수 없다. 정수로 계산을 하려면 객체화를 해야한다. int도 클래스이다. C++만든 사람들이 먼저 만들어준 "개념"으로, 기본 자료형이라고 부른다.

Class

개념을 사용하려면 객체화 해야한다. 그때 Class라는 것을 만든다.

몬스터를 만들고 싶어 → 몬스터의 개념을 먼저 만들어야 한다.
class → 개념을 만들겠다.

Monster를 객체화하는 것은 int A;로 변수를 선언하는 것과 똑같다.

#include <iostream>

// 몬스터를 만들고 싶다.
// 그 개념을 문법화 시켰다.
// 이걸 사용자 정의 자료형이라고 한다.
//		user definition type
class Monster { // 몬스터의 개념

};

int main() {
	int A;
	Monster NewMonster;
}

만들기만 해도 초기화하는 방법이 있다. (나중에 자세히 다시 배움) 그리고 int에도 사실 있다.

	// 몬스터 객체
	Monster NewMonster = Monster(); // 만들기만 해도 초기화하는 방법
	int NewInt = int(); // 사실 int도 갖고 있음.

Class 예시

Class 내부에는 개념이 가져야 하는 상태와 행동을 구체화할 수 있다.
클래스 내부에 있는 변수는 클래스 내부 함수 등에서 바로 사용할 수 있다. 그러므로 StatusRender함수에 인자가 필요없다.

#include <iostream>

class Player {

	// 클래스 내부

	// 상태
	char Name[100];
	int Hp;
	int Att;
	int Speed;

	// 행동
	// 구체화를 해야 한다.
	void Damage(int& _Att);
	void StatusRender();
};

class Monster {

};

int main() {
	Player NewPlayer = Player();
}
profile
일단 시작해보자

0개의 댓글

관련 채용 정보