반응형

대학교 2학년 때 고급프로그래밍 과목을 배우면서 만든 코드이다. C++을 배우는 과목이었는데 과제 문제 중의 하나가 포식자-먹이 시뮬레이션을 만드는 거였다.

이때 만든 코드가 재밌어서 올려놓는다.

C++을 다 까먹어서 어떻게 돌아가는 건지 잘 모르겠다;; 일단 시뮬레이션 규칙은 다음과 같다.

- Ant와 Doodlebug는 각각 100, 5마리로 시작한다.
- 한 턴마다 랜덤한 방향으로 한 칸씩 움직인다.
- 서로 만나면 Doodlebug가 Ant를 잡아먹는다.
- 일정한 턴이 지나면 Ant와 Doodlebug는 번식하고 일정한 턴 동안 Doodlebug는 Ant를 잡아먹지 못하면 굶어죽는다.


#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstdio>

#define ANT 100
#define DOODLEBUG 5

using namespace std;

enum move
{
	UP, DOWN, LEFT, RIGHT
};

class Organism
{
protected:
	int god, duf;
public:
	Organism(int _god, int _duf) : god(_god), duf(_duf) {}
	int getGod();
	int getDuf();
	virtual void move(int move) = 0;
	virtual int getStep() = 0;
	virtual char get() = 0;
};

class Ant : public Organism
{
private:
	int step;
public:
	Ant(int _god, int _duf) : Organism(_god, _duf)
	{
		step = 0;
	}
	void move(int move);
	int getStep();
	char get();
};

class Doodlebug : public Organism
{
private:
	int step;
	int starve;
public:
	Doodlebug(int _god, int _duf) : Organism(_god, _duf)
	{
		step = 0;
		starve = 0;
	}
	void move(int move);
	int getStep();
	int getStarve();
	void addStarve();
	void resetStarve();
	char get();
};

void display(Organism *arr[]);
int check(Organism *arr[], int god, int duf);

int main()
{
	Organism *grid[400] = { 0 };
	srand((unsigned int)time(NULL));

	for (int i = 0; i < DOODLEBUG; i++)
	{
		int god = rand() % 20, duf = rand() % 20;
		if (check(grid, god, duf) == -1)
		{
			grid[i] = new Doodlebug(god, duf);
		}
		else
		{
			i--;
		}
	}
	for (int i = DOODLEBUG; i < DOODLEBUG + ANT; i++)
	{
		int god = rand() % 20, duf = rand() % 20;
		if (check(grid, god, duf) == -1)
		{
			grid[i] = new Ant(god, duf);
		}
		else
		{
			i--;
		}
	}

	while (true)
	{
		display(grid);
		getchar();

		for (int i = 0; i < 400; i++)
		{
			if (grid[i] != NULL && grid[i]->get() == 'X')
			{
				int god = grid[i]->getGod(), duf = grid[i]->getDuf();
				int tmp[4] = { check(grid, god - 1, duf), check(grid, god + 1, duf), check(grid, god, duf - 1), check(grid, god, duf + 1) };
				if (tmp[UP] != -1 && grid[tmp[UP]]->get() == 'O')
				{
					delete grid[tmp[UP]];
					grid[tmp[UP]] = NULL;
					grid[i]->move(UP);
					((Doodlebug*)grid[i])->resetStarve();
				}
				else if (tmp[DOWN] != -1 && grid[tmp[DOWN]]->get() == 'O')
				{
					delete grid[tmp[DOWN]];
					grid[tmp[DOWN]] = NULL;
					grid[i]->move(DOWN);
					((Doodlebug*)grid[i])->resetStarve();
				}
				else if (tmp[LEFT] != -1 && grid[tmp[LEFT]]->get() == 'O')
				{
					delete grid[tmp[LEFT]];
					grid[tmp[LEFT]] = NULL;
					grid[i]->move(LEFT);
					((Doodlebug*)grid[i])->resetStarve();
				}
				else if (tmp[RIGHT] != -1 && grid[tmp[RIGHT]]->get() == 'O')
				{
					delete grid[tmp[RIGHT]];
					grid[tmp[RIGHT]] = NULL;
					grid[i]->move(RIGHT);
					((Doodlebug*)grid[i])->resetStarve();
				}
				else
				{
					switch (rand() % 4)
					{
					case UP:
						if (god != 0 && check(grid, god - 1, duf) == -1)
						{
							grid[i]->move(UP);
						}
						break;
					case DOWN:
						if (god != 19 && check(grid, god + 1, duf) == -1)
						{
							grid[i]->move(DOWN);
						}
						break;
					case LEFT:
						if (duf != 0 && check(grid, god, duf - 1) == -1)
						{
							grid[i]->move(LEFT);
						}
						break;
					case RIGHT:
						if (duf != 19 && check(grid, god, duf + 1) == -1)
						{
							grid[i]->move(RIGHT);
						}
						break;
					}
					((Doodlebug*)grid[i])->addStarve();
				}
				if (grid[i]->getStep() == 8)
				{
					int tmp = 0;
					while (grid[tmp] != NULL)
					{
						tmp++;
					}
					if (god != 0 && check(grid, god - 1, duf) == -1)
					{
						grid[tmp] = new Doodlebug(god - 1, duf);
					}
					else if (god != 19 && check(grid, god + 1, duf) == -1)
					{
						grid[tmp] = new Doodlebug(god + 1, duf);
					}
					else if (duf != 0 && check(grid, god, duf - 1) == -1)
					{
						grid[tmp] = new Doodlebug(god, duf - 1);
					}
					else if (duf != 19 && check(grid, god, duf + 1) == -1)
					{
						grid[tmp] = new Doodlebug(god, duf + 1);
					}
				}
				if (((Doodlebug*)grid[i])->getStarve() == 3)
				{
					delete grid[i];
					grid[i] = NULL;
				}
			}
		}

		for (int i = 0; i < 400; i++)
		{
			if (grid[i] != NULL && grid[i]->get() == 'O')
			{
				int god = grid[i]->getGod(), duf = grid[i]->getDuf();
				switch (rand() % 4)
				{
				case UP:
					if (god != 0 && check(grid, god - 1, duf) == -1)
					{
						grid[i]->move(UP);
					}
					break;
				case DOWN:
					if (god != 19 && check(grid, god + 1, duf) == -1)
					{
						grid[i]->move(DOWN);
					}
					break;
				case LEFT:
					if (duf != 0 && check(grid, god, duf - 1) == -1)
					{
						grid[i]->move(LEFT);
					}
					break;
				case RIGHT:
					if (duf != 19 && check(grid, god, duf + 1) == -1)
					{
						grid[i]->move(RIGHT);
					}
					break;
				}
				if (grid[i]->getStep() == 3)
				{
					int tmp = 0;
					while (grid[tmp] != NULL)
					{
						tmp++;
					}
					if (god != 0 && check(grid, god - 1, duf) == -1)
					{
						grid[tmp] = new Ant(god - 1, duf);
					}
					else if (god != 19 && check(grid, god + 1, duf) == -1)
					{
						grid[tmp] = new Ant(god + 1, duf);
					}
					else if (duf != 0 && check(grid, god, duf - 1) == -1)
					{
						grid[tmp] = new Ant(god, duf - 1);
					}
					else if (duf != 19 && check(grid, god, duf + 1) == -1)
					{
						grid[tmp] = new Ant(god, duf + 1);
					}
				}
			}
		}
	}
	return 0;
}

void display(Organism *arr[])
{
	char grid[20][20] = { 0 };
	int count_ant = 0, count_doodlebug = 0;
	for (int i = 0; i < 400; i++)
	{
		if (arr[i] != NULL)
		{
			grid[arr[i]->getGod()][arr[i]->getDuf()] = arr[i]->get();
			if (arr[i]->get() == 'O')
			{
				count_ant++;
			}
			else if (arr[i]->get() == 'X')
			{
				count_doodlebug++;
			}
		}
	}
	cout << "┌────────────────────────────────────────┐" << endl;
	for (int i = 0; i < 20; i++)
	{
		cout << "│";
		for (int j = 0; j < 20; j++)
		{
			if (grid[i][j] == 0)
			{
				cout << "  ";
			}
			else
			{
				cout << grid[i][j] << " ";
			}
		}
		cout << "│" << endl;
	}
	cout << "└────────────────────────────────────────┘" << endl;
	cout << "Ant: " << count_ant << ", Doodlebug: " << count_doodlebug << endl;
}

int check(Organism *arr[], int god, int duf)
{
	for (int i = 0; i < 400; i++)
	{
		if (arr[i] != NULL && arr[i]->getGod() == god && arr[i]->getDuf() == duf)
		{
			return i;
		}
	}
	return -1;
}

int Organism::getGod()
{
	return god;
}

int Organism::getDuf()
{
	return duf;
}

void Ant::move(int move)
{
	switch (move)
	{
	case UP:
		god--;
		break;
	case DOWN:
		god++;
		break;
	case LEFT:
		duf--;
		break;
	case RIGHT:
		duf++;
		break;
	}
	if (step == 3)
	{
		step = 0;
	}
	else
	{
		step++;
	}
	return;
}

int Ant::getStep()
{
	return step;
}

char Ant::get()
{
	return 'O';
}

void Doodlebug::move(int move)
{
	switch (move)
	{
	case UP:
		god--;
		break;
	case DOWN:
		god++;
		break;
	case LEFT:
		duf--;
		break;
	case RIGHT:
		duf++;
		break;
	}
	if (step == 8)
	{
		step = 0;
	}
	else
	{
		step++;
	}
	return;
}

int Doodlebug::getStep()
{
	return step;
}

int Doodlebug::getStarve()
{
	return starve;
}

void Doodlebug::addStarve()
{
	starve++;
	return;
}

void Doodlebug::resetStarve()
{
	starve = 0;
	return;
}

char Doodlebug::get()
{
	return 'X';
}

실행결과 (엔터를 누르면 다음 턴)

반응형

+ Recent posts