난수 생성 로직
FString ACXGameModeBase::GenerateSecretNumber()
{
TArray<int32> Numbers;
for (int32 i = 1; i <= 9; ++i)
{
Numbers.Add(i);
}
FMath::RandInit(FDateTime::Now().GetTicks());
Numbers = Numbers.FilterByPredicate([](int32 Num) {return Num > 0; });
FString Result;
for (int32 i = 0; i < 3; ++i)
{
int32 Index = FMath::RandRange(0, Numbers.Num() - 1);
Result.Append(FString::FromInt(Numbers[Index]));
Numbers.RemoveAt(Index);
}
return Result;
}
- FMath::RandInit() : 난수 생성기를 초기화하는 함수. 초기화하지 않으면 매번 같은 패턴의 난수가 형성될 수 있다.
- FDateTime::Now().GetTicks() : 현재 시스템 시간을 틱 단위로 가져오는 함수.
- FilterByPredicate : TArray의 멤버함수로, 특정 조건을 만족하는 요소만 남기고 나머지는 제거하는 역할.
- [ ](int32 Num) {return Num > 0;} : 배열의 각 숫자가 0보다 크면 true 반환하는 람다 표현
- FMath::RandRange(Min, Max) : Min과 Max 사이의 범위에서 무작위 정수를 하나 선택하는 언리얼 엔진 함수
- Numbers.Num() - 1 : Numbers 배열에 현재 남아있는 숫자의 개수에서 1을 뺀 값. 배열의 인덱스는 0부터 시작하므로, Num - 1이 마지막 인덱스가 된다.
- FString::FromInt() : int32타입의 정수를 FString 타입의 문자열로 변환해주는 함수.
- Result.Append : Result 문자열의 맨 뒤에 방금 변환된 숫자를 붙여준다.
- Numbers.RemoveAt(Index) : Numbers 배열에서 Index위치에 있는 숫자를 제거한다.
추측 숫자 로직
bool ACXGameModeBase::IsGuessNumberString(const FString& InNumberString)
{
bool bCanPlay = false;
do {
if (InNumberString.Len() != 3)
{
break;
}
bool bIsUnique = true;
TSet<TCHAR> UniqueDigits;
for (TCHAR C : InNumberString)
{
if (FChar::IsDigit(C) == false || C == '0')
{
bIsUnique = false;
break;
}
UniqueDigits.Add(C);
}
if (bIsUnique == false)
{
break;
}
bCanPlay = true;
} while (false);
return bCanPlay;
}
숫자 계산 로직
FString ACXGameModeBase::JudgeResult(const FString& InSecretNumberString, const FString& InGuessNumberString)
{
int32 StrikeCount = 0, BallCount = 0;
for (int32 i = 0; i < 3; ++i)
{
if (InSecretNumberString[i] == InGuessNumberString[i])
{
StrikeCount++;
}
else
{
FString PlayerGuessChar = FString::Printf(TEXT("%c"), InGuessNumberString[i]);
if (InSecretNumberString.Contains(PlayerGuessChar))
{
BallCount++;
}
}
}
if (StrikeCount == 0 && BallCount == 0)
{
return TEXT("OUT");
}
return FString::Printf(TEXT("%dS%dB"), StrikeCount, BallCount);
}