big bang v2

This commit is contained in:
moonleay 2025-01-19 17:59:26 +01:00
parent d48e9d7b28
commit 27589cc385
Signed by: moonleay
GPG key ID: 82667543CCD715FB
18 changed files with 2847 additions and 378 deletions

112
Entities/Entity.cpp Normal file
View file

@ -0,0 +1,112 @@
#include "Entity.h"
#include "../Environment/Maze.h"
namespace game {
Entity::Entity(const Vector2d starting_position, const char display_character): pos(starting_position), display_character(display_character), move_left(true){}
bool Entity::is_at_position(const Vector2d& position) const {
return this->pos.eq(position);
}
void Entity::tick(const Maze& maze, const Vector2d& player_position){
switch (this->display_character) {
case 'A':
// No thoughts, head empty :P
return;
case 'B':
this->handle_bowie(maze);
return;
case 'C':
this->handle_connelly(maze, player_position);
return;
default:
cout << "ERR: THIS IS NOT A GHOST!";
/// This case will never happen
return;
}
}
void Entity::handle_bowie(const Maze& maze) {
Vector2d target_position = this->pos;
if (this->move_left)
target_position.change_x(-1);
else
target_position.change_x(1);
if (maze.is_pos_free(target_position, false))
this->pos = target_position;
else
{
this->move_left = !this->move_left;
if (this->move_left)
target_position.change_x(-1);
else
target_position.change_x(1);
if (maze.is_pos_free(target_position, false))
this->pos = target_position;
}
}
bool Entity::connelly_move_up(const Maze& maze) {
Vector2d top = this->pos.get_new_updated(0, 1);
if (maze.is_pos_free(top, false)) {
this->pos = top;
return true;
}
return false;
}
bool Entity::connelly_move_down(const Maze& maze) {
Vector2d bottom = this->pos.get_new_updated(0, -1);
if (maze.is_pos_free(bottom, false)) {
this-> pos = bottom;
return true;
}
return false;
}
bool Entity::connelly_move_left(const Maze& maze) {
Vector2d left = this->pos.get_new_updated(-1, 0);
if (maze.is_pos_free(left, false)) {
this->pos = left;
return true;
}
return false;
}
bool Entity::connelly_move_right(const Maze& maze) {
Vector2d right = this->pos.get_new_updated(1, 0);
if (maze.is_pos_free(right, false)) {
this->pos = right;
return true;
}
return false;
}
void Entity::handle_connelly(const Maze& maze, const Vector2d& player_position) {
Vector2d diff = maze.get_delta_vector(player_position, this->pos);
Vector2d normalized = diff.normalize();
if ((normalized.y == normalized.x || normalized.y > normalized.x) && normalized.y != 0) {
if (diff.y > 0 ) {
if (this->connelly_move_up(maze))
return;
} else {
if (this->connelly_move_down(maze))
return;
}
}
if (normalized.x != 0) {
if (diff.x > 0){
if (this->connelly_move_right(maze))
return;
}
else {
bool _ = this->connelly_move_left(maze);
}
}
}
char Entity::get_display_character() const {
return this->display_character;
}
}

66
Entities/Entity.h Normal file
View file

@ -0,0 +1,66 @@
#include "../Util/Vector2d.h"
#ifndef ENTITY_H
#define ENTITY_H
namespace game
{
class Maze;
/// Eine Entität, z.B. ein Geist
class Entity {
private:
/// Die aktuelle Position des Geistes
Vector2d pos;
/// Wie der Geist dargestellt werden sollte
char display_character;
/// Ist wahr, wenn der Bowie nach Links läuft, falsch, wenn er nach Rechts läuft.
bool move_left;
/// Behandle Bowie Bewegungen
/// @param maze Das Labyrinth
void handle_bowie(const Maze& maze);
/// Behandle Connelly Bewegungen
/// @param maze Das Labyrinth
/// @param player_position Die Position des Spielers
void handle_connelly(const Maze& maze, const Vector2d& player_position);
/// Versuche den Connelly nach oben zu bewegen
/// @param maze Das Labyrinth
/// @returns Ob die Bewegung geglückt hat
bool connelly_move_up(const Maze& maze);
/// Versuche den Connelly nach unten zu bewegen
/// @param maze Das Labyrinth
/// @returns Ob die Bewegung geglückt hat
bool connelly_move_down(const Maze& maze);
/// Versuche den Connelly nach links zu bewegen
/// @param maze Das Labyrinth
/// @returns Ob die Bewegung geglückt hat
bool connelly_move_left(const Maze& maze);
/// Versuche den Connelly nach Rechts zu bewegen
/// @param maze Das Labyrinth
/// @returns Ob die Bewegung geglückt hat
bool connelly_move_right(const Maze& maze);
public:
Entity(Vector2d starting_position, char display_character);
/// Halte den Entität bzw. den Geist up to date, bewege ihn
/// @param maze Das Labyrinth
/// @param player_position Die Position des Spielers
void tick(const Maze& maze, const Vector2d& player_position);
/// Kontrolliere, ob sich das Entity auf einer Position befindet
/// @param position Die Position
/// @returns Ob das sich das Entity auf der Position befindet
bool is_at_position(const Vector2d& position) const;
/// Besorge dir das Zeichen, was auf dem Labyrinth angezeigt werden soll
/// @returns Das Zeichen
char get_display_character() const;
};
} // game
#endif //ENTITY_H

108
Entities/Player.cpp Normal file
View file

@ -0,0 +1,108 @@
#include "Player.h"
#include "../Environment/Maze.h"
#include "../Exceptions/MovementNotPossible.h"
#include "../Util/GameState.h"
#include "../Environment/Game.h"
using game::GameState;
using game::Game;
using game_exceptions::MovementNotPossible;
namespace game
{
Player::Player(const int target_x, const int target_y): pos(target_x, target_y), keys_in_inventory(0)
{
}
Player::Player(const Vector2d pos) : pos(pos), keys_in_inventory(0)
{
}
Vector2d Player::get_pos() const
{
return this->pos;
}
void Player::update_position(const Vector2d& target)
{
this->pos = target;
}
Maze Player::handle_move(Maze& maze, const Vector2d& move_vector)
{
const Vector2d target_position = Vector2d(this->get_pos().x + move_vector.x,
this->get_pos().y + move_vector.y);
if (maze.is_pos_free(target_position, this->has_key_available()))
{
this->update_position(target_position);
}
else
throw MovementNotPossible("Bewegung nicht moeglich!");
return maze;
}
Maze Player::handle_user_input(Maze& maze, const char& input) {
Vector2d move_vector = {0, 0};
switch (input) {
case 'w':
move_vector = {0, -1};
break;
case 's':
move_vector = {0, 1};
break;
case 'a':
move_vector = {-1, 0};
break;
case 'd':
move_vector = {1, 0};
break;
}
this->handle_move(maze, move_vector);
return maze;
}
void Player::handle_keys(Maze& maze) {
switch (maze.get_field(this->pos))
{
case 'K':
++this->keys_in_inventory;
maze.update_field(this->get_pos(), '.');
break;
case 'T':
--this->keys_in_inventory;
maze.update_field(this->get_pos(), '.');
break;
default: ;
}
}
GameState Player::handle_collisions(const Game& game, const Maze& maze) const {
char field_at_pos = maze.get_field(this->get_pos());
// Game state sanity check
if (game.get_state() != GameState::RUNNING)
return game.get_state();
if (field_at_pos == '.'){
if (game.is_enemy_at_pos(this->get_pos()))
return GameState::HIT_BY_GHOST;
return GameState::RUNNING;
}
// You are not supposed to be here!
return game.get_state();
}
GameState Player::tick(const Game& game, Maze& maze) {
this->handle_keys(maze);
return this->handle_collisions(game, maze);
}
bool Player::has_key_available() const
{
return this->keys_in_inventory > 0;
}
} // game

74
Entities/Player.h Normal file
View file

@ -0,0 +1,74 @@
#include "../Util/Vector2d.h"
#include "../Util/GameState.h"
#ifndef PLAYER_H
#define PLAYER_H
using game::GameState;
namespace game
{
class Maze;
class Game;
/// Ein Spieler.
/// Besitzt einen veränderbaren Positionsvektor
class Player
{
private:
/// Die Position des Spielers
Vector2d pos;
int keys_in_inventory;
/// Bewege den Splieler um den Bewegungsvektor, insofern die Zielposition begehbar ist
/// @param maze Das Maze
/// @param move_vector Die gewollte Bewegung
/// @return Die neue Position des Spielers
Maze handle_move(Maze& maze, const Vector2d& move_vector);
/// Gebe oder Nehme dem Spieler Schlüssel
/// Updated auch das Maze (Reference!)
/// @param maze Das Maze
void handle_keys(Maze& maze);
/// Kontrolliere, ob der Spieler gerade in einem Geist steht
/// @param maze Das Maze
GameState handle_collisions(const Game& game, const Maze& maze) const;
public:
/// Ein Spieler.
/// Besitzt einen veränderbaren Positionsvektor
/// @param target_x Die Startposition des Spielers (X-Koordinate)
/// @param target_y Die Startposition des Spielers (Y-Koordinate)
Player(int target_x, int target_y);
/// Ein Spieler
/// @param pos Die Startposition des Spielers
explicit Player(Vector2d pos);
/// Kriege die Position des Spielers
/// @return Die Position des Spielers
Vector2d get_pos() const;
/// Aktuallisiere die Position des Spielers ohne weitere Checks
/// @param target Das ziel
void update_position(const Vector2d& target);
/// Behandle die eingabe des Nutzers für den Spieler
/// @param maze Das Labyrinth
/// @param input Die Eingabe des Nutzers
Maze handle_user_input(Maze& maze, const char& input);
/// Halte den Spieler aktuell
/// @param game Das Spiel
/// @param maze Das Labyrinth
/// @returns Der Status des Spiels
GameState tick(const Game& game, Maze& maze);
/// Check, if a player has at least one key
/// @return If the player as an available key
bool has_key_available() const;
};
} // maze
#endif //PLAYER_H

108
Environment/Game.cpp Normal file
View file

@ -0,0 +1,108 @@
#include "Game.h"
#include "Maze.h"
#include "../Exceptions/MovementNotPossible.h"
#include "../Exceptions/UnkownAction.h"
#include "../Util/Vector2d.h"
using game::Player;
using game::Maze;
using game_exceptions::UnkownAction;
using game_exceptions::MovementNotPossible;
namespace game
{
Game::Game(Maze& maze) : maze(maze), player(0, 0), enemies({}), state(GameState::RUNNING), infomode_enabled(false)
{
Vector2d player_start_position = this->maze.get_player_start_position();
this->player = Player(player_start_position);
this->enemies = maze.get_entities();
}
GameState Game::get_state() const {
return this->state;
}
void Game::handle_user_input(const char& input)
{
switch (input)
{
case 'w':
case 'a':
case 's':
case 'd':
break;
case 'i':
this->infomode_enabled = !this->infomode_enabled;
break;
case 'q':
this->state = GameState::QUITTING;
break;
case 'h':
cout <<
"Du wurdest von einem Zauberer in ein Labyrinth gesperrt, nachdem du seine Künste beleidigt hast.\n"
<< "Er laesst dich leben, wenn du es schaffst den Ausgang (Z) zu finden. Solltest du keinen Erfolg haben, laesst er dich verhungern.\n"
<< "Auf deinem Abenteuer wirst du dabei boesen Geistern (A) begegnen und mit Schluesseln (K) Tueren (T) aufschliessen.\n"
<< "Bewege dich mit 'w', 'a', 's' und 'd'.\n";
break;
default:
throw UnkownAction("Diese Eingabe kenne ich nicht. Gib 'h' ein, um eine Hilfe zu erhalten.");
}
}
bool Game::is_enemy_at_pos(const Vector2d& position) const {
for (Entity e : this->enemies)
if (e.is_at_position(position))
return true;
return false;
}
bool Game::should_end_game() const
{
return this->state != GameState::RUNNING;
}
void Game::run_game()
{
char game_input;
// Hauptschleife
while (true)
{
this->maze.render(this->player, this->enemies, this->infomode_enabled);
if (this->maze.is_player_at_goal(this->player))
{
cout << "Ziel erreicht! Herzlichen Glueckwunsch!\n";
break;
}
cin >> game_input;
if (!cin)
this->state = GameState::QUITTING;
try
{
this->handle_user_input(game_input);
this->player.handle_user_input(this->maze, game_input);
} catch (UnkownAction& err)
{
cout << err.what() << "\n";
} catch (MovementNotPossible& err)
{
cout << err.what() << "\n";
}
this->state = this->player.tick(*this, this->maze);
for (Entity& e : this->enemies)
e.tick(this->maze, this->player.get_pos());
this->state = this->player.tick(*this, this->maze);
if (this->should_end_game())
return;
}
}
} // game

54
Environment/Game.h Normal file
View file

@ -0,0 +1,54 @@
#include "Maze.h"
#include "../Entities/Player.h"
#include "../Util/GameState.h"
#include "../Entities/Entity.h"
#ifndef GAME_H
#define GAME_H
namespace game
{
/// Eine Instanz des Spiels
class Game
{
private:
/// Das Labyrinth
Maze maze;
/// Der Spieler
Player player;
/// Die Gegner des Spieles
vector<Entity> enemies;
/// Der Status des Spiels
GameState state;
///
bool infomode_enabled;
public:
explicit Game(Maze& maze);
/// Bearbeite die Eingabe des Spielers
/// @param input Die Eingabe des Nutzers
/// @return Der Bewegungsvektor, um den sich den Spieler bewegen möchte
/// @throws UnkownAction Wenn die Eingabe des Spielers unbekannt ist
void handle_user_input(const char& input);
/// Kontrolliere, ob das Spiel beendet werden sollte
bool should_end_game() const;
/// Starte das Spiel
void run_game();
/// Kriege den aktuellen Status des Spiels
/// @returns Den aktuellen Status
GameState get_state() const;
/// Krontroliere ob ein Geist sich an einer Position befindet
/// @param position Die Position
/// @returns Ob sich dort ein Geist aufhält
bool is_enemy_at_pos(const Vector2d& position) const ;
};
} // game
#endif //GAME_H

162
Environment/Maze.cpp Normal file
View file

@ -0,0 +1,162 @@
#include "Maze.h"
#include "../Entities/Entity.h"
#include "../Entities/Player.h"
#include "../Exceptions/MalformedMaze.h"
using game_exceptions::MalformedMaze;
namespace game {
/// Ist eine Konstante, darf also in global scope
static const vector<char> valid_maze_elements = {'Z', '.', '#', 'A', 'K', 'T', 'B', 'C'};
/// Welche Geistertypen es gibt
static const vector<char> valid_enemies = {'A', 'B', 'C'};
/// Die Maximale Labyrinthgröße
static constexpr int MAX_MAZE_SIZE = 20;
Maze::Maze(const vector<vector<char>> &play_field, const vector<int> &player_start_position,
const vector<Entity> &enemies) :
field(play_field), player_start_position(Vector2d{player_start_position[1], player_start_position[0]}),
enemies(enemies) {
if (!this->is_pos_free(this->player_start_position, false))
throw MalformedMaze("Player oob");
}
bool Maze::was_player_killed_by_ghost(const Player &player) const {
return this->field[player.get_pos().y][player.get_pos().x] == 'A';
}
bool Maze::is_player_at_goal(const Player &player) const {
return this->field[player.get_pos().y][player.get_pos().x] == 'Z';
}
bool Maze::is_pos_free(const Vector2d &pos, const bool &player_has_key) const {
if (pos.x < 0 || pos.y < 0 || pos.y > field.size() - 1 || pos.x > field[pos.y].size() - 1)
return false;
if (field[pos.y][pos.x] == '#')
return false;
if (field[pos.y][pos.x] == 'T')
return player_has_key;
return true;
}
void Maze::render(const Player &player, const vector<Entity> &entities, const bool &infomode_enabled) {
for (int y = 0; y < field.size(); ++y) {
for (int x = 0; x < field[y].size(); ++x) {
if (y == player.get_pos().y && x == player.get_pos().x)
cout << "S";
else {
bool an_enemy_is_at_this_position = false;
for (Entity e: entities)
if (e.is_at_position({x, y})) {
an_enemy_is_at_this_position = true;
cout << e.get_display_character();
}
if (!an_enemy_is_at_this_position)
cout << field[y][x];
}
cout << " ";
}
if (y == 0 && infomode_enabled) {
const int steps = this->calculate_steps_until_win(player.get_pos(), 5);
if (steps < 999)
cout << steps << " Schritte bis zum Ziel";
}
cout << "\n";
}
}
char Maze::get_field(const Vector2d &pos) const { return this->field[pos.y][pos.x]; }
void Maze::update_field(const Vector2d &pos, const char &target) { this->field[pos.y][pos.x] = target; }
Vector2d Maze::get_player_start_position() const { return this->player_start_position; }
Vector2d Maze::get_delta_vector(const Vector2d &pos1, const Vector2d &pos2) const {
int x_diff = pos1.x - pos2.x;
int y_diff = pos1.y - pos2.y;
return {x_diff, y_diff};
}
int Maze::calculate_steps_until_win(Vector2d position, const int &steps) {
if (!this->is_pos_free(position, false))
return 999;
if (this->get_field(position) == 'Z')
return 0;
if (steps <= 0)
return 999;
return 1 + std::min({this->calculate_steps_until_win(position.get_new_updated(0, -1), steps - 1),
this->calculate_steps_until_win(position.get_new_updated(0, 1), steps - 1),
this->calculate_steps_until_win(position.get_new_updated(1, 0), steps - 1),
this->calculate_steps_until_win(position.get_new_updated(-1, 0), steps - 1)});
}
vector<Entity> Maze::get_entities() { return this->enemies; }
vector<int> Maze::request_numbers_from_user(const int &amount_of_numbers) {
int input;
vector<int> list;
for (int i = 0; i < amount_of_numbers; ++i) {
cin >> input;
if (!cin)
throw MalformedMaze("Cin failed while reading numbers!");
if (input > MAX_MAZE_SIZE)
throw MalformedMaze("This maze is too big");
list.push_back(input);
}
return list;
}
bool Maze::validate_maze_element(const char &target) {
for (const char c: valid_maze_elements)
if (c == target)
return true;
return false;
}
bool Maze::is_valid_enemy(const char &target) {
for (const char c: valid_enemies)
if (c == target)
return true;
return false;
}
Maze Maze::request_maze_from_user() {
vector<int> maze_size = request_numbers_from_user(2);
char input;
vector<vector<char>> field;
vector<Entity> enemies;
for (int y = 0; y < maze_size[0]; ++y) {
vector<char> row;
for (int x = 0; x < maze_size[1]; ++x) {
cin >> input;
if (!cin)
throw MalformedMaze("Cin failed while reading chars!");
// I don't think that this is needed. I doubt that they test the check for this one ~Eric
// if (input == 'q')
// throw ExitGame("Schoenen Tag noch!");
if (!validate_maze_element(input))
throw MalformedMaze("The given input is not a valid element of a maze!");
if (is_valid_enemy(input)) {
enemies.push_back(Entity({x, y}, input));
row.push_back('.');
} else {
row.push_back(input);
}
}
field.push_back(row);
}
vector<int> player_start_pos = request_numbers_from_user(2);
return {field, player_start_pos, enemies};
} // Beispieleingabe: `4 3 #.# #.K #T# #Z# 0 1`
} // namespace game

113
Environment/Maze.h Normal file
View file

@ -0,0 +1,113 @@
#ifndef MAZE_H
#define MAZE_H
#include "../Util/Vector2d.h"
#include "../std_lib_inc.h"
namespace game {
class Player;
class Entity;
/// Ist eine Konstante, darf also in global scope
/// Ein Labyrinth.
/// Besitzt ein Feld
class Maze {
// class -> members private by default
private:
/// Das Spielfeld
vector<vector<char>> field;
/// Die Startposition des Spielers
Vector2d player_start_position;
/// Eine Liste an Gegnern
vector<Entity> enemies;
/// Erlaubte Zeichen in einem Labyrinth
/* Legende
* S - Spieler
* Z - Ziel
* . - Leerer Raum (begehbar)
* # - Wand
* A - Animaltronic
* K - Schlüssel
* T - Tür
* B - Bowie
* C - Connellys
*/
public:
/// Das Spielfeld
Maze(const Vector<Vector<char>> &play_field, const Vector<int> &player_start_position,
const Vector<Entity> &enemies);
/// Kontrolliere, ob der Spieler stirbt
/// @param player Der Spieler
/// @return Ob der Spieler tot ist
bool was_player_killed_by_ghost(const Player &player) const;
/// Kontrolliere, ob der Spieler am Ziel ist
/// @param player Der Spieler
/// @return Ob der Spieler am Ziel ist
bool is_player_at_goal(const Player &player) const;
/// Kontrolliere, ob eine bestimmte Position begehbar ist
/// @param pos Die Position, die überprüft werden soll
/// @param player_has_key If the player has at least one key
/// @return Ob die Position begehbar ist
bool is_pos_free(const Vector2d &pos, const bool &player_has_key) const;
/// Zeige das Spielfeld in der Konsole an
/// @param player Der Spieler
/// @param entities Die Entities auf dem Spielfeld
/// @param infomode_enabled Ob der Infomode aktiv ist
void render(const Player &player, const vector<Entity> &entities, const bool &infomode_enabled);
/// Kriege den Wert einer Position
/// @param pos Die gewollte Position
/// @return Der Wert der Position
char get_field(const Vector2d &pos) const;
/// Ersetze den Wert von einer Position
/// @param pos Die Position die ersetzt werden soll
/// @param target Der Wert, auf den die Position gesetzt werden soll
void update_field(const Vector2d &pos, const char &target);
/// Kriege die Startposition des Spielers
/// @return Die Startposition des Spielers
Vector2d get_player_start_position() const;
/// Berrechne den Abstand zwischen zwei Vektoren
/// @return Der Abstand als Differenzvektor
Vector2d get_delta_vector(const Vector2d &pos1, const Vector2d &pos2) const;
/// Berechne wie viele Schritte benötigt werden, um das Labyrinth zu schaffen
/// @warning Steps nicht zu groß setzen! Diese Funktion ist 4-fach rekursiv!
/// @param position Die Startposition
/// @param steps Wie viele Schritte maximal gegangen werden sollten
/// @returns Wie viele Schritte benötigt werden
int calculate_steps_until_win(Vector2d position, const int &steps);
/// Kriege alle eingelesenen Entities
vector<Entity> get_entities();
/// Lese ein Labyrinth aus der Konsole
/// @return Das Labyrinth
/// @throws runtime_exception Falls die Eingabe nicht korrekt verlaufen ist.
static Maze request_maze_from_user();
private:
/// Lese eine bestimmte Anzahl an Nummern aus der Konsole
/// @param amount_of_numbers Wie viele Nummern eingelesen werden sollen
/// @return Die eingelesenen Nummern
static vector<int> request_numbers_from_user(const int &amount_of_numbers);
/// Kontrolliere, ob ein Zeichen im Labyrinth vorkommen darf
/// @param target Das Zeichen, welches Kontrolliert werden soll
/// @return Ob das gegebene Zeichen in einem Labyrinth vorkommen darf
static bool validate_maze_element(const char &target);
/// Ob der angegebene char in valider Geist ist
/// @param target Der zu kontrollierende Wert
/// @returns Ob der Wert ein Valider Geist ist
static bool is_valid_enemy(const char &target);
};
} // namespace game
#endif // MAZE_H

View file

@ -0,0 +1,23 @@
#include "../std_lib_inc.h"
#ifndef MALFORMEDMAZE_H
#define MALFORMEDMAZE_H
namespace game_exceptions
{
class MalformedMaze
{
string why;
public:
MalformedMaze(string why): why(why)
{
}
string what()
{
return this->why;
}
};
} // game_exceptions
#endif //MALFORMEDMAZE_H

View file

@ -0,0 +1,23 @@
#include "../std_lib_inc.h"
#ifndef MOVEMENTNOTPOSSIBLE_H
#define MOVEMENTNOTPOSSIBLE_H
namespace game_exceptions
{
class MovementNotPossible
{
string why;
public:
MovementNotPossible(string why): why(why)
{
}
string what()
{
return this->why;
}
};
} // game_exceptions
#endif //MOVEMENTNOTPOSSIBLE_H

23
Exceptions/UnkownAction.h Normal file
View file

@ -0,0 +1,23 @@
#include "../std_lib_inc.h"
#ifndef UNKOWNACTION_H
#define UNKOWNACTION_H
namespace game_exceptions
{
class UnkownAction
{
string why;
public:
UnkownAction(string why): why(why)
{
}
string what()
{
return this->why;
}
};
} // game_exceptions
#endif //UNKOWNACTION_H

15
Util/GameState.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef GAMESTATE_H
#define GAMESTATE_H
namespace game
{
/// Beschreibt den aktuellen GameState
enum class GameState
{
RUNNING,
HIT_BY_GHOST,
QUITTING,
};
} // game
#endif //GAMESTATE_H

47
Util/Vector2d.cpp Normal file
View file

@ -0,0 +1,47 @@
#include "Vector2d.h"
namespace game
{
Vector2d::Vector2d(const int x, const int y)
{
this->x = x;
this->y = y;
}
void Vector2d::update(const int& x, const int& y)
{
this->x = x;
this->y = y;
}
void Vector2d::change_x(const int& amount) {
this->x += amount;
}
void Vector2d::change_y(const int& amount) {
this->y += amount;
}
Vector2d Vector2d::normalize() {
Vector2d v = *this;
if (v.x < 0)
v.x *= -1;
if (v.y < 0)
v.y *= -1;
return v;
}
bool Vector2d::eq(const Vector2d& position) const {
return this->x == position.x && this->y == position.y;
}
Vector2d Vector2d::get_new_updated(const int& diff_x, const int& diff_y) const {
Vector2d new_position = *this;
new_position.change_x(diff_x);
new_position.change_y(diff_y);
return new_position;
}
} // game

51
Util/Vector2d.h Normal file
View file

@ -0,0 +1,51 @@
#ifndef POSITION_H
#define POSITION_H
namespace game
{
/// Ein Vector aus zwei zahlen.
/// Kann eine Position oder eine Differenz zwischen zwei Positionen darstellen.
struct Vector2d
{
// struct -> members public by default
// Die beiden Variablen des Vectors
int x;
int y;
/// Ein Vector aus zwei zahlen.
/// Kann eine Position oder eine Differenz zwischen zwei Positionen darstellen.
/// @param x Die 'X'-Koordinate
/// @param y Die 'Y'-Koordinate
Vector2d(int x, int y);
/// Aktualisiere die Werte des Vectors
/// @param x Die neue 'X'-Koordinate
/// @param y Die neue 'Y'-Koordinate
void update(const int& x, const int& y);
/// Verschiebe den X Wert des Vektors um eine Anzahl
/// @param amount Die zu verschiebene Anzahl
void change_x(const int& amount);
/// Verschiebe den Y Wert des Vektors um eine Anzhal
/// @param amount Die zu verschiebene Anzahl
void change_y(const int& amount);
/// Kriege einen normalisierten Vektor zurück
/// @returns Den aktuellen Vektor als normalisierter Vektor
Vector2d normalize();
/// Kontrolliere, ob ein Vektor einem anderen Enspricht
/// @param position Die Position mit der verglichen werden soll
/// @returns Ob die Position die gleiche ist
bool eq(const Vector2d& position) const;
/// Kriege einen Vektor, der mit den gegebenen Werten verschoben worden ist
/// @param diff_x Die Verschiebung auf der X-Achse
/// @param diff_y Die Verschiebung auf der Y-Achse
/// @returns Den berrechneten Vektor
Vector2d get_new_updated(const int& diff_x, const int& diff_y) const;
};
} // game
#endif //POSITION_H

View file

@ -0,0 +1,904 @@
#ifdef __cplusplus
# error "A C++ compiler has been selected for C."
#endif
#if defined(__18CXX)
# define ID_VOID_MAIN
#endif
#if defined(__CLASSIC_C__)
/* cv-qualifiers did not exist in K&R C */
# define const
# define volatile
#endif
#if !defined(__has_include)
/* If the compiler does not have __has_include, pretend the answer is
always no. */
# define __has_include(x) 0
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
except that a few beta releases use the old format with V=2021. */
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
/* The third version component from --version is an update index,
but no macro is provided for it. */
# define COMPILER_VERSION_PATCH DEC(0)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
# define COMPILER_ID "IntelLLVM"
#if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
#endif
#if defined(__GNUC__)
# define SIMULATE_ID "GNU"
#endif
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
* VVVV is no smaller than the current year when a version is released.
*/
#if __INTEL_LLVM_COMPILER < 1000000L
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
#else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
#endif
#if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
#endif
#if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
#elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
#endif
#if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
#endif
#if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
#endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_C)
# define COMPILER_ID "SunPro"
# if __SUNPRO_C >= 0x5100
/* __SUNPRO_C = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
# endif
#elif defined(__HP_cc)
# define COMPILER_ID "HP"
/* __HP_cc = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100)
#elif defined(__DECC)
# define COMPILER_ID "Compaq"
/* __DECC_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000)
#elif defined(__IBMC__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__open_xl__) && defined(__clang__)
# define COMPILER_ID "IBMClang"
# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__)
# define COMPILER_VERSION_MINOR DEC(__open_xl_release__)
# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800
# define COMPILER_ID "XL"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__NVCOMPILER)
# define COMPILER_ID "NVHPC"
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
# if defined(__NVCOMPILER_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
# endif
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(__clang__) && defined(__cray__)
# define COMPILER_ID "CrayClang"
# define COMPILER_VERSION_MAJOR DEC(__cray_major__)
# define COMPILER_VERSION_MINOR DEC(__cray_minor__)
# define COMPILER_VERSION_PATCH DEC(__cray_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__CLANG_FUJITSU)
# define COMPILER_ID "FujitsuClang"
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__FUJITSU)
# define COMPILER_ID "Fujitsu"
# if defined(__FCC_version__)
# define COMPILER_VERSION __FCC_version__
# elif defined(__FCC_major__)
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# endif
# if defined(__fcc_version)
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
# elif defined(__FCC_VERSION)
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
# endif
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__TASKING__)
# define COMPILER_ID "Tasking"
# define COMPILER_VERSION_MAJOR DEC(__VERSION__/1000)
# define COMPILER_VERSION_MINOR DEC(__VERSION__ % 100)
# define COMPILER_VERSION_INTERNAL DEC(__VERSION__)
#elif defined(__ORANGEC__)
# define COMPILER_ID "OrangeC"
# define COMPILER_VERSION_MAJOR DEC(__ORANGEC_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__ORANGEC_MINOR__)
# define COMPILER_VERSION_PATCH DEC(__ORANGEC_PATCHLEVEL__)
#elif defined(__TINYC__)
# define COMPILER_ID "TinyCC"
#elif defined(__BCC__)
# define COMPILER_ID "Bruce"
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION/100 % 100)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__) && defined(__ti__)
# define COMPILER_ID "TIClang"
# define COMPILER_VERSION_MAJOR DEC(__ti_major__)
# define COMPILER_VERSION_MINOR DEC(__ti_minor__)
# define COMPILER_VERSION_PATCH DEC(__ti_patchlevel__)
# define COMPILER_VERSION_INTERNAL DEC(__ti_version__)
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))
# define COMPILER_ID "LCC"
# define COMPILER_VERSION_MAJOR DEC(__LCC__ / 100)
# define COMPILER_VERSION_MINOR DEC(__LCC__ % 100)
# if defined(__LCC_MINOR__)
# define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__)
# endif
# if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define SIMULATE_ID "GNU"
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
# endif
#elif defined(__GNUC__)
# define COMPILER_ID "GNU"
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(_ADI_COMPILER)
# define COMPILER_ID "ADSP"
#if defined(__VERSIONNUM__)
/* __VERSIONNUM__ = 0xVVRRPPTT */
# define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF)
# define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF)
# define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF)
# define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
#elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC)
# define COMPILER_ID "SDCC"
# if defined(__SDCC_VERSION_MAJOR)
# define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR)
# define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR)
# define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH)
# else
/* SDCC = VRP */
# define COMPILER_VERSION_MAJOR DEC(SDCC/100)
# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10)
# define COMPILER_VERSION_PATCH DEC(SDCC % 10)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__MSYS__)
# define PLATFORM_ID "MSYS"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# elif defined(__VXWORKS__)
# define PLATFORM_ID "VxWorks"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
# elif defined(_ADI_COMPILER)
# define PLATFORM_ID "ADSP"
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_ARM64EC)
# define ARCHITECTURE_ID "ARM64EC"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# elif defined(__ICCSTM8__)
# define ARCHITECTURE_ID "STM8"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__clang__) && defined(__ti__)
# if defined(__ARM_ARCH)
# define ARCHITECTURE_ID "Arm"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__TI_COMPILER_VERSION__)
# if defined(__TI_ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__MSP430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__TMS320C28XX__)
# define ARCHITECTURE_ID "TMS320C28x"
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
# define ARCHITECTURE_ID "TMS320C6x"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
# elif defined(__ADSPSHARC__)
# define ARCHITECTURE_ID "SHARC"
# elif defined(__ADSPBLACKFIN__)
# define ARCHITECTURE_ID "Blackfin"
#elif defined(__TASKING__)
# if defined(__CTC__) || defined(__CPTC__)
# define ARCHITECTURE_ID "TriCore"
# elif defined(__CMCS__)
# define ARCHITECTURE_ID "MCS"
# elif defined(__CARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__CARC__)
# define ARCHITECTURE_ID "ARC"
# elif defined(__C51__)
# define ARCHITECTURE_ID "8051"
# elif defined(__CPCP__)
# define ARCHITECTURE_ID "PCP"
# else
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number. */
#ifdef COMPILER_VERSION
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
/* Construct a string literal encoding the version number components. */
#elif defined(COMPILER_VERSION_MAJOR)
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#elif defined(COMPILER_VERSION_INTERNAL_STR)
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#define C_STD_99 199901L
#define C_STD_11 201112L
#define C_STD_17 201710L
#define C_STD_23 202311L
#ifdef __STDC_VERSION__
# define C_STD __STDC_VERSION__
#endif
#if !defined(__STDC__) && !defined(__clang__)
# if defined(_MSC_VER) || defined(__ibmxl__) || defined(__IBMC__)
# define C_VERSION "90"
# else
# define C_VERSION
# endif
#elif C_STD > C_STD_17
# define C_VERSION "23"
#elif C_STD > C_STD_11
# define C_VERSION "17"
#elif C_STD > C_STD_99
# define C_VERSION "11"
#elif C_STD >= C_STD_99
# define C_VERSION "99"
#else
# define C_VERSION "90"
#endif
const char* info_language_standard_default =
"INFO" ":" "standard_default[" C_VERSION "]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__)
"ON"
#else
"OFF"
#endif
"]";
/*--------------------------------------------------------------------------*/
#ifdef ID_VOID_MAIN
void main() {}
#else
# if defined(__CLASSIC_C__)
int main(argc, argv) int argc; char *argv[];
# else
int main(int argc, char* argv[])
# endif
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
require += info_arch[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_standard_default[argc];
require += info_language_extensions_default[argc];
(void)argv;
return require;
}
#endif

View file

@ -0,0 +1,919 @@
/* This source file must have a .cpp extension so that all C++ compilers
recognize the extension without flags. Borland does not know .cxx for
example. */
#ifndef __cplusplus
# error "A C compiler has been selected for C++."
#endif
#if !defined(__has_include)
/* If the compiler does not have __has_include, pretend the answer is
always no. */
# define __has_include(x) 0
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
except that a few beta releases use the old format with V=2021. */
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
/* The third version component from --version is an update index,
but no macro is provided for it. */
# define COMPILER_VERSION_PATCH DEC(0)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
# define COMPILER_ID "IntelLLVM"
#if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
#endif
#if defined(__GNUC__)
# define SIMULATE_ID "GNU"
#endif
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
* VVVV is no smaller than the current year when a version is released.
*/
#if __INTEL_LLVM_COMPILER < 1000000L
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
#else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
#endif
#if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
#endif
#if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
#elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
#endif
#if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
#endif
#if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
#endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_CC)
# define COMPILER_ID "SunPro"
# if __SUNPRO_CC >= 0x5100
/* __SUNPRO_CC = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# endif
#elif defined(__HP_aCC)
# define COMPILER_ID "HP"
/* __HP_aCC = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
#elif defined(__DECCXX)
# define COMPILER_ID "Compaq"
/* __DECCXX_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__open_xl__) && defined(__clang__)
# define COMPILER_ID "IBMClang"
# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__)
# define COMPILER_VERSION_MINOR DEC(__open_xl_release__)
# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
# define COMPILER_ID "XL"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__NVCOMPILER)
# define COMPILER_ID "NVHPC"
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
# if defined(__NVCOMPILER_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
# endif
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(__clang__) && defined(__cray__)
# define COMPILER_ID "CrayClang"
# define COMPILER_VERSION_MAJOR DEC(__cray_major__)
# define COMPILER_VERSION_MINOR DEC(__cray_minor__)
# define COMPILER_VERSION_PATCH DEC(__cray_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__CLANG_FUJITSU)
# define COMPILER_ID "FujitsuClang"
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__FUJITSU)
# define COMPILER_ID "Fujitsu"
# if defined(__FCC_version__)
# define COMPILER_VERSION __FCC_version__
# elif defined(__FCC_major__)
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# endif
# if defined(__fcc_version)
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
# elif defined(__FCC_VERSION)
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
# endif
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__TASKING__)
# define COMPILER_ID "Tasking"
# define COMPILER_VERSION_MAJOR DEC(__VERSION__/1000)
# define COMPILER_VERSION_MINOR DEC(__VERSION__ % 100)
# define COMPILER_VERSION_INTERNAL DEC(__VERSION__)
#elif defined(__ORANGEC__)
# define COMPILER_ID "OrangeC"
# define COMPILER_VERSION_MAJOR DEC(__ORANGEC_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__ORANGEC_MINOR__)
# define COMPILER_VERSION_PATCH DEC(__ORANGEC_PATCHLEVEL__)
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION/100 % 100)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__) && defined(__ti__)
# define COMPILER_ID "TIClang"
# define COMPILER_VERSION_MAJOR DEC(__ti_major__)
# define COMPILER_VERSION_MINOR DEC(__ti_minor__)
# define COMPILER_VERSION_PATCH DEC(__ti_patchlevel__)
# define COMPILER_VERSION_INTERNAL DEC(__ti_version__)
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))
# define COMPILER_ID "LCC"
# define COMPILER_VERSION_MAJOR DEC(__LCC__ / 100)
# define COMPILER_VERSION_MINOR DEC(__LCC__ % 100)
# if defined(__LCC_MINOR__)
# define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__)
# endif
# if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define SIMULATE_ID "GNU"
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
# endif
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_ID "GNU"
# if defined(__GNUC__)
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# else
# define COMPILER_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(_ADI_COMPILER)
# define COMPILER_ID "ADSP"
#if defined(__VERSIONNUM__)
/* __VERSIONNUM__ = 0xVVRRPPTT */
# define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF)
# define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF)
# define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF)
# define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__MSYS__)
# define PLATFORM_ID "MSYS"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# elif defined(__VXWORKS__)
# define PLATFORM_ID "VxWorks"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
# elif defined(_ADI_COMPILER)
# define PLATFORM_ID "ADSP"
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_ARM64EC)
# define ARCHITECTURE_ID "ARM64EC"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# elif defined(__ICCSTM8__)
# define ARCHITECTURE_ID "STM8"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__clang__) && defined(__ti__)
# if defined(__ARM_ARCH)
# define ARCHITECTURE_ID "Arm"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__TI_COMPILER_VERSION__)
# if defined(__TI_ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__MSP430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__TMS320C28XX__)
# define ARCHITECTURE_ID "TMS320C28x"
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
# define ARCHITECTURE_ID "TMS320C6x"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
# elif defined(__ADSPSHARC__)
# define ARCHITECTURE_ID "SHARC"
# elif defined(__ADSPBLACKFIN__)
# define ARCHITECTURE_ID "Blackfin"
#elif defined(__TASKING__)
# if defined(__CTC__) || defined(__CPTC__)
# define ARCHITECTURE_ID "TriCore"
# elif defined(__CMCS__)
# define ARCHITECTURE_ID "MCS"
# elif defined(__CARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__CARC__)
# define ARCHITECTURE_ID "ARC"
# elif defined(__C51__)
# define ARCHITECTURE_ID "8051"
# elif defined(__CPCP__)
# define ARCHITECTURE_ID "PCP"
# else
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number. */
#ifdef COMPILER_VERSION
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
/* Construct a string literal encoding the version number components. */
#elif defined(COMPILER_VERSION_MAJOR)
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#elif defined(COMPILER_VERSION_INTERNAL_STR)
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#define CXX_STD_98 199711L
#define CXX_STD_11 201103L
#define CXX_STD_14 201402L
#define CXX_STD_17 201703L
#define CXX_STD_20 202002L
#define CXX_STD_23 202302L
#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG)
# if _MSVC_LANG > CXX_STD_17
# define CXX_STD _MSVC_LANG
# elif _MSVC_LANG == CXX_STD_17 && defined(__cpp_aggregate_paren_init)
# define CXX_STD CXX_STD_20
# elif _MSVC_LANG > CXX_STD_14 && __cplusplus > CXX_STD_17
# define CXX_STD CXX_STD_20
# elif _MSVC_LANG > CXX_STD_14
# define CXX_STD CXX_STD_17
# elif defined(__INTEL_CXX11_MODE__) && defined(__cpp_aggregate_nsdmi)
# define CXX_STD CXX_STD_14
# elif defined(__INTEL_CXX11_MODE__)
# define CXX_STD CXX_STD_11
# else
# define CXX_STD CXX_STD_98
# endif
#elif defined(_MSC_VER) && defined(_MSVC_LANG)
# if _MSVC_LANG > __cplusplus
# define CXX_STD _MSVC_LANG
# else
# define CXX_STD __cplusplus
# endif
#elif defined(__NVCOMPILER)
# if __cplusplus == CXX_STD_17 && defined(__cpp_aggregate_paren_init)
# define CXX_STD CXX_STD_20
# else
# define CXX_STD __cplusplus
# endif
#elif defined(__INTEL_COMPILER) || defined(__PGI)
# if __cplusplus == CXX_STD_11 && defined(__cpp_namespace_attributes)
# define CXX_STD CXX_STD_17
# elif __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi)
# define CXX_STD CXX_STD_14
# else
# define CXX_STD __cplusplus
# endif
#elif (defined(__IBMCPP__) || defined(__ibmxl__)) && defined(__linux__)
# if __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi)
# define CXX_STD CXX_STD_14
# else
# define CXX_STD __cplusplus
# endif
#elif __cplusplus == 1 && defined(__GXX_EXPERIMENTAL_CXX0X__)
# define CXX_STD CXX_STD_11
#else
# define CXX_STD __cplusplus
#endif
const char* info_language_standard_default = "INFO" ":" "standard_default["
#if CXX_STD > CXX_STD_23
"26"
#elif CXX_STD > CXX_STD_20
"23"
#elif CXX_STD > CXX_STD_17
"20"
#elif CXX_STD > CXX_STD_14
"17"
#elif CXX_STD > CXX_STD_11
"14"
#elif CXX_STD >= CXX_STD_11
"11"
#else
"98"
#endif
"]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__)
"ON"
#else
"OFF"
#endif
"]";
/*--------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
require += info_arch[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_standard_default[argc];
require += info_language_extensions_default[argc];
(void)argv;
return require;
}

414
main.cpp
View file

@ -1,395 +1,53 @@
/*
* Ein verbessertes Labyrinth-Spiel
* Autor: Fritz Bökler (fboekler@uos.de)
* Datum: 02.12.2024
* MIT Lizenz
*
* In diesem Spiel versucht eine SpielerIn (S) das Ziel (Z) zu erreichen.
* Das Labyrinth wird ueber die Konsole (cout) ausgegeben, die Eingabe erfolgt ebenfalls
* zeilengepuffert ueber die Konsole (cin).
*
* Das Labyrinth enthält die folgenden Zeichen:
* . Leeres Feld
* # Wand (nicht begehbar)
* Z Ziel
* S SpielerIn (wird nicht im Labyrint selbst gespeichert)
* K Schluessel
* T Tür
* A Geist
*
* Eine SpielerIn hat eine Anzahl an Schlüsseln. Diese Anzahl wird beim Erreichen eines
* K-Feldes erhöht und beim Erreichen eines T-Feldes reduziert. Eine Tür kann nur durchschritten
* werden, wenn die SpielerIn mindestens einen Schluessel besitzt. Ein aufgenommener Schluessel
* verschwindet (wird zu .), ebenso wie eine durchschrittene Tuer.
*
* Die folgenden Eingaben sind gültig:
* w - nach oben bewegen
* a - nach links bewegen
* s - nach unten bewegen
* d - nach rechts bewegen
* q - Spiel beenden
*
* Das Labyrnith wird zu Beginn eingegeben.
* Syntax: <Zeilen> <Spalte> <Labyrinth-Zeichen> <Spieler Zeile> <Spieler Spalte>
* <Zeilen>: 1 bis 20
* <Spalten>: 1 bis 20
* <Labyrint-Zeichen>: Eine Folge von <Zeilen> * <Spalten> vielen Zeichen aus {., #, Z, K, T, A}
* <Spieler Zeile>: 0 bis <Zeilen> - 1
* <Spieler Spalte>: 0 bis <Spalten> - 1
*
* Ein Beispiellabyrinth: 7 7 ...#....#...#T..####Z#....##K###.#......A#.###### 0 4
*/
#include "Environment/Maze.h"
#include "Environment/Game.h"
#include "Exceptions/MalformedMaze.h"
#include "Util/GameState.h"
#include "std_lib_inc.h"
using game::Maze;
using game::Game;
using game::GameState;
// Exception fuer nicht erlaubte Bewegungen
class BadMovement {};
using game_exceptions::MalformedMaze;
// Exception fuer unbekannte Eingaben
class UnknownInput {};
// Ein Programm, welches dir erlaubt ein Labyrinth zu erkunden mit 'w', 'a', 's', und 'd'.
// Exception fuer eine falsche Labyrinth-Eingabe
class BadMaze {};
// Klasse, die eine SpielerIn kapselt
class Player
{
public:
int no_keys; // Anzahl der Schlüssel der SpielerIn
vector<int> position; // Aktuelle Position der SpielerIn im Labyrinth
};
// Klasse, die das Labyrinth kapselt
class Maze
{
public:
int rows; // Anzahl der Zeilen des Labyrinths
int cols; // Anzahl der Spalten des Labyrinths
vector<vector<char>> data; // Labyrinth-Daten (erst Zeilen dann Spalten)
vector<int> player_start_position; // Startposition der SpielerIn, so wie es in der Übergabe steht
};
// Fasst Labyrinth und Spieler zu einem Spiel-Status zusammen
class GameState
{
public:
Maze maze; // Das Labyrinth
Player player; // Die SpielerIn
bool exit; // Wurde 'q' gerdückt?
bool hit_ghost; // Wurde ein Geist getroffen?
};
// Funktion zur Anzeige des Spielfeldes
void display_maze(GameState game_state)
{
const int player_row = game_state.player.position[0];
const int player_col = game_state.player.position[1];
//cout << "\033[H\033[J"; // ANSI Escape Code zum Loeschen des Bildschirms
for(int i = 0; i < game_state.maze.rows; i++)
{
for(int j = 0; j < game_state.maze.cols; j++)
{
if(i == player_row && j == player_col)
{
cout << 'S';
}
else
{
cout << game_state.maze.data[i][j];
}
cout << " ";
}
cout << '\n';
}
}
// Funktion zur Umrechnung eines Kommandos zu einer neuen Position
// Vorbedingung: direction muss aus {w, s, a, d} kommen.
vector<int> new_position_by_direction(vector<int> player_position, char direction)
{
const int row = player_position[0];
const int col = player_position[1];
switch(direction)
{
case 'w':
return {row - 1, col};
case 's':
return {row + 1, col};
case 'a':
return {row, col - 1};
case 'd':
return {row, col + 1};
default:
assert(false, "new_position_by_direction: invalid direction, assumes direction is one of {w, s, a, d}.");
return {};
}
}
// Fuehrt Aktionen des Spieler-Feldes aus
// Vorbedingung: Wenn das Feld eine Tuer ist, muss mindestens ein Schluessel zur Verfuegung stehen
GameState process_tile_action(GameState game_state)
{
const int row = game_state.player.position[0];
const int col = game_state.player.position[1];
assert(game_state.maze.data[row][col] != 'T' || game_state.player.no_keys > 0,
"process_tile_action(...) assumes enough keys are there when approaching a door.");
if(game_state.maze.data[row][col] == 'K')
{
++game_state.player.no_keys;
game_state.maze.data[row][col] = '.';
}
else if(game_state.maze.data[row][col] == 'T')
{
--game_state.player.no_keys;
game_state.maze.data[row][col] = '.';
}
else if(game_state.maze.data[row][col] == 'A')
{
game_state.hit_ghost = true;
}
return game_state;
}
// Gibt true zurueck gdw. die Position begehbar ist
bool position_is_walkable(vector<int> position, GameState game_state)
{
const int row = position[0];
const int col = position[1];
if(row < 0 || col < 0)
{
return false;
}
if(row >= game_state.maze.rows || col >= game_state.maze.cols)
{
return false;
}
if(game_state.maze.data[row][col] == '#')
{
return false;
}
if(game_state.maze.data[row][col] == 'T' && game_state.player.no_keys == 0)
{
return false;
}
return true;
}
// Funktion zur Bewegung der SpielerIn
GameState move_player(GameState game_state, char direction)
{
vector<int> potential_new_position = new_position_by_direction(game_state.player.position, direction);
if(!position_is_walkable(potential_new_position, game_state))
{
throw BadMovement {};
}
game_state.player.position = potential_new_position;
return process_tile_action(game_state);
}
// Gibt eine kurze Hilfe aus
void display_help()
{
cout << "Willkommen zum Labyrinth-Spiel!\n";
cout << "Ziel des Spiels: Finden Sie den Weg vom Startpunkt (S) zum Ziel (Z).\n";
cout << "Spielfeld-Erklaerung:\n";
cout << "S - Startpunkt: Hier beginnt die SpielerIn.\n";
cout << "Z - Ziel: Erreichen Sie diesen Punkt, um das Spiel zu gewinnen.\n";
cout << "# - Wand: Diese Felder sind nicht begehbar.\n";
cout << "K - Schluessel: Hier können Sie einen Schluessel aufsammeln, um eine Tuer zu oeffnen.\n";
cout << "T - Tuer: Unbegehbares Feld, ausser, Sie haben einen Schluessel. Beim Durchschreiten wird ein Schluessel verbraucht.\n";
cout << "A - Geist: Ein Geist im Labyrinth. Stehen die SpielerIn auf dem selben Feld, verlieren Sie das Spiel!\n";
cout << ". - Leeres Feld: Diese Felder koennen betreten werden.\n";
cout << "\nSteuerung:\n";
cout << "w - Nach oben bewegen\n";
cout << "a - Nach links bewegen\n";
cout << "s - Nach unten bewegen\n";
cout << "d - Nach rechts bewegen\n";
cout << "q - Spiel beenden\n";
cout << "Nach jeder Befehlseingabe muss die Eingabetaste (Enter) gedrueckt werden, um sich zu bewegen.\n";
cout << "\nViel Erfolg im Labyrinth!\n";
}
// Reagiert auf das eingegebene Kommando und gibt an die jeweilige Funktion
// ab, die sich um genau dieses Kommando kuemmert.
GameState process_input(GameState game_state, char input)
{
switch(input)
{
case 'w':
case 's':
case 'a':
case 'd':
return move_player(game_state, input);
case 'h':
case 'H':
display_help();
break;
case 'q':
game_state.exit = true;
return game_state;
default:
throw UnknownInput{};
}
return game_state;
}
// Gibt true zurueck, wenn das Ziel erreicht wurde
bool reached_goal(GameState game_state)
{
return game_state.maze.data[game_state.player.position[0]][game_state.player.position[1]] == 'Z';
}
// Gibt true zurueck gdw der Geist getroffen wurde
bool hit_ghost(GameState game_state)
{
return game_state.hit_ghost;
}
// Gibt true zurueck gdw. das Spiel zuende ist
bool is_end_condition(GameState game_state)
{
return reached_goal(game_state) || hit_ghost(game_state) || game_state.exit;
}
// Die Hauptschleife des Spiels
GameState game_loop(GameState game_state)
{
char input;
while(cin && !is_end_condition(game_state))
{
assert(game_state.player.no_keys >= 0,
"Player has a negative number of keys.");
display_maze(game_state);
cin >> input;
if(cin)
{
try
{
game_state = process_input(game_state, input);
}
catch(BadMovement&)
{
cout << "Bewegung nicht moeglich!\n";
}
catch(UnknownInput&)
{
cout << "Diese Eingabe kenne ich nicht. Gib 'h' ein, um eine Hilfe zu erhalten.\n";
}
}
}
return game_state;
}
// Liest ein integer von der Eingabe.
// Vorbedingung: cin ist in Ordnung
int read_int()
{
int integer;
cin >> integer;
if(!cin) {throw BadMaze{};}
return integer;
}
// Liest die Labyrinth-Daten ein.
// Vorbedingung: cin ist ok.
vector<vector<char>> read_maze_data(int rows, int cols)
{
vector<vector<char>> maze_data(rows);
char ch;
for(int i = 0; i < rows * cols; ++i)
{
cin >> ch;
if(!cin) {throw BadMaze {};}
if(!(ch == '#' || ch == 'T' || ch == 'A' || ch == '.' || ch == 'K' || ch == 'Z'))
{
throw BadMaze {};
}
maze_data[i / cols].push_back(ch);
}
return maze_data;
}
// Liest das Labyrinth von der Konsole nach der Formatdefinition aus der Aufgabe
Maze read_maze()
{
int rows = read_int();
int cols = read_int();
if(rows < 1 || cols < 1 || rows > 20 || cols > 20)
{
throw BadMaze {};
}
vector<vector<char>> labyrinth_data = read_maze_data(rows, cols);
int player_row = read_int();
int player_col = read_int();
if(player_row < 0 || player_row >= rows || player_col < 0 || player_col >= cols)
{
throw BadMaze {};
}
if(labyrinth_data[player_row][player_col] != '.')
{
throw BadMaze {};
}
return {rows, cols, labyrinth_data, {player_row, player_col}};
}
// Initialisiert das Labyrinth-Objekt
GameState initialize()
{
Maze maze = read_maze();
Player player{0, maze.player_start_position};
return GameState {maze, player, false, false};
}
void print_exit_message_based_on_state(const GameState& state);
int main()
{
activateAssertions();
GameState state = GameState::RUNNING;
try
{
GameState game_state = initialize();
Maze maze = Maze::request_maze_from_user();
game_state = game_loop(game_state);
Game game = Game(maze);
if(reached_goal(game_state))
{
display_maze(game_state);
cout << "Ziel erreicht! Herzlichen Glueckwunsch!\n";
}
else if(hit_ghost(game_state))
{
cout << "Sie haben einen Geist getroffen! Game Over!\n";
}
else
{
cout << "Schoenen Tag noch!\n";
}
return 0;
game.run_game();
state = game.get_state();
}
catch(BadMaze&)
catch (MalformedMaze& _)
{
cout << "Fehler beim Einlesen des Labyrinths.\n";
return 1;
return 0;
}
catch(...)
{
cout << "Unbekannter Fehler!\n";
return 1;
print_exit_message_based_on_state(state);
return 0;
}
/// Schriebe eine Nachricht in die Konsole wenn das Programm beendet wird
/// @param state Der Spielzustand als das Programm beendet wurde
void print_exit_message_based_on_state(const GameState& state) {
switch (state){
case GameState::QUITTING:
cout << "Schoenen Tag noch!" << "\n";
break;
case GameState::HIT_BY_GHOST:
cout << "Sie haben einen Geist getroffen! Game Over!\n";
default:
break;
}
}

View file

@ -79,6 +79,15 @@ namespace std
{
using size_type = typename std::vector<T>::size_type;
/* #ifdef _MSC_VER
// microsoft doesn't yet support C++11 inheriting constructors
Vector() { }
explicit Vector(size_type n) :std::vector<T>(n) {}
Vector(size_type n, const T& v) :std::vector<T>(n, v) {}
template <class I>
Vector(I first, I last) : std::vector<T>(first, last) {}
Vector(initializer_list<T> list) : std::vector<T>(list) {}
*/
using std::vector<T>::vector; // inheriting constructor
T &operator[](unsigned int i) // rather than return at(i);