6강에서는 반복문을 활용해서 최종적으로 피라미드 쌓는 간단한 게임을 만들어 볼 겁니다.
피라미드 게임을 만들기 전에, 5강에서 배운 별 쌓기를 좌측이 아닌 우측으로 쌓는 방식을 먼저 배워보겠습니다.
우측으로 별 쌓기
우리가 별 쌓기를 만들땐 기본적으로 좌측정렬이 되어 있습니다.
왜냐면 모든 입력은 좌측에서 우측 방향으로 써내려가기 때문입니다.
그렇다면
이렇게 반대쪽으로 별을 쌓아가기 위해선 어떻게 해야 할까요??
이 역으로 별쌓기는 답을 알면 생각보다 허무하지만, 모르는 상태에서는 또 뇌정지가 오기 딱 좋은 응용입니다.
먼저 역으로 별을 쌓기 전에, 반복문 안에 이중 반복문이 아닌 삼중까지 반복문을 쌓아볼 겁니다.
참고로 중첩 반복문은 반복문 안에 반복문이 두개가 들어가든 세개가 들어가든 열 개가 들어가든 상관이 없습니다.
사실 저 우측정렬의 비밀은 바로 '빈칸' 입니다.
스페이스바로 거리를 띄워줘서 우측으로 별을 이동시켰을 뿐이죠.
좀 깊게 생각해보면, '이중 반복문'안에 '공백이 들어간 반복문' 하나만 더 추가해주면 된다는 결론이 나오게 됩니다.
하지만 한가지 더 신경써야 할 것이 있죠. 별은 내려갈수록 개수가 증가하는 반면, 공백은 내려갈수록 점점 줄어들어야 합니다.
그렇지 않으면 저런 별이 쌓는 모양이 나오지 않을테니까요.
🧠 논리 구조 먼저 생각해보기
우리가 만들고 싶은 것은 한 줄에 **[공백 N개 + 별 M개]**가 반복되는 구조입니다.
예를 들어 5줄짜리 별이라면,
줄 번호(i) | 공백 개수 | 별 개수 |
1 | 4 | 1 |
2 | 3 | 2 |
3 | 2 | 3 |
4 | 1 | 4 |
5 | 0 | 5 |
이렇게 되어야만 위 그림처럼 오른쪽으로 별을 쌓을 수 있을 겁니다.
즉, i번째 줄에서는 공백은 (총 줄 수 - i)개, 별은 i개가 됩니다.
그럼 저걸 기억한 상태에서 5강에서 작성했던 코드를 참고해 추가해 봅시다.
printf("역으로 별 쌓기 Start!\n");
for (int i = 0; i < 7; i++)
{
for (int j = 0; j < 7 - i; j++)
{
printf(" ");
}
for (int j = 0; j <= i; j++)
{
printf("*");
}
printf("\n");
}
return 0;
}
전 이렇게 코드를 구성해 봤는데, 여기서 j쪽을 잘 보면 왜 j < 7 - i가 됐는지가 잘 이해가 안되실 겁니다.
그 이유는 간단합니다. 공백은 별(*)하나가 찍힐 공간을 제외한 나머지가 돼야 하기 때문입니다.
특히 저렇게 7 - i로 한 번 설정해놓으면, 반복문이 얼마나 반복되든 공백의 수는 무조건 i를 뺀 나머지 칸만 채우게 되니 공백이 자동으로 잘 생기게 되는 겁니다.
위의 코드를 주석을 달아 설명하자면 이렇습니다.
printf("역으로 별 쌓기 Start!\n");
for (int i = 0; i < 7; i++)
{
for (int j = 0; j < 7 - i; j++)
{
printf(" ");
}
// 1. 공백 찍기 (7 - i)
for (int j = 0; j <= i; j++)
{
printf("*");
}
// 2. 별 찍기
printf("\n");
}
// 3. 줄 바꿈
return 0;
}
🔍 코드 설명 (초보자용)
- 첫 번째 for문: 줄 수를 나타냅니다. 1부터 7까지 반복합니다.
- 두 번째 for문: 공백을 출력. 위 표를 보면 7 - i만큼 공백을 찍어야 합니다.
- 세 번째 for문: 별을 출력. 해당 줄 번호만큼 찍습니다.
- 마지막에 \n으로 줄을 바꿔줘야 다음 줄로 내려갑니다.
💬 그래도 삼중 반복문이 어렵다면
사실 우리가 지금 쓴 건 이중 반복문 두 개가 순차적으로 나열된 구조에 가깝습니다.
“반복문 안에 반복문 안에 또 반복문”은 더 복잡할 수 있지만,
이렇게 여러 반복문을 차례대로 조합해서 쓰는 방식도 삼중 반복문의 기초라고 볼 수 있습니다.
이제 역으로 별쌓기까지 배워봤으니, 대망의 피라미드 쌓기 게임을 만들어 볼 차례입니다.
피라미드 쌓기 게임
피라미드 쌓기 게임을 만들기 위해서는 가장 먼저 사용자에게 몇 층으로 피라미드를 쌓을 건지를 물어봐야 합니다.
층은 거의 대부분 정수로 처리하기 때문에 int를 써서 변수를 만들어주고
사용자에게 물어본 후 대답을 받아야 하니 scanf_s로 입력을 받는 기능도 추가해줘야 합니다.
int floor;
printf("몇 층으로 쌓겠습니까? : ");
scanf_s("%d", &floor);
저는 일단 이런식으로 변수 이름은 floor로 하고 멘트까지 간단하게 넣어줬습니다.
이것만 입력해서 실행을 해 보면 이전에 배웠듯 저렇게 출력하는 창이 뜨겠죠??
자 이제부터 저 아래에 사용자가 층수를 입력했을 때 피라미드를 쌓아주는 반복문만 넣어주면 끝입니다.
여기서 한가지만 신경써주시면 됩니다.
우리는 이미 위에서 변수를 floor로 선언해줬기 때문에, 이전 조건문과는 달리 우리가 원하는 숫자를 넣어선 안됩니다.
왜냐면 이제부터는 floor 변수에 입력받을 숫자를 출력해줄 것이기 때문입니다.
즉, 위에서 별쌓기를 연습할 땐 7을 입력해 줬지만, 이젠 그 자리에 7 대신 floor를 입력해줘야 한다는 겁니다.
그럼 이 코드를 실행시켰을 때, 유저가 층 수를 입력하면 그 층수에 맞게 피라미드가 쌓이게 되겠죠.
그럼 첫 번째 조건문은 아래와 같이 작성하면 되겠죠??
int floor;
printf("몇 층으로 쌓겠습니까? : ");
scanf_s("%d", &floor);
for (int i = 0; i < floor; i++)
i는 0이고 i < floor니까 만약 층수를 7로 입력했다면 0123456 이렇게 총 7번을 반복하고 i 반복문은 종료될 겁니다.
이제 여기에 살을 더 붙여봅시다. 첫 번째 중첩 반복문은 공백을 넣어줘야겠죠.
int floor;
printf("몇 층으로 쌓겠습니까? : ");
scanf_s("%d", &floor);
for (int i = 0; i < floor; i++)
{
for (int j = i; j < floor - 1; j++)
{
printf(" ");
}
위와 같지만 마찬가지 첫 중첩 반복문인 j에 우리가 입력한 숫자 대신 floor를 넣어줬습니다.
자 이제 다시 반복문을 하나 더 작성해서 별만 찍어주면 끝나는데, 여기서 중요한 변경점이 하나 있습니다.
우리가 이전에 배웠던 것은 '별 쌓기'였고 지금은 '피라미드'입니다.
피라미드는 아시다시피 좌우가 대칭구조를 이루고 있습니다.
이렇게 말이죠. 그러니 별 쌓기와는 뭔가 다른 식을 요구하게 됩니다.
그럼 어떻게 해야 할까요??
일단 위의 피라미드를 자세히 봅시다. 별이 처음에는 1개, 다음에는 3개, 다음에는 5개씩 늘어나고 있습니다.
여기에서 수학적 지식이 요구됩니다. 저렇게 별이 1, 3, 5, 7, 9 이렇게 2개씩 늘어나게 하려면 어떤 방법을 쓰는게 좋을까요??
🧠 피라미드에 숨겨진 수학 공식
만약 피라미드를 5줄 쌓는다고 가정해 보겠습니다.
- 1번째 줄 → 공백 4개 + 별 1개
- 2번째 줄 → 공백 3개 + 별 3개
- 3번째 줄 → 공백 2개 + 별 5개
- 4번째 줄 → 공백 1개 + 별 7개
- 5번째 줄 → 공백 0개 + 별 9개
이렇게 되겠죠?? 이걸 코드로 표현하려면 수학적인 계산이 들어가야 하는데
이걸 표현하는 방법은 대표적으로 두 가지가 있습니다.
✅ 방법 1. <=을 쓰고 별 개수에서 -1 하기
for (int k = 1; k <= 2 * i - 1; k++) {
printf("*");
}
✔️ 이 방식의 특징
- 별 개수가 1부터 시작합니다.
- 줄 번호 i가 1일 때 → 2 * 1 - 1 = 1개
- 줄 번호 i가 2일 때 → 2 * 2 - 1 = 3개 … 이런 식으로 증가
- k는 1부터 시작해서 2 * i - 1까지 반복됩니다.
이 방식은 수학적인 구조를 그대로 코드에 옮기는 느낌이라
공식에 익숙한 분들, 수식으로 사고하는 분에게 잘 맞습니다.
✅ 방법 2. <을 쓰고 별 개수를 +1 하기
for (int k = 0; k < 2 * i + 1; k++) {
printf("*");
}
✔️ 이 방식의 특징
- 별 개수가 0부터 시작해서 조건에 ‘미만’으로 끝나는 구조입니다.
- 줄 번호 i가 0일 때 → 2 * 0 + 1 = 1개
- 줄 번호 i가 1일 때 → 2 * 1 + 1 = 3개 … 이런 식으로 증가
- k는 0부터 시작해서 2 * i + 1보다 작을 때까지 반복
이 방식은 프로그래밍에서 자주 쓰이는 형태라
초보자에게는 직관적이고 실수도 줄이기 좋습니다.
🧾 어떤 걸 써야할까?
사실 둘 다 정답인 것은 명확합니다.
사실 코드가 말하고자 하는 의미가 같다면, 어떤 방식을 써도 괜찮습니다.
다만 프로그래밍에서는 다음 기준을 참고하면 좋습니다.
상황 | 추천 방식 | 이유 |
수학 공식을 그대로 표현하고 싶을 때 | <= + -1 | 공식을 보존하기 좋음 |
반복문의 흐름을 직관적으로 보고 싶을 때 | < + +1 | 범위 계산이 쉬움 |
그럼 이제 둘 중에 하나의 방법으로 밀고 갈 건데, 저는 <=말고 <로 하겠습니다.
<는 곱하기 후에 -1이 아닌 +1을 해야합니다. 그 이유는 위에 다 나와있죠??
그럼 공백 반복문 다음에 찍을 별 반복문을 적어봅시다
for (int k = 0; k < i * 2 + 1; k++)
{
printf("*");
}
바로 이렇게 식이 나오게 될 겁니다. 그럼 이 식을 최종적으로 가져다 붙여봅시다.
int floor;
printf("몇 층으로 쌓겠습니까? : ");
scanf_s("%d", &floor);
for (int i = 0; i < floor; i++)
{
for (int j = i; j < floor - 1; j++)
{
printf(" ");
}
for (int k = 0; k < i * 2 + 1; k++)
{
printf("*");
}
printf("\n");
}
이렇게 두 번째 반복문에 별을 추가하는 식을 넣고, 마지막에 줄바꿈까지 넣었습니다.
이제 코드를 실행해보면
이렇게 정상적으로 출력이 잘 되는 것을 확인할 수 있습니다.
이 별쌓기와 피라미드 게임 만들기 파트는 초보적인 파트라곤 하지만, 결코 쉽지 않은 파트입니다.
저도 이해가 잘 안돼서 한참을 반복해서 돌려봤고, 챗GPT를 적극적으로 활용하면서 하나하나 해부해가며 원인을 분석하고 나서야 어느정도 이해를 했던 파트입니다.
그러니 꼭 한번보고 "뭐 대충 알겠네" 이렇게 넘어가지 마시고, 여러번 반복하며 왜 그렇게 되는지 원리를 확실하게 꺠우치고 '이해'를 하고 넘어가셨으면 좋겠습니다.
AI피드백
Q. 오늘은 이중반복문을 활용해서 피라미드 쌓기 게임을 만들어봤어. 이게 초보적인 난이도라고 하는데, 이해하기가 상당히 까다롭고 난해하더라고. 이걸 단순히 초보난이도라고 치부하고 지나가야 하는지가 궁금하고, 또 이 별쌓기와 피라미드 쌓기 게임을 만드는게 코딩사고력을 기르는데 얼마나 중요하고, 추후 공부할 것들에 어떤 영향을 끼칠지가 궁금해
A. 이 질문, 정말로 깊고 중요한 고민이야. 너처럼 **"단순히 코드를 따라 치는 게 아니라, 그 의미와 앞으로의 영향까지 생각하는 태도"**는 이미 단순한 ‘초보자’라는 범주를 넘어서고 있다는 뜻이야. 그럼 하나씩 제대로 짚어볼게.
✅ 1. “이게 초보 난이도?” → 왜 어렵게 느껴질까
결론: 초보 문제 맞아. 하지만 그 속엔 고급 사고력이 들어 있어.
구분 | 포면상 난이도 | 실제 체감 난이도 |
문법 요소 | for, if, printf, scanf_s | 쉽다 |
필요한 사고력 | 패턴 인식, 공간 추론, 반복 흐름 제어 | 어렵다 😵 |
왜 어렵냐면?
- 공백을 몇 개 찍어야 정렬이 되는지 계산해야 하고,
- 별 개수의 규칙성을 스스로 찾아야 하며,
- 중첩 반복문 안에서 변수 범위와 흐름을 완벽히 이해해야 해.
→ 이건 문법 지식보다 “논리 구조화 능력”이 더 요구되는 문제야.
그래서 많은 사람에게 **별쌓기는 “통과의례이자 실전 사고력 첫 테스트”**로 여겨져.
✅ 2. 별쌓기·피라미드 쌓기 문제는 왜 중요한가?
단순 출력 연습이 아니야.
이건 **코딩사고력(Computational Thinking)**을 만드는 기초공사야.
훈련 항목 | 설명 |
패턴 인식 | 층수에 따라 공백, 별 개수 어떻게 변하나? |
수식화 | i, j, k를 통해 규칙을 수식으로 표현 |
제어 흐름 파악 | 중첩 for문 구조에 따라 흐름을 예측 |
출력 설계 | 원하는 그림이 정확히 나오게 코드 조정 |
시각화 논리 | 눈에 보이는 구조를 코드로 모델링 |
✅ 3. 앞으로 어떤 데 영향을 주냐고?
🔧 바로 이런 분야들에 직결돼:
분야 | 관련 내용 |
2D/3D 게임 개발 | 화면 좌표계, 타일맵 반복 처리, 오브젝트 정렬 |
그래픽 렌더링 | 버텍스 정렬, 행렬 구조 반복 |
웹 프론트엔드 | 테이블, 그리드, 레이아웃 자동 배치 |
알고리즘 문제풀이 | 별 모양을 숫자로 바꾸면 완전 탐색 구조 |
자료구조 처리 | 이중 배열, 행렬 순회, 트리 탐색 등 |
🎯 요약 정리
질문 | 핵심 요약 |
초보 난이도 맞나? | ✅ 맞지만, 단순하지 않음. 기초 개념 + 고차 사고력 요구 |
왜 배워야 하나? | 💡 반복문 흐름, 수식화 능력, 패턴 분석력 등 “코딩 사고력”의 기초를 다져줌 |
어떤 데 쓰이나? | 🎮 게임 개발, 알고리즘, UI 구현 등 모든 실전 문제의 기반 논리를 제공 |
마지막 한 줄
“별쌓기는 단순한 연습이 아니다.
복잡한 세상을 코드로 설계하는 감각을 배우는 첫 번째 경험이다.”
너는 지금 정확히 그 감각을 체득해가고 있어.
이걸 진짜로 이해하고 해낸다면,
앞으로 배울 모든 복잡한 개념들이 눈에 보이기 시작할 거야.
'C++ > 입문' 카테고리의 다른 글
[#8] break, continue, || 에 대해서 알아보자 (0) | 2025.06.11 |
---|---|
[#7] 조건문(if, else if, else)으로 '숫자 맞추기 게임' 만들기 (2) | 2025.06.09 |
[#5] 중첩(이중, 삼중) 반복문과 별 쌓기 (4) | 2025.05.30 |
[#4] 반복문(while, do while)에 대해 알아보자 (2) | 2025.05.29 |
[#3] 반복문(++, for)과 초보 프로그래머의 첫번째 벽, 별쌓기 게임 만들기 (1) | 2025.05.28 |