#include "game_state.h" #include #include #include #include #include const int OPENING_LINES = 6; const int GAME_AREA_LINES = 25; const int GAME_WIDTH = 19; void moveToNextChar(int &x, int &y, int &width, char &nextChar, std::istream &mapFile) { if (nextChar == '\n') { x = 0; ++y; } else { x += width; } if (width > 1) { mapFile.ignore(width-1); } nextChar = mapFile.get(); } GameState::GameState(std::istream &&mapFile) { for (int i=0; i::max(), '\n'); } char nextChar = mapFile.get(); for (int x=0, y=0, width=1; y < GAME_AREA_LINES && nextChar != EOF; moveToNextChar(x, y, width, nextChar, mapFile)) { width = addEntity(x, y, nextChar); } } int GameState::addEntity(int x, int y, char type) { switch (type) { case Alien::MAP_CHAR: _aliens.push_back(Alien(x,y)); return 1; case EnemyBullet::ALIEN_MAP_CHAR: case EnemyBullet::ENEMY_MISSILE_MAP_CHAR: _bullets.push_back(EnemyBullet(x,y)); return 1; case PlayerMissile::MAP_CHAR: _missiles.push_back(PlayerMissile(x,y)); return 1; case Shield::MAP_CHAR: _shields.push_back(Shield(x,y)); return 1; case Spaceship::ENEMY_MAP_CHAR: _enemySpaceship = std::unique_ptr(new Spaceship(x+1, y)); return 3; case Spaceship::PLAYER_MAP_CHAR: _playerSpaceship = std::unique_ptr(new Spaceship(x+1, y)); return 3; case Building::MISSILE_CONTROLLER_CHAR: _missileControllers.push_back(Building(x+1, y)); return 3; case Building::ALIEN_FACTORY_CHAR: _alienFactories.push_back(Building(x+1, y)); return 3; } return 1; } void GameState::logState() const { for (auto const& alien : _aliens) { std::cout << "Alien " << alien.coords() << std::endl; } for (auto const& bullet : _bullets) { std::cout << "Enemy Bullet" << bullet.coords() << std::endl; } for (auto const& missile : _missiles) { std::cout << "Player Missile" << missile.coords() << std::endl; } for (auto const& shield : _shields) { std::cout << "Shield" << shield.coords() << std::endl; } if (_playerSpaceship) { std::cout << "Player Spaceship" << _playerSpaceship->coords() << std::endl; } if (_enemySpaceship) { std::cout << "Enemy Spaceship" << _enemySpaceship->coords() << std::endl; } } int getPyramidOffset(int bottomWidth, int maxWidth, int x, int y, int resultIfLeft, int resultIfRight) { int currentRowWidth = bottomWidth; int currentRowOffset = 0; for (int i=0; i maxWidth) { currentRowWidth = maxWidth; } } if (x > currentRowWidth/2) { return resultIfRight; } else if (x < -currentRowWidth/2) { return resultIfLeft; } else { return currentRowOffset + currentRowWidth/2 + x; } } int getRectangularOffset(int width, int x, int y) { int currentRowOffset = width*y; return currentRowOffset + width/2 + x; } std::vector GameState::toBitArray() const { std::vector result(61); int alienOffset = 0; //Aliens are 0 to 35 int bulletOffset = 36; //Bullets are 36 to 50 int shieldOffset = 51; //Shields are 51 to 53 int missileOffset = 54; //Missile info is 54 to 55 int positionOffset = 56; //Position is 56 to 58 int existingBuildingsOffset = 59; //Existing buildings is 59 int canBuildOffset = 60; //Can build here is 60 int playerX = GAME_WIDTH/2; int playerY = GAME_AREA_LINES-3; if (_playerSpaceship) { playerX = _playerSpaceship->x(); } for (auto const& alien : _aliens) { if (alien.y() > playerY-4 || alien.y() < playerY-7 || alien.x() > playerX+4 || alien.x() < playerX-4) { continue; } result.at(alienOffset + getRectangularOffset(9, alien.x()-playerX, playerY-4-alien.y())) = true; } for (auto const& bullet : _bullets) { if (bullet.y() >= playerY || bullet.y() < playerY-3 || bullet.x() > playerX+2 || bullet.x() < playerX-2) { continue; } result.at(bulletOffset + getRectangularOffset(5, bullet.x()-playerX, playerY-1-bullet.y())) = true; } for (auto const& shield : _shields) { if (shield.y() < playerY-3 || shield.x() < playerX-1 || shield.x() > playerX+1) { continue; } result.at(shieldOffset + shield.x()-playerX+1) = true; } if (_missiles.size() > 0) { result.at(missileOffset) = true; } if (_missiles.size() < 1) { result.at(missileOffset + 1) = true; } if (_playerSpaceship) { if (playerX <= GAME_WIDTH/3) { result.at(positionOffset) = true; } else if (playerX >= GAME_WIDTH*2/3) { result.at(positionOffset+2) = true; } else { result.at(positionOffset+1) = true; } } result.at(canBuildOffset) = true; for (auto const& missileController : _missileControllers) { if (missileController.y() < playerY) { continue; } result.at(existingBuildingsOffset + 0) = true; if (_missiles.size() < 2) { result.at(missileOffset+1) = true; } if (abs(missileController.x() - playerX) < 3) { result.at(canBuildOffset) = false; } } return result; }