개념: while문의 기본 구조와 증감식(i++) 위치에 따른 결과 차이를 익힙니다.
i가 0부터 시작하여 i < 5인 동안i가 0부터 시작하여 i < 10인 동안i의 값을 출력하고 1씩 증가시키는 코드를 쓰세요.i가 0부터 시작하여 i < 5인 동안,i를 출력한 뒤 i++를 하는 코드를 쓰세요.i가 0부터 시작하여 i < 5인 동안,i++를 실행한 뒤 i를 출력하는 코드를 쓰세요.i가 1부터 시작하여 i <= 5인 동안 현재 i의 값을 출력하고1씩 증가시키는 코드를 쓰세요.i가 1부터 시작하여 i < 10인 동안i를 2씩 증가시키는 코드를 쓰세요.i가 5부터 시작하여 i > 0인 동안i의 값을 출력하고 1씩 감소시키는 코드를 쓰세요./*
i가 0부터 시작하여 i<5인 동안 "안녕하세요"를 출력하는 코드를 쓰세요.
*/
int i = 0;
while (i < 5) {
cout << "안녕하세요" << endl;
i++;
}
/*
0부터 시작하여 ㅑ<10인 동안 현재 i의 값을 출력하고 1씩 증가하는 코드를 쓰세요.
*/
i = 0;
while (i < 10) {
cout << i << endl;
i++;
}
/*
i가 0부터 시작하여 i<5인 동안, 먼저 i를 출력한 뒤 i++를 하는 코드를 쓰세요
*/
i = 0;
while (i < 5) {
cout << i<< endl;
i++;
}
/*
i가 0부터 시작하여 i<5인 동안, 먼저 i++를 실행한 뒤 i를 출력하는 코드를 쓰세요
*/
i = 0;
while (i < 5) {
i++;
cout << i << endl;
}
/*
i가 1부터 시작하여 i<=5인 동안 현재 i의 값을 출력하고 1씩 증가하는 코드를 쓰세요
*/
i = 1;
while (i <= 5) {
cout << i << endl;
i++;
}
/*i가 1부터 시작하여 i<10인 동안 홀수만 출력하도록 i를 2씩 증가시키는 코드를 쓰세요*/
i = 1;
while (i < 10) {
if (i % 2 != 0) {
cout << i << endl;
}
i += 2;
}
/*
i가 5부터 시작하여 i>0인 동안 현재 i의 값을 출력하고 1씩 감소시키는 코드를 쓰세요
*/
i = 5;
while (i > 0) {
cout<<i<<endl;
i--;
}
개념: 숫자 카운트가 아닌 boolean 변수의 상태에 따라 루프를 켜고 끄는 법을 익힙니다.
bool isRunning = true일 때,isRunning이 참인 동안 "가동 중"을 출력하고isRunning을 false로 바꾸는 코드를 쓰세요.int energy = 3일 때,energy > 0인 동안 "에너지 출력"을 하고energy를 1씩 줄이되,energy가 0이 되면boolean isActive를 false로 만드는 코드를 쓰세요.boolean isFound = false일 때,!isFound인 동안 "찾는 중..."을 출력하고isFound를 true로 변경하여 멈추는 코드를 쓰세요.int count = 0이고 boolean keepGoing = true일 때,keepGoing이 참인 동안 count를 증가시키고,count가 3이 되면 keepGoing을 false로 바꾸는 코드를 쓰세요. boolean powerOn = true일 때, powerOn인 동안 "전원 켜짐"을 한 번 출력하고 바로 powerOn을 false로 처리하는 코드를 쓰세요. /*
bool isRunning = true일 때 isRunning이 참인 동안 가동중을 출력하고 isRunning을 false로 바꾸는 코드를 쓰세요
*/
bool isRunning = true;
while (isRunning) {
cout << "가동중" << endl;
isRunning = false;
}
int energy = 3;
bool isActive = true;
while (energy > 0) {
cout << "에너지 출력" << endl;
energy--;
if (energy == 0) {
isActive = false;
}
}
bool isFound = false;
while (!isFound) {
cout << "찾는중..." << endl;
isFound = true;
}
int count = 0;
bool keepGoing = true;
while (keepGoing) {
count++;
if (count == 3) {
keepGoing = false;
}
}
bool powerOn = true;
while (powerOn) {
cout << "전원 켜짐" << endl;
powerOn = false;
}
//While 문으로 작성했던 코드 for문으로 전환 연습
for(int i=0; i<5; i++){
cout << "안녕하세요" << endl;
}
for (int i = 0; i < 10; i++) {
cout << i << endl;
}
for (int i = 0; i < 5; ++i) {
cout << i << endl;
}
for (int i = 1; i <=5; i++) {
cout << i << endl;
}
for (int i = 1; i < 10; i += 2) {
if (i % 2 != 0) {
cout << i << endl;
}
}
for (int i = 5; i > 0; i--) {
cout << i << endl;
}
for (bool isRunning = true; isRunning !=false; isRunning =!isRunning) {
cout << "가동 중" << endl;
}
isActive = true;
for (int energy = 3; energy >0; ) {
energy--;
cout << "에너지 출력" << endl;
if (energy == 0) {
isActive = false;
}
}
for (bool isFound=false; isFound!=true; isFound=!isFound) {
cout << "찾는중..." << endl;
}
count = 0;
for (bool keepGoing = true; keepGoing != false;) {
count++;
if (count == 3) {
keepGoing = false;
}
}
for (bool powerOn=true; powerOn!=false; powerOn =!powerOn) {
cout << "전원 켜짐" << endl;
}
개념: 단순 숫자가 아니라, 특정 상태나 값의 변화를 감지하여 반복을 멈추는 훈련입니다.
int target = 100이고 int sum = 0일 때,sum < target인 동안 sum에 20씩 더하며sum의 값을 출력하는 코드를 쓰세요.int balance = 1000일 때, balance >= 200인 동안balance에서 200씩 차감하는 코드를 쓰세요.String input = ""일 때, !input.equals("quit")인 동안input을"quit"으로 변경하여 종료하는 코드를 쓰세요. int i = 10;
do {
cout << i << endl;
i--;
} while (i < 5);
int count = 1;
do {
cout << count << endl;
count++;
} while (count <= 3);
bool isHappy = false;
do {
cout << "웃으세요" << endl;
} while (isHappy);
개념: 정해진 횟수만큼 도는 for문 도중, 특정 상황에서 즉시 멈추는 연습을 합니다.
for문을 사용하여 i가 1부터 10까지 반복하되,i가 5가 되면 break를 실행하여 루프를 탈출하는 코드를 쓰세요.for문을 사용하여 i가 1부터 100까지 반복하되,i가 7이 되는 순간 "행운의 숫자 발견"을 출력하고 즉시 멈추는 코드를 쓰세요.for문을 사용하여 1부터 10까지 숫자를 더해가다가,break하는 코드를 쓰세요. for (int i = 1; i <= 10; i++) {
if (i == 5) {
break;
}
}
for (int i = 0; i < 100; i++) {
if (i == 7) {
cout << "행운의 숫자 발견" << endl;
break;
}
}
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
if (sum > 10) {
cout << "중단" << endl;
break;
}
}
개념: while문의 조건이 항상 true인 무한 루프에서 안전하게 탈출하는 법을 익힙니다.
while(true) 무한 루프 안에서 count를 1씩 증가시키다가,count가 5가 되면 "탈출"을 출력하고 break하는 코드를 쓰세요.while(true) 루프 안에서 "작업 중..."을 출력하고,isDone이 true가 되면 break를 통해 루프를 끝내는 코드를 쓰세요.int coffee = 10일 때, while(true) 루프 안에서 coffee를 하나씩 줄이며 "커피 판매"를 출력하고, coffee가 0이 되면 "매진"을 출력한 뒤 break하는 코드를 쓰세요. count = 0;
while (true) {
count++;
if (count == 5) {
cout << "탈출" << endl;
break;
}
}
bool isDone = false;
while (true) {
cout << "작업 중..." << endl;
isDone = !isDone;
if (isDone) {
break;
}
}
int coffee = 10;
while (true) {
coffee--;
if (coffee == 0) {
cout << "매진" << endl;
break;
}
}
개념: 특정 조건에서 아래 코드를 무시하고 다음 회차(증감식)로 건너뛰는 법을 익힙니다.
for문을 사용하여 1부터 10까지 출력하되,i가 5일 때는 continue를 사용하여 출력을 건너뛰는 코드를 쓰세요. for문을 사용하여 1부터 10까지 반복하되,i % 3 == 0 (3의 배수)일 때 건너뛰기를 실행하여for문을 사용하여 1부터 5까지 반복하며, i가 짝수이면 "짝수"라고 출력하고 continue를 실행하여 숫자는 출력되지 않게 하세요. for (int i = 1; i <= 10; i++) {
if (i == 5) {
continue;
}
cout << i << endl;
}
for (int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
continue;
}
cout << i << endl;
}
for (int i = 1; i <= 5; i++) {
if (i % 2 == 0) {
cout << "짝수" << endl;
}
}
개념: while문에서 continue를 쓸 때 증감식(i++)의 위치를 조정하여 '무한 루프'를 방지하는 훈련입니다.
i가 0부터 시작합니다. while(i < 5) 루프 안에서 가장 먼저 i++를 실행하고,i가 3이면 continue로 출력을 건너뛰는 코드를 쓰세요.i가 0부터 시작하여 i < 10인 동안, i를 먼저 1 증가시킨 후i가 홀수이면 continue를 실행하여 짝수만 출력되게 하세요.int count = 0일 때, while(count < 5) 루프에서 count++를 먼저 수행하고,count가 2 또는 4인 경우 continue를 실행하는 코드를 쓰세요.i가 5부터 시작하여 i > 0인 동안, i--를 먼저 수행하고i가 2이면 continue를 실행하는 코드를 쓰세요.while(true) 무한 루프 안에서 i++를 수행하다가,i가 5의 배수이면 continue를 하고, i가 12가 되면 break로 탈출하는 코드를 쓰세요.int score = 0일 때, while(score < 100) 루프에서 score를 10씩 더하며,score가 50일 때만 "보너스 구간"을 출력하고 continue를 실행하는 코드를 쓰세요. i = 0;
while (i < 5) {
i++;
if (i == 3) {
continue;
}
}
i = 0;
while (i < 10) {
i++;
if (i % 2 != 0) {
continue;
}
cout << i << endl;
}
count = 0;
while (count < 5) {
count++;
if (count == 2 || count == 4) {
continue;
}
}
i = 5;
while (i > 0) {
i--;
if (i == 2) {
continue;
}
}
while (true) {
i++;
if (i % 5 == 0) {
continue;
}
else if (i == 12) {
break;
}
}
int score = 0;
while (score < 100) {
score += 10;
if (score == 50) {
cout << "보너스 구간\n";
continue;
}
}
개념: 반복문 안에 반복문이 있을 때, break가 '어디까지' 빠져나오는지 확인합니다.
for문이 2번(i=1~2), 내부 for문이 5번(j=1~5) 반복됩니다.j가 3이 되면 break를 실행하여 내부 루프만 빠져나오는 코드를 쓰세요.while(true) 루프 안에 for(int i=1; i<=10; i++) 루프가 있습니다.for문에서 i가 5가 되면 "시스템 종료"를 출력하고 내부 루프를 break한 뒤,while문도 멈추게 하는 코드를 쓰세요. for (int i = 1; i <= 2; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 3) {
break;
}
}
}
bool systemEnd = false;
while (true) {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
cout << "시스템 종료" << endl;
systemEnd = true;
break;
}
}
if (systemEnd) {
break;
}
}
개념: 작은 타입에서 큰 타입으로 데이터가 흐를 때, 컴퓨터가 자동으로 변환해주는 과정을 익힙니다.
int num = 10;을 선언하고,double dNum 변수에 대입하여float fNum = 3.14f;를 double dNum2에 대입하여char ch = 'A';를 int unicode 변수에 대입하여 int num = 10;
double dNum = num;
float fNum = 3.14f;
double dNum2 = fNum;
char ch = 'A';
int unicode = ch;
cout<<dNum<<", "<<dNum2<<", "<<unicode<<endl;
개념: 큰 그릇의 데이터를 작은 그릇에 강제로 담을 때 발생하는 '소수점 버림'을 집중 훈련합니다.
double pi = 3.14;를 (int)를 사용하여 정수로 강제 형 변환하고,double val = 9.99;를 int로 형 변환하여,9가 출력되는 코드를 쓰세요.float weight = 70.8f;를 int 변수에 담아 정수 부분만 남기는 코드를 쓰세요.double score = 85.5;에 (int)를 붙여 형 변환한 값과 원래 값을 각각 출력하는 코드를 쓰세요.123.456을 (int) 캐스팅을 통해 123으로 만드는 코드를 쓰세요. double pi = 3.14;
cout << (int)pi << endl;
double val = 9.99;
cout << (int)val << endl;
float weight = 70.8f;
int weightNum = weight;
double score = 85.5;
cout << score <<"," << (int)score << endl;
double point = 123.456;
cout << (int)point << endl;
개념: 서로 다른 타입이 계산될 때 큰 타입으로 맞춰지는 원리와, 정수 나눗셈의 함정을 배웁니다.
int a = 10;과 double b = 3.0;을 더한 결과를 double 변수에 담아 출력하는 코드를 쓰세요. (정수+실수=실수 확인)int x = 5; int y = 2; 일 때, x / y를 출력하세요.2.5가 아닌 2가 나오는지 확인해보세요.5 / 2.0을 계산하여 결과가 2.5가 나오게 하는 코드를 쓰세요.int kor = 80; int eng = 81; 일 때,(kor + eng) / 2.0을 계산하여 실수형 변수에 담는 코드를 쓰세요.double result = 10 / 3;의 결과를 출력해보고,3.0이 나오는지 고민한 뒤 10 / 3.0으로 수정하여 3.333...을 출력하는 코드를 쓰세요. double b = 3.0;
double result = a + b;
cout << result << endl;
int x = 5;
int y = 2;
cout << x / y << endl;
float x1 = 5;
float y1 = 2;
cout << x1 / y1 << endl;
int kor = 80;
int eng = 81;
result = (kor + eng) / 2.0;
cout << result << endl;
result = 10 / 3.0;
cout << result << endl;
개념: 변수가 담을 수 있는 최대치를 넘었을 때 숫자가 어떻게 왜곡되는지 눈으로 확인합니다.
byte b = 127; (byte의 최대치)에 1을 더하여 출력했을 때,-128이 나오는 것을 확인하는 코드를 쓰세요.int max = 2147483647; (int의 최대치)에 1을 더해 출력하여 숫자가 음수로 변하는 것을 확인하는 코드를 쓰세요. char byte = 127;
byte += 1;
cout << byte << endl;
int max = 2147483647;
max += 1;
cout << max<< endl;
개념: 컴퓨터가 소수점을 2진수로 저장하면서 생기는 미세한 오차를 직접 확인합니다.
0.1 + 0.2를 계산하여 출력하고, 결과가 정확히 0.3이 아닌0.30000000000000004처럼 나오는 것을 확인하는 코드를 쓰세요.double d = 1.0 - 0.9;를 계산하여 출력하고, //부동 소수점 연산
result = 0.1 + 0.2;
cout << result << endl;
double d = 1.0 - 0.9;
cout << d << endl;
개념: char와 int 사이의 변환을 C++ 스타일로 익힙니다.
char ch = 'A';를 선언하고, static_cast<int>(ch)를 사용하여int code = 97;을 선언하고, (char)code를 사용하여cout으로 확인하는 코드를 쓰세요. ch = 'A';
cout << static_cast<int>(ch) << endl; //static_cast ==()
int code = 97;
cout << (char)code << endl;
개념: #include <string>의 stoi, stod, to_string을 사용합니다.
string strNum = "123";을 stoi(strNum)을 사용하여int n에 저장하고, n + 7을 계산하여 출력하는 코드를 쓰세요.string strDouble = "3.14";를 stod(strDouble)을 사용하여 double d에 저장하고 출력하는 코드를 쓰세요.int age = 25;를 to_string(age)를 사용하여 문자열 변수에 담고 출력하는 코드를 쓰세요. string strNum = "123";
int n = stoi(strNum);
//n = create_stoi(strNum);
cout << n + 7 << endl;
string strDouble = "3.14";
d = stod(strDouble);
cout << d << endl;
int age = 25;
string age_string = to_string(age);
cout << to_string(3.141592) << endl;
cout << age_string << endl;
세부 요구사항은 아래와 같습니다.
언리얼 엔진 C++ 클래스 액터 큐브 메시 추가 후 코드 헤더파일 수정
RandomMoveCube.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "RandomMoveCube.generated.h"
UCLASS()
class RANDOMMOVEEVENT_API ARandomMoveCube : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ARandomMoveCube();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
FTimerHandle MoveTimerHandle;
int32 CurrentStep = 1;
int32 MaxStep = 10;
FVector StartLocation;
int32 EventCount = 0;
double TotalDistance = 0;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
//Turn, Move 함수 추가
virtual void Move(double Forward, double Right);
virtual void Turn(double Rotation);
//랜덤하게 이벤트가 발생하는 함수 추가
virtual bool RandomEvent();
//10회 이동 시 마다 Move,Turn, RandomEvent, 좌표 로그 출력 등 로직 동작 함수
virtual void DoRandomStep();
};
헤더파일 정의한 기능들 구현부분 추가
처음 구현 시 BeginPlay 내에 반복문 For문으로 처리해서 10번 반복하게 했으나 실제 실행해보면 멈춰있다가 일정 시간 지나면 마지막 위치에 큐브 위치하면서 종료되는 현상 발생
해당 현상 검색을 해보니 BeginPlay 내의 For문은 시간을 두고 실행되지 않고 한 프레임에 전부 실행되기 때문이라고 해서 반복마다 약간의 Delay 주기 위해서 Timer 사용해서 0.5초마다 반복되게 처리
RandomMoveCube.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "RandomMoveCube.h"
#include "Engine/Engine.h"
// Sets default values
ARandomMoveCube::ARandomMoveCube()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ARandomMoveCube::BeginPlay()
{
Super::BeginPlay();
//시작 점 (0,50,0)으로 위치 설정
StartLocation = FVector(0.f, 50.f, 0.f);
SetActorLocation(StartLocation);
//이벤트 발생 횟수 및 스텝 수, 총 이동 거리 초기화
CurrentStep = 1;
EventCount = 0;
TotalDistance = 0.f;
//For,While문으로 처리할 경우 1 프레임 내에서 For문 다 돌아가 버려서 제대로 움직임 동작 불가
// 월드의 타이머 매니저와 타이머를 설정
//0.5초마다 현재 액터에 DoRandomStep 호출하는 식으로 반복문 처리
GetWorld()->GetTimerManager().SetTimer(
MoveTimerHandle,
this,
&ARandomMoveCube::DoRandomStep,
0.5f,
true
);
}
// Called every frame
void ARandomMoveCube::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ARandomMoveCube::Move(double Forward, double Right) {
//랜덤 범위 내 로케이션 벡터
FVector NewLocation = GetActorLocation();
NewLocation += GetActorForwardVector() * Forward;
NewLocation += GetActorRightVector() * Right;
SetActorLocation(NewLocation);
}
void ARandomMoveCube::Turn(double Rotation) {
//랜덤 범위 내 로테이션 벡터 만들기
SetActorRotation(FRotator(0.f, Rotation, 0.f));
}
bool ARandomMoveCube::RandomEvent()
{
//1~100 숫자 중 뽑힌 숫자가 50이상이면 확률 50프로
int32 RandomNum = FMath::RandRange(1, 100);
if (RandomNum >= 50)
{
//랜덤 이벤트 발생여부 출력
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
2.f,
FColor::Red,
TEXT("Random Event Occur")
);
}
return true;
}
else {
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
2.f,
FColor::Red,
TEXT("Random Event Doesn't Occur")
);
}
return false;
}
}
void ARandomMoveCube::DoRandomStep()
{
// 현재 스텝이 10번 됬는지 체크 후 총 이동 거리, 총 이벤트 발생 횟수 출력
if (CurrentStep > MaxStep)
{
GetWorld()->GetTimerManager().ClearTimer(MoveTimerHandle);
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
5.f,
FColor::White,
FString::Printf(
TEXT("Total Moved Distance: %.2f, Random Event Count: %d"),
TotalDistance,
EventCount
)
);
}
return;
}
//랜덤 이동 X좌표, Y좌표, 회전 각 초기화
double RandomForward = FMath::RandRange(-500, 500);
double RandomRight = FMath::RandRange(-500, 500);
double RandomRotation = FMath::RandRange(0, 360);
//매 스텝마다 거리 계산위해 이동 전 좌표, 이동 후 좌표 설정
//이동 거리 계산값 TotalDistance에 더함
FVector BeforeLocation = GetActorLocation();
Turn(RandomRotation);
Move(RandomForward, RandomRight);
//이동 거리 누적
const FVector PresentLocation = GetActorLocation();
TotalDistance += FVector::Distance(BeforeLocation, PresentLocation);
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
2.f,
FColor::Green,
FString::Printf(TEXT("Step %d : Location (X: %.1f, Y: %.1f, Z: %.1f)"), CurrentStep,GetActorLocation().X, GetActorLocation().Y,GetActorLocation().Z)
);
}
//랜덤 이벤트 발생 시 이벤트 발생횟수 더하기
if (RandomEvent())
{
EventCount++;
}
//현재 스텝수 업데이트
CurrentStep++;
}