https://steamcdn-a.akamaihd.net/apps/valve/2010/gdc2010_vlachos_l4d2wounds.pdf

 

돌아다니는 코드 개량해서 올림

#include <iostream>
#include <io.h>
#include <vector>
#include <tchar.h>
#include <string>
using namespace std;
using std::string;
using std::wstring;
#ifdef UNICODE
typedef wstring tstring;
#else
typedef string tstring;
#endif

// Check windows
#if _WIN32 || _WIN64
#if _WIN64
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif

// Check GCC
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif

#if defined(UNICODE) || defined(_UNICODE)
#define tcout std::wcout
#else
#define tcout std::cout
#endif

#ifdef ENVIRONMENT32
#define T_FIND_DATA _tfinddata_t
#define T_FIND_FIRST _tfindfirst
#define T_FIND_NEXT _tfindnext
#endif
#ifdef ENVIRONMENT64
#define T_FIND_DATA _tfinddata64_t
#define T_FIND_FIRST _tfindfirst64
#define T_FIND_NEXT _tfindnext64
#endif

vector<tstring> GetFilesInDirectory(const tstring& _absolutePath, const tstring& _filter)
{
	tstring searching = _absolutePath + _filter;
	vector<tstring> return_;

	T_FIND_DATA fd;
	const auto handle = T_FIND_FIRST(searching.c_str(), &fd);  //현재 폴더 내 모든 파일을 찾는다.

	if (handle == -1)
		return return_;

	auto result = 0;
	do
	{
		if (fd.attrib & _A_SUBDIR) { // 디렉토리면
			tstring dirName = fd.name;
			if (_T(".") != dirName && _T("..") != dirName) {
				tstring subPath = _absolutePath + dirName + _T("\\");
				vector<tstring> vec = GetFilesInDirectory(subPath, _filter);
				for (int i = 0; i < vec.size(); ++i)
					return_.push_back(vec[i]);
			}
		}
		else { // 파일이면
			tstring fileName = fd.name;
			return_.push_back(fileName);
		}

		result = T_FIND_NEXT(handle, &fd);
	} while (result != -1);

	_findclose(handle);

	return return_;
}

int main() {
	// 절대경로
	tstring path = _T("N:\\Project\\DirectX2019Game\\DirectX11Game\\OutputFile\\bin\\content\\texture\\");

	// 필터
	tstring filter = _T("*.*");

	vector<tstring> veclist = GetFilesInDirectory(path, filter);
	for (int i = 0; i < veclist.size(); ++i) {

		tcout << veclist[i].c_str() << _T("\n");
	}
	
	return 0;
}

구조체의 메모리 크기(12byte)가 배열의 크기(12byte)와 같다면 float*타입으로 캐스팅하여 구조체 변수의 주소값을 넘겨주기만 하면 된다.

 

출력 결과

 

DirectX11를 이용하여 게임 엔진을 만들면서 프로젝트가 커질수록 빌드속도가 느려진다.

빌드속도를 더 빠르게 높여주도록 개선해보자.

 

2019버전에서 Unity 빌드를 제공해준다. 

Unity 빌드를 사용하면 더 빠르게 빌드 할 수 있다.

 

설정하는 방법

 

Unity(JUMBO) 빌드 사용을 "예"로 설정한다.

 

예로 설정하게되면 C/C++에서 Unity 빌드가 나타나게 되는데 아래 사진과 같이 설정한다.

Unity 파일의 최대 소스 수를 0으로 설정하면 알아서 파일 개수가 설정 됨.

미리 컴파일된 헤더를 사용으로 설정한다.

 

 

다중 프로세서 컴파일을 "예"로 설정한다.

 

빌드하게되면 아래와 같은 파일이 생성된다.

 

 

Tip : 한글로 된 경로가 있을 경우 에러가 나서 제대로 작동 안함.

 

Astar 알고리즘 시뮬레이션

 

youtu.be/en0QjTzjSd8

 

소스 코드

github.com/gkagm2/cpppractise/blob/master/cpptraining/ch1/Algorithm/AStar/AStar.cpp

 

gkagm2/cpppractise

:orange_book:C++ 연습용, 연구용, 토이 프로그램들을 담은 프로젝트:orange_book: - gkagm2/cpppractise

github.com

 

'게임 개발 > WinApi' 카테고리의 다른 글

WinAPI 2D 총게임 소스코드  (0) 2019.10.23
WinAPI 싱글톤 Singleton  (0) 2019.10.23
WinApi  (0) 2019.10.09
메서드 설명 참고
복제 생성자 원본과 같은 복제 항목을 만든다. 원본에 아무런 영향 없이 복제 항목이 소멸도리 수 있다. 항목을 삽일할 때마다 매번 호출된다. 단, 즉성(emplace) 메서드는 예외다.
이동 생성자 원본 항목의 내용물을 이동시킴으로써 새로운 항목을 만든다. 새로운 항목을 생성한 후 원본 항목(우측값)이 소멸할 때 이용된다. 또한 예를 들어 vector의 크기가 커질 때 이용된다.
대입 연산자 원본 항목의 복제를 통해 기존 항목의 내용물을 대체한다. 항목을 수정할 때마다 사용된다.
이동 대입 연산자 원본 항목의 내용물을 다른 항목으로 이동 시킨다. 대입 연산 후 원본 항목(우측값)이 소멸할 때 이용된다.
소멸자 항목을 삭제한다. 컨테이너에서 항목을 제거할 때마다 호출된다. 예를 들어 vector의 크기가 커지고 항목이 이동 시맨틱을 지원하지 않을 때 호출된다.
디폴트 생성자 아무런 인자 없이 항목을 생성한다. 인자 하나짜리 vector::resize() 메서도를 호출하거나 map의 operator[]를 이용할 때와 같이 특별한 경우에만 필요하다.
operator== 두 항목이 같은지 비교한다. 비순차 컨테이너에 저장된 키 간에 operator==과 같은 특별한 연산이 수행될 때만 필요하다.
operator< 두 항목의 값의 크기를 비교한다. 연관 컨테이너에 사용되는 키 값은 이 연산자가 지원되어야 한다. 컨테이너 간에 operator<가 사용될 때도 쓰인다.

전문가를 위한 cpp 참고.

여러가지 상황에서 사용되는 캐스팅 방법 정리

상황 캐스팅 방법
const 속성 제거 const_cast
int, double 간 변환처럼 언어 자체에서 허용되는 변환을 명시적으로 수행 static_cast
커스텀 생성자나 변환 연산자가 구현되어 있을 때의 명시적인 변환 static_cast
전혀 관계없는 두 객체 간의 변환 불가능
같은 클래스 계층에 속하는 서로 다른 클래스 객체의 포인터 간 변환 dynamic_cast(권장) 또는 static_cast
같은 클래스 계층에 속하는 서로 다른 클래스 객체의 참조 간 변환 dynamic_cast(권장) 또는 static_cast
전혀 관계없는 두 포인터 간의 변환 reinterpret_cast
전혀 관계없는 두 참조 간의 변환 reinterpret_cast
함수 포인터 간의 변환 reinterpret_cast

 

알고리즘 문제를 풀면서 한번쯤은 구현해봤을 만한 알고리즘들이 STL에 있다.

 

 

<algorithm> 헤더 파일에서 해당 알고리즘들을 정의한다.

 

불변 알고리즘

불면 알고리즘은 항목의 나열을 대상으로 하여 항목의 어떤 정보를 리턴하거나 항목마다 특정 함수를 실행한다. 불변 알고리즘이므로 주어진 데이터 항목의 값이나 순서에 어떠한 변경도 가해지지 않는다. 불변 알고리즘에는 다음 표와 같이 세 가지 타입의 알고리즘이 있다. 이 알고리즘을 이용하면 컨테이너의 항목에 for 루프를 직접 사용할 일이 매우 드물 것이다.

 

검색 알고리즘

이 알고리즘들은 입력 값이 정렬되어 있지 않아도 이용할 수 있다.

알고리즘 이름 알고리즘 개요 복잡도(성능)
adjacent_find() 주어진 값이 조건에 연속적으로 합치되는 인접한 두 항목을 찾는다. 선형
find()
find_if()
주어진 값과 동일하거나, 주어진 조건이 true가 되는 첫 번째 항목을 찾는다. 선형
find_first_of() find()와 같으나 동시에 여러 항목을 찾는다. 제곱
find_if_not() 주어진 조건이 false가 되는 첫 번째 항목을 찾는다. 선형
search()
find_end()
주어진 나열 값 또는 주어진 조건과 합치되는 첫 번째(search())또는 마지막(find_end())부분열을 찾는다. 즉, 전체 대상 리스트에서 조건에 맞는 서브 리스트를 찾는다. 제고
search_n() 주어진 값이나 주어진 조건에 첫 번째로 n번 연속 합치되는 항목들을 찾는다. 선형

 

비교 알고리즘

대상 항목열이 정렬된 상태일 필요는 없고 선형의 실행 시간 복잡도를 가진다.

알고리즘 이름 알고리즘 개요
equal() 주어진 두 항목열에서 병렬적으로 동일 순서 위치의 항목쌍들이 모두 값이 같거나 주어진 조건에 합치하는지 검사한다.
mismatch() 주어진 두 항목열에서 병렬적으로 동일 순서 위치의 항목쌍들 중 값이 일치하지 않는 첫 번째 위치를 리턴한다.
lexicographical_comapre() 주어진 두 항목열을 사전순에 맞춰 비교한다. 즉, 두 항목열에서 병렬적으로 동일 순서 위치의 항목쌍들을 시작 지점부터 차례대로 비교하여 서로 값이 다른 항목쌍이 있을 때 두 값의 사전적 순서를 결과로 리턴한다.

 

유틸리티 알고리즘

알고리즘 이름 알고리즘 개요
all_of() 항목열이 비어 있거나 주어진 조건을 모든 항목이 만족하면 true를 리턴하고 그 외의 경우에는 false를 리턴한다.
any_of() 항목열이 비어 있거나 주어진 조건을 모든 항목이 만족시키지 못하면 false를 리턴하고 그 외의 경우에는 true를 리턴한다.
none_of() 항목열이 비어 있거나 주어진 조건을 모든 항목이 만족시키지 못하면 true를 리턴하고 그 외의 경우에는 false를 리턴한다.
count()
count_if()
주어진 값 또는 주어진 조건에 합치되는 항목의 개수를 센다.

 

변경 순차 알고리즘

변경 알고리즘은 대상 항목열의 일부 또는 전체에 변경을 가한다. 어떤 경우에는 항목을 그 자리에서 바로 변경하기 때문에 원본 항목열이 변경된다. 다른 경우에는 원본 항목열에서 일부분을 다른 항목열로 복사하여 원본은 변경되지 않는다. 모드 최악 조건 실행 시간 성능이 선형 복잡도를 가진다.

 

변경 알고리즘

알고리즘 이름 알고리즘 개요
copy()
copy_backward()
원본 항목열에서 대상 항목열로 항목들을 복제한다.
copy_if() 주어진 조건에 대해 참인 항목을 다른 항목열로 복제한다.
copy_n() n개의 항목을 다른 항목열로 복제한다.
fill() 모든 항목을 새로운 값으로 세팅한다.
fill_n() 첫 n개 항목을 새로운 값으로 세팅한다.
generate() 주어진 생성 함수를 모든 항목에 적용하여 생성 함수의 결과값으로 값을 세팅한다.
generate_n() 주어진 생성 함수를 첫 n개 항목에 적용하여 생성 함수의 결과값으로 값을 세팅한다.
move()
move_backward()
항목들을 다른 항목열로 이동시킨다. 이때 이동 시맨틱을 따른다.
remove()
remove_if()
remove_copy()
remove_copy_if()
주어진 값과 동일하거나 주어진 조건에 합치되는 항목을 제거한다. 또는 동시에 다른 항목열로 복제한다(copy 버전).
reverse()
reverse_copy()
항목열의 각 항목의 순서를 그 자리에서 거꾸로 만들거나(reverse()), 새로운 항목열에 거꾸로 된 항목열을 복사한다(reverse_copy()).
rotate()
rotate_copy()
항목열을 주어진 항목 개수만큼 그 자리에서 회전시키거나(rotate()), 회전된 항목열을 새로운 항목열에 복사한다(예:1,2,3,4,5 -> +2만큼 회전 -> 3,4,5,1,2).
shuffle()
random_shuffle()
항목들의 순서를 무작위로 뒤섞는다. 사용할 난수 생성기의 속성을 조정할 수도 있다.
random_shuffle()은 C++14부터 사용 중단 안내되었다.
transform() 한 개 항목열에 대해 각 항목마다 단항 함수를 호출하거나, 두 개 항목열의 병렬적인 항목쌍에 대해 이항 함수를 호출한다.
unique()
unique_copy()
항목열에서 연속적으로 중복되는 항목을 그 자리에서 제거하거나(unique()), 중복 항목이 제거된 항목열을 새로운 항목열로 복제한다(unique_copy()).

 

작업 알고리즘

알고리즘 이름 알고리즘 개요
for_each() 항목열의 각 항목마다 특정 함수를 실행한다. 대상 항목열은 정렬된 상태일 필요가 없고 선형 실행 시간 복잡도를 가진다.

 

교환 알고리즘

알고리즘 이름 알고리즘 개요
iter_swap()
swap_ranges()
두 항목(iter_swap) 또는 두 항목열(swap_ranges)을 서로 교환한다.
swap() 주어진 두 변수의 값을 교환한다. <utility> 헤더 파일에 정의

 

분할 알고리즘

알고리즘 이름 알고리즘 개요 복잡도(성능)
is_partitioned() 항목을 구분하는 프레디킷(predicate) 함수가 섞임 없이 연속된 true와 연속된 false를 리턴하면 true를 리턴한다. 선형
partition() 프레디킷 함수가 true를 리턴하는 항목을 앞으로 보내고 false를 리턴하는 항목을 뒤로 보낸다. 이때 원래 항목 간 순서는 보존되지 않는다. 선형
stable_partition() 프레디킷 함수가 true를 리턴하는 항목을 앞으로 보내고 false를 리턴하는 항목을 뒤로 보내되 원래의 항목 간 순서가 지켜지도록 한다. t선형로그
partition_copy() 원본 항목열을 두 개의 다른 항목열로 복제한다. 이때 복제되는 항목들은 프레디킷 함수의 true 또는 false 리턴에 의해 결정된다. 선형
partition_point() 주어진 조건에 합치되는 항목을 앞에 두고 불합치되는 항목을 뒤에 두는 반복자를 리턴한다. 다시 말해, 주어진 조건에 맞는 항목과 맞지 않는 항목을 양쪽으로 나누어 그 경계를 인덱스로 가진 반복자를 리턴한다. 로그

 

정렬 알고리즘

알고리즘 이름 알고리즘 개요 복잡도(성능)
is_sorted()
is_sorted_until()
항목열 전체(is_sorted()) 또는 일부분(is_sorted_until())이 정렬된 상태인지 검사한다. 선형
nth_element() n번째 항목만 전체 정렬 시 위치할 곳으로 이동시킨다. n번째 항목 앞에는 n번째 항목보다 빠른 항목들이, 뒤에는 느린 항목들이 위치하나 정렬된 상태는 아니다. 선형
partial_sort() 항목열의 처음 n개 항목만 정렬하고 나머지는 그대로 둔다. 원본에서 바로 정렬될 수도 있고(partial_sort()), 정렬 결과를 다른 항목열에 복제할 수도 있다(partial_sort_copy()). 선형로그
sort()
stable_sort()
원본에서 바로 정렬한다. 동일 항목은 순서가 바뀔 수도 있고(sort()), 순서가 유지될 수도 있다(stable_sort()). 선형로그

 

이진 탐색 알고리즘

대상 항목열이 최소한 찾고자 하는 항목을 기준으로 분할되어 있을 것을 요구한다. 예를 들어 str::partition()을 이용해서 충족시킬 수도 있고 전체 항목열을 정렬해서 충족시킬 수도 있다. 모두 로그 시간 성능을 가진다.

알고리즘 이름 알고리즘 개요
lower_bound()
upper_bound()
equal_range()
주어진 항목 값을 기준으로 가장 극단 항목을 찾는다. lower_bound()는 시작 항목, upper_bound()는 마지막 항목, equal_range()는 양 끝단 항목을 찾는다.
binary_search() 정렬된 항목에서 이진 탐색으로 값을 찾는다.

 

집합 알고리즘

set 컨테이너에 적용할 때 가장 적합하지만 대부분의 정렬된 컨테이너에도 적용할 수 있다. 모든 알고리즘은 선형의 최악 실행 시간을 가진다.

알고리즘 이름 알고리즘 개요 복잡도(성능)
inplace_merge() 두 정렬된 항목열을 둘 중 한 항목열에 바로 병합한다. 선형로그
merge() 두 정렬된 항목열을 새로운 항목열로 복제하면서 병합한다. 선형
includes() 어떤 항목열이 다른 항목열에 완전히 속하는지 검사한다. 선형
set_union()
set_intersection()
set_difference()
set_symmetric_difference()
두 개의 정렬된 항목열을 대상으로 합집합(union()), 교집합(intersection()), 차집합(difference()), 대칭차집합(symmetric_difference())을 수행하고 그 결과를 다른 항목열에 복제한다. 선형

 

힙 알고리즘

배열이나 항목열의 항목들이 최댓값(또는 최소값)을 매우 빠르게 찾는데 유리한 구조를 갖추고 있다. 다음 알고리즘은 힙을 대상으로 작동한다.

알고리즘 이름 알고리즘 개요 복잡도(성능)
is_heap() 주어진 범위의 항목들이 힙을 만족하는지 검사한다. 선형
is_heap_until() 주어진 범위의 항목들 중에서 힙을 만족하는 가장 큰 부분 범위를 찾는다. 선형
make_heap() 주어진 범위의 항목들을 이용하여 힙을 만든다. 선형
push_heap() 힙에 항목을 추가 또는 삭제한다. 선형로그
sort_heap() 힙을 오름차순으로 정렬된 항목열로 변환한다. 선형로그

 

최대/최소 알고리즘

알고리즘 이름 알고리즘 개요
min()
max()
주어진 2개 이상의 값 중에서 최솟값 또는 최댓값을 리턴한다.
minmax() 주어진 2개 이상의 값 중에서 최솟값과 최댓값을 찾고 그 둘을 묶어서 pair 타입으로 리턴한다.
min_element()
max_element()
최솟값 항목(min_element()) 또는 최댓값 항목(max_element())을 찾는다.
minmax_element() 최솟값 항목과 최댓값 항목을 찾고 그 둘을 묶어서 pair 타입으로 리턴한다.

 

수치 처리 알고리즘

<numeric> 헤더 파일에 정의되어 있다. 대상 항목열이 정렬된 상태일 필요는 없으며 선형 실행 시간을 가진다.

알고리즘 이름 알고리즘 개요
accumulate() 항목열의 모든 값을 누적한다. 디폴트 동작은 모든 항목에 대한 덧셈이지만, 함수 호출 측에서 다른 종류의 이항 함수(binary function, 인자가 두 개인 함수)를 지정할 수도 있다.
adjacent_difference() 주어진 범위의 부분열 a0, a1, ..., aN에 대해 a0, a1-a0, a2-a1, ... ,aN-a(N-1)을 결과열로 출력한다. 마찬가지로 디폴트인 뺄셈 대신 다른 이항 함수를 지정할 수도 있다.
inner_product() accumulate()와 유사하나 두 개의 항목열을 대상으로 하는 것이 다르다. 두 열 각각에서 하나씩 병렬적으로 취한 항목 쌍을 대상으로 이항 함수(디폴트는 곱셈)를 호출한 다음 그 결과값을 또 다른 이상 함수를 통해 누적(디폴트는 덧셈)한다. 만약 두 열이 수학의 벡터를 의미할 경우 전체 결과값은 벡터의 내적과 동일한다.
iota() 주어진 초기값을 각 항목에 대입하되 숫차적으로 대입할 때마다 값을 증가시킨다.
partial_sum() 주어진 범위의 부분열 a0, a1, ... aN에 대해 a0+a1, a0+a1+a2, ... ,a0+...+aN을 결과열로 출력한다. 이때 디폴트인 덧셈 대신 다른 이항 함수를 지정할 수도 있다.

 

순열 알고리즘

알고리즘 이름 알고리즘 개요 복잡도(성능)
is_permutation() 항목열이 다른 항목의 순열이면 true를 리턴한다. 제곱
next_permutation()
prev_permutation()
주어진 항목열을 사전순에 따라서, 그 항목들로 생성 가능한 다음 순열 조합(next_permutation()) 또는 이전 순열 조합(prev_permutation())에 맞추어 항목열의 순서를 변환한다(예를 들어 1, 2, 3은 3!개의 순열 조합 경우의 수가 있고, 1, 2, 3 다음의 순열 조합은 1, 3, 2가 될 수 있다).
올바르게 정렬된 상태에서 연속해서 next_permutation과 prev_permutation을 호출하면 모든 가능한 순열을 완전 탐색할 수 있다. 더 이상 탐색할 조합이 없으면 false를 리턴한다.
선형

 

 

(불변)

- STL은 컨테이너에 복수의 스레드가 접근할 때 스레드 안정성을 보증하지 않는다.

- STL은 제네릭 트리 또는 제네릭 그래프 데이터 구조를 지원하지 않는다. 비록 map과 set이 균형 이진트리로 구현되었지만 그 내부 구현이 인터페이스로 드러나 있지는 않다. 만약 파서 등의 구현을 위해 트리나 그래프 데이터 구조가 필요하다면 직접 해당 데이터 구조를 구현하거나 다른 라이브러리를 찾아봐야 한다.

 

 

 

이 내용의 출처 - 전문가를 위한 CPP (마크 그레고리)

+ Recent posts