2022-01-05
오늘은 알고리즘을 공부해보도록 한다.
알고리즘을 공부한적 있지만, 최근 유니티만 작업하면서 C++ 문법에 대한 이해도가 떨어지고 있다는 느낌을 받았다.
최근 .NET을 이용한 서버를 구현해보면서 느낀점
C#으로 library를 많이 쓰게 되어 reference를 사용하는 경우가 많아지면서 좀 더 low한 프로그램을 만들고 싶다.
포인터로 직접 접근이 가능한 C++과 다르게 간접 접근이 많은 C#에 효율성에 이마를 치게 되었다.
먼 개소리같지만 느낌적으로 Low한 c++로 개고생하면 이해도가 더 넓어질거란 생각이다.
일단 설정부터 해보자.
c++ 콘솔로 진행할거라서 깔끔한게 좋아보인다.
Console.cpp //콘솔 조정용
#include "pch.h"
#include "ConsoleHelper.h"
void ConsoleHelper::SetCursorPosition(int32 x, int32 y)
{
HANDLE output = ::GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
::SetConsoleCursorPosition(output, pos);
}
void ConsoleHelper::SetCursorColor(ConsoledColor color)
{
HANDLE output = ::GetStdHandle(STD_OUTPUT_HANDLE);
::SetConsoleTextAttribute(output, static_cast<int16>(color));
}
void ConsoleHelper::ShowConsoleCursor(bool flag)
{
HANDLE output = ::GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
::GetConsoleCursorInfo(output, &cursorInfo);
cursorInfo.bVisible = flag;
::SetConsoleCursorInfo(output, &cursorInfo);
}
#include <iostream>
#include "pch.h"
#include "ConsoleHelper.h"
int main()
{
uint64 lastTick = 0;
while (true)
{
#pragma region 프레임 관리
const uint64 currentTick = ::GetTickCount64();
const uint64 deltaTick = currentTick - lastTick;
lastTick = currentTick;
#pragma endregion
// 콘솔 cursor 위치, 보이기, 색 조정
ConsoleHelper::SetCursorPosition(0, 0);
ConsoleHelper::ShowConsoleCursor(false);
ConsoleHelper::SetCursorColor(ConsoledColor::RED);
// 맵 만들기
const char* TILE = "■";
for (int32 y = 0; y < 25; y++)
{
for (int32 x = 0; x < 25; x++)
{
cout << TILE;
}
cout << endl;
}
}
}
위와 같이 일단 맵을 만들기 위한 기초 작업부터 실시한다.
이걸 왜 하냐...? 나는 일단 알고리즘 공부를 하면서 처음으로 A* 알고리즘을 다시 복습하고 싶다. 요즘 유튜브에서 스타크래프트에 빠졌거든. 특히 유니티에서 구동되는 NevMesh라는 기능을 체험해 본 사람으로서, 프레임 및 응답 속도가 드릅게 느리다는걸 느꼈다.
그리하여, 인프런에서 C++관련 알고리즘 강의를 끊었다.
내 피같은 돈이 나가지만 공부하면 지식이 늘며 머리가 무거워지니 거지라고 놀리면 박치기로 죽여줄거다.
일단 미로를 생성하였다. 미로를 생성하는 과정에서 재밌는 알고리즘을 배웠는데
// Binary Tree 미로 생성 알고리즘
// - Mazes For Programmers
라는 거다. 들어는 봤지만 구체적으로 어떤식으로 구현되는지는 본 적 없는 알고리즘이었는데 이번에 배우면서 흥미를 많이 느꼈다. 이걸로 장난치다가 30분이 흘러버렸다.
void Board::GenerateMap()
{
for (int32 y = 0; y < _size; y++)
{
for (int32 x = 0; x < _size; x++)
{
if (x % 2 == 0 || y % 2 == 0)
_tile[y][x] = TileType::WALL;
else
_tile[y][x] = TileType::EMPTY;
}
}
// 홀수에서 랜덤값으로 오른쪽 혹은 아래쪽을 랜덤으로 뚫어주는 작업
for (int32 y = 0; y < _size; y++)
{
for (int32 x = 0; x < _size; x++)
{
if (x % 2 == 0 || y % 2 == 0)
continue;
// x축 끝이고 y축이 끝일 경우.
if (x == _size - 2 && y == _size - 2)
continue;
// y축만 끝에 다다를 경우
if (y == _size - 2)
{
_tile[y][x + 1] = TileType::EMPTY;
continue;
}
// x축만 끝에 다다를 경우.
if (x == _size -2)
{
_tile[y + 1][x] = TileType::EMPTY;
continue;
}
const int32 randValue = ::rand() % 2; // 1 혹은 0의 랜덤값 생성.
if (randValue ==0)
{
_tile[y][x+1] = TileType::EMPTY;
}
else
{
_tile[y + 1][x] = TileType::EMPTY;
}
}
}
}
처음 시작이 0 부터 시작하므로 짝수는 벽으로 만들어 놓고, 홀수를 빈공간으로 만든다.
그런 다음 홀수일때, 불필요한 값은 걸러낸 후 랜덤값으로하여, 아래 혹은 우측을 벽에서 빈공간으로 만든다. 이런 로직을 통해 미로가 만들어진다.
아쉬운 점은 아래 짝수 지점과 오른쪽 짝수 지점을 컨트롤 할 수 없다는 건데 30분동안 막기위해 여러짓을 해보았다. 하지만 강의를 들어야 하므로 다시 원상복귀
오랜만에 c++를 해보았는데 재밌기도 했지만 확실히 무뎌진 느낌이 강했다.
포인터 관련 *, & 관해서 이해하고 쓰고 있지만 가물가물하다. 다시 공부해야 할 필요성을 느꼈다. 또한, 클래스 쓰는 방식이 C#에 익숙해져 있어 문법이 낯설었다. 또한, 역시 C++은 불친절해. #include <Windows.h> 해더파일을 쓰는데 소문자로 쓴 걸 몰라서 20분동안 노트북과 눈싸움을 벌였다. 빙신
'공부 > 알고리즘 (c++)' 카테고리의 다른 글
오른손 법칙 향상 - stack 대입 (0) | 2022.01.16 |
---|---|
Queue (0) | 2022.01.15 |
Stack (0) | 2022.01.15 |
List (0) | 2022.01.11 |
오른손 법칙 과 Vector (0) | 2022.01.08 |