From 8eebf1079fbed2848ee47cf990f5def5926a0c1f Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 21:24:15 +0200 Subject: Refile for merging repos --- 2015-spacebot/src/game_state.cpp | 234 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 2015-spacebot/src/game_state.cpp (limited to '2015-spacebot/src/game_state.cpp') diff --git a/2015-spacebot/src/game_state.cpp b/2015-spacebot/src/game_state.cpp new file mode 100644 index 0000000..952c2f3 --- /dev/null +++ b/2015-spacebot/src/game_state.cpp @@ -0,0 +1,234 @@ +#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; +} -- cgit v1.2.3