/*
Loops through the three included levels. Displays the shop menu,
lets the user buy chickens and start the game. Checks if the
user has won or lost, displays the appropriate message and exits.
*/
void PlayGame(void) {
	int winCheck = 1;
	int levelCount = 1;
	int coins = 100;
	char input[BUF];
	char map[22][80];
	List L;

	Initialize(&L);

	while(winCheck == 1 && levelCount <= 3) {

		strcpy(input, "asd");
		printf("Welcome to Level %d!\n", levelCount); fflush(stdout);
		while(strcmp(input, "s\n") != 0 && strcmp(input, "4\n") != 0) {
			printf("SHOP:\n1. Chick(c)   ($10)\n2. Hen(H)     ($25)\n3. Rooster(R) ($50)\n4. Start Level\n\n"); fflush(stdout);
			printf("Available Coins: $%d\n", coins); fflush(stdout);
			printf("Current Number of Chickens (Max 13): %d\n>", L.size); fflush(stdout);
			fgets(input, BUF, stdin);
			coins = Shop(input, coins, &L);
		}

		/*load the level*/
		if(levelCount == 1)
			Load("level1.txt", map);
		else if(levelCount == 2)
			Load("level2.txt", map);
		else if(levelCount == 3)
			Load("level3.txt", map);
	
		/*return 1 if user completed level, 0 if they failed*/
		winCheck = Run(&L, map, levelCount);
		endwin();

		/*award resources based on which level was completed*/
		if(levelCount == 1 && winCheck == 1) {
			coins = coins + 150;
		}else if(levelCount == 2 && winCheck == 1) {
			coins = coins + 200;
		}else if(levelCount == 3 && winCheck == 1) {
			coins = coins + 300;
		}

		levelCount++;
		fflush(stdout);
	}


	if(winCheck == 1 && levelCount == 4) {
		printf("Congratulations! You escaped from the farm with %d chickens remaining!\n", L.size);
		exit(0);
	}
    else {
		printf("You lose, but the farmers eat well.\n");
		exit(0);
	}
}
void GameEngine::generateLevel() {

	//Clear out the last level
	for (vector<Actor*>::iterator it = monsters.begin(); it != monsters.end(); ++it)
		delete (*it);
	monsters.clear();
	for (vector<Pickup*>::iterator it = pickups.begin(); it != pickups.end(); ++it)
		delete (*it);
	pickups.clear();
	map.clear();
	playableMap.clear();

	//Set tile graphics for curr floor
	if (currLevel == 1) {
		wallTile = 0x103;
		floorTile = 0x100;
	}
	else if (currLevel > 1) {
		wallTile = 0x14D;
		floorTile = 0x13E;

		delete boss;
	}

	//Initialize the outer map vector
	for (int i = 0; i < worldSize; i++) {
		vector<Cell> v;
		map.push_back(v);
	}

	//Generate the map boundaries
	lib.loop_portion(Point(0, 0), Point(worldSize, worldSize), [&](Point p) {
		Cell c(p, 2, wallTile, 0);
		map[p.x()].push_back(c);
	});

	//Generate the random rooms
	for (int i = 0; i < rand() % 130 + 100; i++) {
		Point pStart((rand() % 55 + 1), (rand() % 55 + 1));
		Point pEnd(pStart.x() + (rand() % 6 + 3), pStart.y() + (rand() % 6 + 3));

		fillBox(pStart, pEnd);
	}

	//Flood fill to connect the world
	int currZone = 0;
	vector<int> zoneSize;
	lib.loop_portion(Point(0, 0), Point(worldSize, worldSize), [&](Point p) {
		if (map[p.x()][p.y()].getCellType() != 2 && map[p.x()][p.y()].getZone() == 0) {
			currZone++;
			int size = floodFill(map[p.x()][p.y()].getLoc(), currZone, 0);
			zoneSize.push_back(size);
		}
	});

	//Get biggest zone in array
	int max = zoneSize[0];
	int largestZone = 0;
	for (unsigned int i = 1; i < zoneSize.size(); i++) {
		if (zoneSize[i] > max) {
			largestZone = i;
			max = zoneSize[i];
		}
	}
	largestZone++; //Offset for vector index

	//Get rid of everything but largest zone
	int end = worldSize - 1;
	lib.loop_portion(Point(0, 0), Point(worldSize, worldSize), [&](Point p) {
		Cell& c = map[p.x()][p.y()];

		if (c.getZone() != largestZone) {
			if ((p.x() + 1 < end && map[p.x() + 1][p.y()].getZone() == largestZone) ||
				(p.x() - 1 > 0 && map[p.x() - 1][p.y()].getZone() == largestZone) ||
				(p.y() + 1 < end && map[p.x()][p.y() + 1].getZone() == largestZone) ||
				(p.y() - 1 > 0 && map[p.x()][p.y() - 1].getZone() == largestZone) ||
				(p.x() - 1 > 0 && p.y() - 1 > 0 && map[p.x() - 1][p.y() - 1].getZone() == largestZone) ||
				(p.x() - 1 > 0 && p.y() + 1 < end   && map[p.x() - 1][p.y() + 1].getZone() == largestZone) ||
				(p.x() + 1 < end && p.y() - 1 > 0 && map[p.x() + 1][p.y() - 1].getZone() == largestZone) ||
				(p.x() + 1 < end && p.y() + 1 < end && map[p.x() + 1][p.y() + 1].getZone() == largestZone)) {
				c.setTile(wallTile);
				c.setTileType(2);
			}
			else {
				c.setTile(0);
				c.setTileType(2);
			}
		}
		else if (c.getLoc().x() == end)
			c.setTile(0);
	});

	//Set player starting position
	lib.loop_portion(Point(0, 0), Point(worldSize - 1, worldSize - 1), [&](Point p) {
		if (map[p.x()][p.y()].getZone() != 0 && map[p.x()][p.y()].getCellType() != 2)
			playableMap.push_back(map[p.x()][p.y()].getLoc());
	});

	//Add monsters
	for (unsigned int i = 0; i < playableMap.size(); i++) {
		int chance = rand() % 30;
		if (chance == 15) {
			//Make the monster
			ActorDef def = pickfromtable<ActorDef>(actordefs);
			monsters.push_back(new Actor(def, playableMap[i], false, false));
			map[playableMap[i].x()][playableMap[i].y()].setActor(monsters.back());

			//Give chance to spawn with item
			chance = rand() % 5 + 1; //Give 10% chance to spawn
			if (chance == 3) {
				PickupDef def = pickfromtable<PickupDef>(pickupdefs);
				pickups.push_back(new Pickup(def, playableMap[i]));
				map[playableMap[i].x()][playableMap[i].y()].setPickup(pickups.back());
			}
		}
	}

	//Set starting pos
	Point heroLoc = getRandomLoc();
	screenOrientation = heroLoc;
	hero->setLoc(screenOrientation);

	//Add stairs, shop, boss
	stairLoc = addToRandomLoc(Cell(Point(), 5, 0x1A0, -1));
	shop = Shop(addToRandomLoc(Cell(Point(), 6, 0x0C0, -1)), currLevel, pickupdefs, &lib, hero, &log, &invLog);
	bossLoc = addToRandomLoc(Cell(Point(), 7, 0x1AB, -1));
	bossInRoomLoc = Point(5, 2);


	//Instantiate the boss map
	for (int i = 0; i < bossMapSize; i++) {
		vector<Cell> row;
		for (int j = 0; j < bossMapSize; j++) {
			if (i == 0 || i == bossMapSize - 1 || j == 0 || j == bossMapSize - 1)
				row.push_back(Cell(Point(i, j), 2, 0x14B, 1));
			else
				row.push_back(Cell(Point(i, j), 1, 0x122, 1));
		}
		bossMap.push_back(row);
	}

	//Add the boss to its location in the boss map
	int which = rand() % bossdefs.size();
	boss = new Actor(bossdefs[which], bossInRoomLoc, false, true);
	bossMap[bossInRoomLoc.x()][bossInRoomLoc.y()].setActor(boss);
}