1. 배열의 크기 상관없음.
2. 우주선 모양 상관없음.
3. 구름(▩)의 모양, 속도 상관없음. 갯수는 적어도 세 개 이상.
4. 테두리 지워지지 말것.
5. 우주선이 구름에 가려지면 안 됨. 그 반대로 구현해야함.
-----------------------------------------------------------------------------------------------------------
솔직히 우주선이라 보기에는 너무 대충만들었다.
필자는 이번 문제를 보면서 생각한 것이 우주선은 어쩌피 안 움직이고 뒤에 배경 즉, 구름만 움직여야 한다는 조건을 듣고 생각을 해봤다. "차라리 우주선을 배경으로 씌워버리면 어떨까? 어쩌피 우주선은 고정이니깐" 이런 생각을 가지고 저번 포스팅때 만든 맵을 그대로 가져왔다.
우주선이 해결되니 남은 것은 구름이다. 우주선은 기본적으로 움직여야 하니 구름은 스스로 내려가도록 설정해야한다. 따라서 필자는 AutoMove() 라는 함수를 새로 만들었다.
맨 처음에는 이렇게 짰었다. 하지만 구름은 미친듯한 속도로 내려가는 걸 보고 절망에 빠졌고 속도를 늦출 방법을 생각해야했다. 그래서 검색을 하던중 time.h에 시간에 관련된 함수가 있는 것을 보고 delay(clock_h n) 이라는 함수라는 것을 새로 만들었다. delay함수는 이 함수를 컴파일러가 읽으면 n값 만큼 시간을 지연시켜주는 함수이다.
충돌 체크는 의외로 쉬웠다.오른쪽으로 움직일 시 구름의 좌표 + 구름의 길이 +1의 값이 BLOCK 즉 테두리 일 경우 입력을 못 받게 했으면 왼쪽으로 움직일 시 구름의 좌표 -1의 값을 체크했다. 이렇게 완성을 했다.
이번에도 소스코드는 C++이다. 하지만 전편에서도 말했지만 딱히 상관은 없다. C++의 꽃인 상속(다형성)은 1도 안썼다.
접기
//Define.h
#pragma once
#include <iostream>
#include<Windows.h>
#include <conio.h>
#define WIDTH 10
#define HEIGHT 10
enum state { BLOCK = 1, ROAD = 0, SHIP = 2 };
void setXY(int _x, int _y);
void Curclear();
//Define.cpp
#include"Define.h"
void setXY(int _x, int _y)
{
COORD cur;
cur.X = _x;
cur.Y = _y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cur);
}
// 커서 지우는 함수
void Curclear()
{
CONSOLE_CURSOR_INFO cur;
cur.dwSize = 1;
cur.bVisible = false;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cur);
}
//Terrain.h
#pragma once
#include"Define.h"
class Terrain
{
private:
int m_state;
int m_x;
int m_y;
char *m_name;
public:
// 초기화
Terrain();
void Init();
void SetPos(int _x, int _y);
void Render();
int GetX();
int GetY();
int Getstate();
void Setstate(int _state);
};
//Terrain.cpp
#include"Terrain.h"
Terrain::Terrain()
{
int m_state = 0;
int m_x = 0;
int m_y = 0;
char *m_name = "";
}
void Terrain::Init()
{
if (m_state == state::BLOCK)
{
m_name = "□";
}
else if (m_state == state::ROAD)
{
m_name = "";
}
if (m_state == state::SHIP)
{
m_name = "@";
}
}
void Terrain::SetPos(int _x, int _y)
{
m_x = _x;
m_y = _y;
}
void Terrain::Render()
{
setXY(m_x * 2, m_y);
printf("%s", m_name);
}
int Terrain::GetX()
{
return m_x;
}
int Terrain::GetY()
{
return m_y;
}
int Terrain::Getstate()
{
return m_state;
}
void Terrain::Setstate(int _state)
{
m_state = _state;
}
//Object.h
#pragma once
#include"Define.h"
class Object
{
private:
int m_x;
int m_y;
char *m_name;
public:
Object();
void Move(int _x, int _y);
void SetPos(int _x, int _y);
void Render();
int GetX();
int GetY();
void AutoMove();
};
//Object.cpp
#include"Object.h"
#include<time.h>
void delay(clock_t n)
{
clock_t start = clock();
while (clock() - start < n);
}
Object::Object()
{
m_x = 1;
m_y = 1;
m_name = "▩▩▩▩";
}
void Object::Move(int _x, int _y)
{
m_x += _x;
m_y += _y;
}
void Object::SetPos(int _x, int _y)
{
m_x = _x;
m_y = _y;
}
void Object::Render()
{
setXY(m_x * 2, m_y);
printf("%s", m_name);
setXY(0, m_y - 1);
printf(" ");
}
int Object::GetX()
{
return m_x;
}
int Object::GetY()
{
return m_y;
}
void Object::AutoMove()
{
delay(100);
m_y++;
}
//main.cpp
#include"Define.h"
#include"Object.h"
#include"Terrain.h"
#include<time.h>
void main()
{
Object obj;
Terrain ter[WIDTH][HEIGHT];
Curclear();
// 맵 그리는 2차원 배열
int map[WIDTH][HEIGHT] =
{
{ 1,1,1,1,1,1,1,1,1,1 },
{ 1,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,2,2,0,0,0,1 },
{ 1,0,0,2,2,2,2,0,0,1 },
{ 1,0,0,0,2,2,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,1 },
{ 1,1,1,1,1,1,1,1,1,1 },
};
for (int i = 0; i < WIDTH; i++)
{
for (int j = 0; j < HEIGHT; j++)
{
ter[i][j].SetPos(i, j);
ter[i][j].Setstate(map[i][j]);
ter[i][j].Init();
}
}
char ch;
bool check = true;
while (true == check)
{
if (_kbhit())
{
ch = _getch();
switch (ch)
{
case 'a':
if (ter[obj.GetX() + 4][obj.GetY()].Getstate() != state::BLOCK)
obj.Move(1, 0);
break;
case 'd':
if (ter[obj.GetX() - 1][obj.GetY()].Getstate() != state::BLOCK)
obj.Move(-1, 0);
break;
}
}
obj.AutoMove();
if (ter[obj.GetX()][obj.GetY() + 1].Getstate() == state::BLOCK)
{
setXY(0, obj.GetY() - 1);
printf(" ");
obj.SetPos(2, 2);
}
obj.Render();
for (int i = 0; i < WIDTH; i++)
{
for (int j = 0; j < HEIGHT; j++)
{
ter[i][j].Render();
}
}
}
}
접기