본문 바로가기
프로그래밍/Unreal 부트캠프

TIL 2025.02.26 기록

by Rozentea 2025. 2. 26.

0. 개요


오늘은 챌린지 반 수업을 듣고, Octree 길 찾기에 문제점이 있어서 조금 수정했다.

그리고 지금은 그래플링을 만들어 보는 중인데.. 진짜진짜 쉽지 않은 것 같다.. ㅠ

그래도 내일까지 작업을 최대한 마무리를 해보려 한다.

그래야 금요일에는 드론이 몬스터를 공격하는 AI 행동을 구현할 수 있을 것 같다.

 

1. 알고리즘 수업


< 문제 1 >

Q. 이미 정렬된 두 정수형 배열 arr1과 arr2가 주어졌을 때, 두 배열에 공통으로 존재하는 원소만을 포함하는 배열을 반환하는 solution() 함수를 구현하시오.

제약 조건
1. arr1 과 arr2는 각각 길이가 1 이상 100,000 이하이다.
2. arr1 과 arr2는 오름차순으로 정렬되어 있다.
3. 결과 배열도 오름차순으로 정렬되어 있어야 한다.

입출력 예시
arr1 = [1, 2, 4, 5, 7]
arr2 = [2, 3, 5, 6]
결과: [2, 5]​
#include <algorithm>
#include <vector>
#include <set>

using namespace std;

int main()
{
	vector<int> arr1 = { 1, 2, 4, 5, 7 };
	vector<int> arr2 = { 2, 3, 5, 6 };
	vector<int> answer;

// 시도 1.
	for (int i = 0; i < arr1.size(); ++i)
	{
		for (int j = 0; j < arr2.size(); ++j)
		{
			if (arr1[i] == arr2[j])
			{
				answer.push_back(arr1[i]);
				return;
			}
		}
	}

// 시도 2.
	set<int> set1;
	for (int i = 0; i < arr1.size(); ++i)
	{
		set1.insert(arr1[i]);
	}

	for (int j = 0; j < arr2.size(); ++j)
	{
		if (set1.find(arr2[j]) != set1.end())
		{
			answer.push_back(arr2[j]);
		}
	}

	return 0;
}

투포인터가 떠올랐지만.. 투 포인터로 어떻게 해야할지.. 잘 안풀려서 우선 2중 반복으로 해보고, set으로도 해보았다..

 

< 문제 2 >

Q. 정수n이 주어졌을 때, 각 자릿수를 오름차순으로 정렬하여 새로운 정수를 반환하는 solution() 함수를 구현하시오.

제약 조건
1. n은 1 이상 8,000,000,000 이하인 자연수이다.

입출력 예시
n = 873211
결과: 112378​
#include <algorithm>
#include <string>

using namespace std;

int main()
{
	int n = 8732112;

	string num = to_string(n);
	sort(num.begin(), num.end(), less<>());

	n = stoi(num);

	return 0;
}

정답도 방법 자체는 똑같았던 것 같다.

다만, stoll을 사용하는게 맞았는데, 제약 조건이 굉장히 큰 자연수이기 때문에 int가 아닌 longlong을 사용해야 맞다.. ㅠ

 

< 문제 3 >

Q. 문자열로 구성된 배열 strings와 문자 c가 주어졌을 때, c를 포함하는 문자열만 추려서 오름차순으로 정렬한 결과를 반환하는 solution()함수를 구현하시오.

제약 조건
1. string는 길이가 1 이상 50 이하인 벡터이다.
2. 각 문자열은 소문자 알파벳으로 이루어져 있다.
3. 각 문자열의 길이는 1 이상 100 이하이다.

입출력 예시
strings = ["apple", "banana", "cherry", "date"]
c = 'a'
결과: ["apple", "banana", "date"]​
#include <algorithm>
#include <vector>
#include <string>

using namespace std;

int main()
{
	vector<string> strings = { "apple", "banana", "cherry", "date" };
	char c = 'a';
	vector<string> answer;

	for (int i = 0; i < strings.size(); ++i)
	{
		if (strings[i].find(c) != string::npos)
		{
			answer.push_back(strings[i]);
		}
	}

	sort(answer.begin(), answer.end(), less<>());

	return 0;
}

set을 사용하면, 넣어줄 때 자동으로 정렬되니까 이걸 이용하신 분도 계셨다.

 

< 문제 4 >

Q. 정수 배열 arr이 주어졌을 때, 연속된 숫자들이 가장 길게 이어지는 구간의 길이를 구하는 solution()함수를 구현하시오.

제약 조건
1. arr의 길이는 1 이상 100,000 이하이다.
2. arr의 각 원소는 1 이상 1,000,000 이하의 정수이다.

입출력 예시
arr = [100, 4, 200, 1, 3, 2]
결과: 4  (1, 2, 3, 4가 연속됨)​
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
	vector<int> arr = { 100, 4, 200, 1, 3, 2, 5 };

	sort(arr.begin(), arr.end(), less<>());

	int answer = 0;
	int dist = 0;
	for (int i = 1; i < arr.size(); ++i)
	{
		if (arr[i - 1] + 1 == arr[i])
		{
			dist++;
			if (answer < dist)
			{
				answer = dist;
			}
		}
		else
		{
			dist = 0;
		}
	}

	answer += 1;

	return 0;
}

중복을 고려해야 했는데, 고려하지 않고 풀었다.. ㅠ

또, answer += 1을 무조건 하는데 이 경우 틀릴 가능성이 있는게, 답이 0일 경우에는 1이 나와버려 문제가 될 수 있을 것 같다.. 이 외에도 문제가 많을 수도 있는 것 같아서.. 좀 더 공부를 해야할 것 같다는 생각이 들었다.

 

2. 팀 프로젝트 ( Octree 수정하기 )


< 주변 노드 탐색 함수 구현하기 & UBTTask_MoveToCommand 로직 변경하기 >

NavNode* AAOctreeVolume::FindNearestValidNode(const FVector& location, const TArray<TEnumAsByte<EObjectTypeQuery>>& object_types, UClass* actor_class_filter)
{
	const FIntVector center = ConvertLocationToCoordinates(location);
	const int32 searchRadius = 5; // 탐색 반경 (필요에 따라 조절)

	NavNode* nearestNode = nullptr;
	float nearestDistance = FLT_MAX;

	for (int32 x = -searchRadius; x <= searchRadius; x++)
	{
		for (int32 y = -searchRadius; y <= searchRadius; y++)
		{
			for (int32 z = -searchRadius; z <= searchRadius; z++)
			{
				FIntVector offset = FIntVector(x, y, z);
				NavNode* node = GetNode(center + offset);

				if (node && IsValidDestLocation(ConvertCoordinatesToLocation(node->Coordinates), object_types, actor_class_filter))
				{
					float distance = FVector::Distance(location, ConvertCoordinatesToLocation(node->Coordinates));
					if (distance < nearestDistance)
					{
						nearestNode = node;
						nearestDistance = distance;
					}
				}
			}
		}
	}

	DrawDebugSphere(GetWorld(), ConvertCoordinatesToLocation(nearestNode->Coordinates), 30, 30, FColor::Orange, false , 100.f);
	
	return nearestNode;
}

기존에 만들었던 IsValidDestLocation()를 이용해 주변 노드들이 유효한지 검사해, 주변 5만큼 거리의 노드들을 탐색해서 유효한 노드가 있다면, 그중 가장 거리가 가까운 노드를 반환해주도록 구현했다.

테스트를 위해서 디버그 드로우를 이용해 띄워도 보았다.

 

이후 기존 로직을 조금 변경해 잘 동작되도록 만들었다. ㅎㅎ

 

< UBTTask_FollowWithAvoidance 로직 변경하기 >

로직을 변경하고 테스트 해보니, UBTTask_WaitForStabilization에서 다른 행동들로 상태전환이 제대로 발생하지 않아 해당 부분도 함께 수정해주었다.

그 결과 잘 동작하는 것을 확인할 수 있었다.

 

음.. 코드가 길고 코드적인 부분이라 정리는 이렇게 글로만 간단히 작성해두겠다.

 

지금 보니 간혹 프레임 드랍이 발생하는데.. 이 부분은 잘 발생하지 않아서 계속하면서 잡아봐야겠다… ㅠㅠㅠ

'프로그래밍 > Unreal 부트캠프' 카테고리의 다른 글

TIL 2025.02.28 기록  (0) 2025.02.28
TIL 2025.02.27 기록  (0) 2025.02.27
TIL 2025.02.25 기록  (0) 2025.02.25
TIL 2025.02.24 기록  (0) 2025.02.24
TIL 2025.02.21 기록  (0) 2025.02.21