공부/알고리즘 (c++)

알고리즘 드가자

원클릭쓰리버그 2022. 1. 5. 19:15
728x90

 

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