오늘의 코드카타
2차원 동전 뒤집기
- XOR + 브루트포스(dfs)
- LV3 - 27% (복습 필요)
-> 문제 풀이
오늘의 공부
팀 프로젝트 진행 내용
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);
}
}
BTTask_ActivateAbility 구현
- Behavior Tree에서 Ability를 활성화시켜 줄 태스크 노드 생성
TSubclassOf<UGameplayAbility>를 통해 Ability를 받아서 AI의 ASC에서 실행

- 공격 받는 상태를 추가해서 공격 받는 Ability 생성
EAIState::Angry 추가
AI_AngryAbility 구현
- Behavior Tree에 Angry 상태 추가

오늘의 CS
std::list
- 개념
- 이중 연결 리스트(Doubly Linked List)로 구현된 컨테이너
- 원소들이 연속된 메모리에 저장되지 않고, 각각 노드 단위로 따로따로 할당됨
- 각 노드는 데이터 + 이전 노드 포인터 + 다음 노드 포인터를 가짐
- 특징
- 메모리 구조
vector는 배열 기반 -> 메모리 연속적
list는 노드 기반 -> 불연속적 (메모리 locality가 떨어짐)
- 시간 복잡도
- 임의 원소 접근 불가능
- 앞/뒤 삽입·삭제 : O(1) (
push_front, push_back, pop_front, pop_back)
- 중간 삽입·삭제 : O(1) (iterator 이용)
- 탐색 : O(n) (
find)
- 특수 연산
splice() -> 두 리스트 간 노드 이동 (O(1))
merge() -> 정렬된 두 리스트 병합
remove() -> 특정 값 제거
unique() -> 중복 원소 제거
sort() -> 자체 정렬 알고리즘 제공
- 안정된 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)
- 연결 리스트에서 병합 정렬을 하면 불필요한 복사/이동이 일어나지 않기 때문에 좋음