Advertisement
Guest User

Untitled

a guest
Oct 19th, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.22 KB | None | 0 0
  1. //
  2. // Created by Julia Sanguinetti on 2019-10-16.
  3. //
  4. #include <time.h>
  5.  
  6. #include <cstdio>
  7. #include <cstdlib>
  8. #include <iostream>
  9. #include <string>
  10. #include <vector>
  11. using namespace std;
  12.  
  13. // Constants
  14. const int WORLDSIZE = 20;
  15. const int INITIAL_ANTS = 20;
  16. const int INITIAL_DOODLEBUGS = 5;
  17. const int DOODLEBUG = 1;
  18. const int ANT = 2;
  19. const int ANT_BREED = 3;
  20. const int DOODLE_BREED = 8;
  21. const int DOODLE_STARVE = 3;
  22.  
  23. // Declarations of classes
  24. class Organism;
  25. class Doodlebug;
  26. class Ant;
  27.  
  28. // World class
  29. class World {
  30. public:
  31. // Constructor
  32. World();
  33. // Destructor
  34. ~World();
  35. Organism *getAt(int x, int y);
  36. void setAt(int x, int y, Organism *org);
  37. void display();
  38. void oneTurn();
  39. bool withinBoundaries(int x, int y);
  40.  
  41. private:
  42. Organism *grid[WORLDSIZE][WORLDSIZE];
  43. void oneTurnForType(int type);
  44. };
  45.  
  46. // Definition for the Organism base class
  47. class Organism {
  48. friend class World;
  49.  
  50. public:
  51. // Constructors
  52. Organism();
  53. Organism(World *wrld, int x, int y);
  54.  
  55. // Destructor
  56. virtual ~Organism() { world->setAt(x, y, nullptr); }
  57.  
  58. // Methods
  59. virtual void breed() = 0;
  60. virtual void move() = 0;
  61. virtual int getType() = 0;
  62. virtual bool starve() = 0;
  63.  
  64. protected:
  65. int x, y;
  66. bool moved;
  67. int breedCount;
  68. World *world;
  69. void basicMove();
  70.  
  71. private:
  72. void moveIfPossible(int x, int y);
  73. };
  74.  
  75. void Organism::moveIfPossible(int x, int y) {
  76. if (world->withinBoundaries(x, y) && world->getAt(x, y) == nullptr) {
  77. world->setAt(x, y, this);
  78. world->setAt(this->x, this->y, nullptr);
  79. this->x = x;
  80. this->y = y;
  81. }
  82. }
  83.  
  84. void Organism::basicMove() {
  85. int dir = rand() % 4;
  86. // Try to move up, if not at an edge and empty spot
  87. if (dir == 0) {
  88. Organism::moveIfPossible(x, y + 1);
  89. }
  90. // Try to move down
  91. else if (dir == 1) {
  92. Organism::moveIfPossible(x, y - 1);
  93. }
  94. // Try to move left
  95. else if (dir == 2) {
  96. Organism::moveIfPossible(x - 1, y);
  97. }
  98. // Try to move right
  99. else {
  100. Organism::moveIfPossible(x + 1, y);
  101. }
  102. }
  103.  
  104. // Constructor definition
  105. World::World() {
  106. int i, j;
  107. for (i = 0; i < WORLDSIZE; i++) {
  108. for (j = 0; j < WORLDSIZE; j++) grid[i][j] = nullptr;
  109. }
  110. }
  111. // Destructor definition
  112. World::~World() {
  113. // Release any allocated memory
  114. for (int i = 0; i < WORLDSIZE; i++) {
  115. for (int j = 0; j < WORLDSIZE; j++) {
  116. if (grid[i][j] != nullptr) delete grid[i][j];
  117. }
  118. }
  119. }
  120.  
  121. bool World::withinBoundaries(int x, int y) {
  122. return (0 <= x) && (x < WORLDSIZE) && (0 <= y) && (y < WORLDSIZE);
  123. }
  124.  
  125. // Member function definitions
  126. Organism *World::getAt(int x, int y) {
  127. if (withinBoundaries(x, y)) return grid[x][y];
  128. return nullptr;
  129. }
  130.  
  131. // Method definition of setAt
  132. void World::setAt(int x, int y, Organism *org) { grid[x][y] = org; }
  133.  
  134. // Method definition of display
  135. void World::display() {
  136. for (int j = 0; j < WORLDSIZE; j++) {
  137. for (int i = 0; i < WORLDSIZE; i++) {
  138. if (grid[i][j] == nullptr)
  139. cout << '-';
  140. else if (grid[i][j]->getType() == ANT)
  141. cout << 'o';
  142. else
  143. cout << "X";
  144. }
  145. cout << endl;
  146. }
  147. }
  148.  
  149. void World::oneTurnForType(int type) {
  150. for (int i = 0; i < WORLDSIZE; i++) {
  151. for (int j = 0; j < WORLDSIZE; j++) {
  152. Organism *organism = grid[i][j];
  153. if (organism != nullptr && organism->getType() == type) {
  154. if (!organism->moved) {
  155. organism->moved = true;
  156. organism->move();
  157. organism->breed();
  158. }
  159.  
  160. if (organism->getType() == DOODLEBUG && organism->starve()) {
  161. delete organism;
  162. }
  163. }
  164. }
  165. }
  166. }
  167.  
  168. // Method definition of oneTurn
  169. void World::oneTurn() {
  170. // First reset all organism to not move
  171. for (int i = 0; i < WORLDSIZE; i++) {
  172. for (int j = 0; j < WORLDSIZE; j++) {
  173. if (grid[i][j] != nullptr) grid[i][j]->moved = false;
  174. }
  175. }
  176.  
  177. oneTurnForType(DOODLEBUG);
  178. oneTurnForType(ANT);
  179. }
  180.  
  181. // Default constructor of Organism
  182. Organism::Organism() {
  183. world = nullptr;
  184. moved = false;
  185. breedCount = 0;
  186. x = 0;
  187. y = 0;
  188. }
  189.  
  190. Organism::Organism(World *wrld, int x, int y) {
  191. this->world = wrld;
  192. moved = true;
  193. breedCount = 0;
  194. this->x = x;
  195. this->y = y;
  196. wrld->setAt(x, y, this);
  197. }
  198.  
  199. // Ant class
  200. class Ant : public Organism {
  201. public:
  202. friend class World;
  203. // Constructors
  204. Ant() = default;
  205. Ant(World *wrld, int x, int y) : Organism(wrld, x, y){};
  206. // Methods
  207. void breed() override;
  208. void move() override;
  209. int getType() override;
  210. bool starve() override { return false; }
  211. };
  212. // Method definition of move
  213. void Ant::move() { Organism::basicMove(); }
  214.  
  215. // Method definition of getType
  216. int Ant::getType() { return ANT; }
  217.  
  218. // Method definition of breed
  219. void Ant::breed() {
  220. breedCount++;
  221. if (breedCount == ANT_BREED) {
  222. breedCount = 0;
  223. // Try to make a new any either above, left, right, below
  224. if ((y > 0) && (world->getAt(x, y - 1) == nullptr))
  225. new Ant(world, x, y - 1);
  226. else if ((y < WORLDSIZE - 1) && (world->getAt(x, y + 1) == nullptr))
  227. new Ant(world, x, y + 1);
  228. else if ((x > 0) && (world->getAt(x - 1, y) == nullptr))
  229. new Ant(world, x - 1, y);
  230. else if ((x < WORLDSIZE - 1) && (world->getAt(x + 1, y) == nullptr))
  231. new Ant(world, x + 1, y);
  232. }
  233. }
  234.  
  235. // Create a class Doodlebug
  236. class Doodlebug : public Organism {
  237. public:
  238. friend class World;
  239.  
  240. public:
  241. Doodlebug();
  242. Doodlebug(World *world, int x, int y);
  243. void breed() override;
  244. void move() override;
  245. int getType() override;
  246. bool starve() override;
  247.  
  248. private:
  249. int starveTricks;
  250. bool eatAndMoveIfPossible(int x, int y);
  251. };
  252.  
  253. // Default constructor
  254. Doodlebug::Doodlebug() { starveTricks = 0; }
  255.  
  256. // Constructor with parameters
  257. Doodlebug::Doodlebug(World *world, int x, int y) : Organism(world, x, y) {
  258. starveTricks = 0;
  259. }
  260.  
  261. bool Doodlebug::eatAndMoveIfPossible(int x, int y) {
  262. if (world->withinBoundaries(x, y) && (world->getAt(x, y) != nullptr) &&
  263. (world->getAt(x, y)->getType() == ANT)) {
  264. delete world->getAt(x, y);
  265. world->setAt(x, y, this);
  266. world->setAt(this->x, this->y, nullptr);
  267. starveTricks = 0;
  268. this->x = x;
  269. this->y = y;
  270. return true;
  271. }
  272. return false;
  273. }
  274. // Member functions
  275. void Doodlebug::move() {
  276. bool ate = eatAndMoveIfPossible(x, y + 1);
  277. if (!ate) ate = eatAndMoveIfPossible(x + 1, y);
  278. if (!ate) ate = eatAndMoveIfPossible(x, y - 1);
  279. if (!ate) ate = eatAndMoveIfPossible(x - 1, y);
  280.  
  281. if (ate) return;
  282.  
  283. // Increment starve tick since didn't eat on this turn
  284. Organism::basicMove();
  285. starveTricks++;
  286. }
  287.  
  288. // Method definition of getType
  289. int Doodlebug::getType() { return DOODLEBUG; }
  290.  
  291. // Method definition of breed
  292. void Doodlebug::breed() {
  293. breedCount++;
  294. if (breedCount == DOODLE_BREED) {
  295. breedCount = 0;
  296. // Try to make a new ant either above, left, right, or down
  297. if ((y > 0) && (world->getAt(x, y - 1) == nullptr)) {
  298. new Doodlebug(world, x, y - 1);
  299. } else if ((y < WORLDSIZE - 1) && (world->getAt(x, y + 1) == nullptr)) {
  300. new Doodlebug(world, x, y + 1);
  301. } else if ((x > 0) && (world->getAt(x - 1, y) == nullptr)) {
  302. new Doodlebug(world, x - 1, y);
  303. } else {
  304. new Doodlebug(world, x + 1, y);
  305. }
  306. }
  307. }
  308. // Method definition of starve
  309. bool Doodlebug::starve() {
  310. // Starve if no food eaten in last DOODLE_STARVE time ticks
  311. return starveTricks >= DOODLE_STARVE;
  312. }
  313.  
  314. int main() {
  315. // Seed random number generator
  316. srand(time(nullptr));
  317. World w;
  318.  
  319. // Randomly create 100 ants
  320. int antCount = 0;
  321. while (antCount < INITIAL_ANTS) {
  322. int x = rand() % WORLDSIZE;
  323. int y = rand() % WORLDSIZE;
  324. // Check for empty spots
  325. if (w.getAt(x, y) == nullptr) {
  326. new Ant(&w, x, y);
  327. antCount++;
  328. }
  329. }
  330.  
  331. // Randomly create 5 doodlebugs
  332. int doodleCount = 0;
  333. while (doodleCount < INITIAL_DOODLEBUGS) {
  334. int x = rand() % WORLDSIZE;
  335. int y = rand() % WORLDSIZE;
  336. // Check for empty spots
  337. if (w.getAt(x, y) == nullptr) {
  338. new Doodlebug(&w, x, y);
  339. doodleCount++;
  340. }
  341. }
  342.  
  343. // Run simulation until user cancels
  344. do {
  345. w.display();
  346. w.oneTurn();
  347. cout << '\n' << "Press enter to continue...";
  348. } while (cin.get() == '\n');
  349.  
  350. return 0;
  351. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement