09.12 - TIL

김혁·2025년 9월 12일

TIL

목록 보기
17/84

오늘의 코드카타

2차원 동전 뒤집기

  • XOR + 브루트포스(dfs)
  • LV3 - 27% (복습 필요)
    -> 문제 풀이

오늘의 공부

팀 프로젝트 진행 내용

  1. AI_PeckAbility, AI_LayEggAbility 구현
    • 애님 몽타주만 실행시켜주는 어빌리티 생성
    • UAbilityTask_PlayMontageAndWait를 통해 몽타주 실행
      • OnCompleted, OnInterrupted, OnCancelled 상태에 EndAbility() 바인딩
    • 주의할 점
      • 애님 몽타주를 시켜주는 것이니 AnimInstance를 미리 설정해야 함
      • 다른 몽타주가 실행되고 있으면 실패할 수 있음
// EGAI_PeckAbility.cpp

void UEGAI_PeckAbility::ActivateAbility(...)
{
	...

	MontageTask = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(this, NAME_None, PeckMontage);
	if (MontageTask)
	{
		MontageTask->OnCompleted.AddDynamic(this, &ThisClass::OnMontageFinished);
		MontageTask->OnInterrupted.AddDynamic(this, &ThisClass::OnMontageFinished);
		MontageTask->OnCancelled.AddDynamic(this, &ThisClass::OnMontageFinished);
		MontageTask->ReadyForActivation();
	}
	else
	{
		EndAbility(Handle, ActorInfo, ActivationInfo, true, true);
	}
}
  1. BTTask_ActivateAbility 구현
    • Behavior Tree에서 Ability를 활성화시켜 줄 태스크 노드 생성
    • TSubclassOf<UGameplayAbility>를 통해 Ability를 받아서 AI의 ASC에서 실행
  2. 공격 받는 상태를 추가해서 공격 받는 Ability 생성
    • EAIState::Angry 추가
    • AI_AngryAbility 구현
      • 애님 몽타주만 실행시켜주는 어빌리티 생성
    • Behavior Tree에 Angry 상태 추가

오늘의 CS

std::list

  • 개념
    • 이중 연결 리스트(Doubly Linked List)로 구현된 컨테이너
    • 원소들이 연속된 메모리에 저장되지 않고, 각각 노드 단위로 따로따로 할당됨
    • 각 노드는 데이터 + 이전 노드 포인터 + 다음 노드 포인터를 가짐
  • 특징
    1. 메모리 구조
      • vector는 배열 기반 -> 메모리 연속적
      • list는 노드 기반 -> 불연속적 (메모리 locality가 떨어짐)
    2. 시간 복잡도
      • 임의 원소 접근 불가능
      • 앞/뒤 삽입·삭제 : O(1) (push_front, push_back, pop_front, pop_back)
      • 중간 삽입·삭제 : O(1) (iterator 이용)
      • 탐색 : O(n) (find)
    3. 특수 연산
      • splice() -> 두 리스트 간 노드 이동 (O(1))
      • merge() -> 정렬된 두 리스트 병합
      • remove() -> 특정 값 제거
      • unique() -> 중복 원소 제거
      • sort() -> 자체 정렬 알고리즘 제공
    4. 안정된 iterator
      • list는 노드 기반이라, 해당 노드를 직접 삭제하지 않는다면 다른 iterator는 무효화되지 않음
  • 유리한 경우
    • 중간 위치에 원소의 삽입/삭제가 자주 발생하는 경우
    • 원소 개수가 많고, 정렬·병합 같은 작업이 필요한 경우
  • 불리한 경우
    • 임의 접근이 자주 필요한 경우 -> vector가 더 적합
    • 캐시 효율이 중요한 경우 -> list는 메모리 locality가 떨어져 성능이 나쁨


list::sort 정렬 함수가 별도로 존재하는 이유

std::sort (algorithm)

  • 내부적으로 예전에는 퀵소트(quick sort)였으나, 요즘은 인트로소트(intro sort) 사용
  • Random Access Iterator를 지원하는 컨테이너에서만 사용 가능

intro sort

  • 평균적으로 빠른 성능을 내면서 최악의 조건에서도 점진적으로 최적화된 성능을 제공하는 하이브리드 정렬 알고리즘
  • 조건에 따라 퀵 정렬, 힙 정렬, 삽입 정렬로 선택해서 3가지 알고리즘의 좋은 부분만 채택하는 정렬

list::sort

  • list가 Bidirectional Iterator만 제공 -> 임의 접근이 불가능하기 때문에 사용 불가능
  • 내부 구현은 병합 정렬(Merge Sort) 기반
  • 시간 복잡도 : O(N*logN)
  • 연결 리스트에서 병합 정렬을 하면 불필요한 복사/이동이 일어나지 않기 때문에 좋음
profile
게임 개발자를 향해..

0개의 댓글