#include <iostream>
#include <vector>
#include <string>

class Person
{
 public:
  Person(const std::string& f, const std::string& l, int a)
    : firstName(f), lastName(l), age(a)
  {
  }
  Person()
  {
  }
  std::string toString()
  {
    return lastName + ", " + firstName
      + ". Alter: " + std::to_string(age);
  }
  std::string firstName;
  std::string lastName;
  int age = -1;
};

class Room
{
 public:
  Room(const std::string& n, int c, int p)
    : name(n), capacity(c), pricePerPerson(p)
  {
  }
  bool book(const Person& person, int maxPrice)
  {
    if (pricePerPerson <= maxPrice  // Preis okay
      && persons.size() < capacity)  // Frei
    {
      persons.push_back(person);
      return true;
    }
    // Dieser Raum eignet sich nicht
    return false;
  }
  const std::string name;
  const int capacity;
  const int pricePerPerson;
  std::vector<Person> persons;
};

class Hotel
{
 public:
  Hotel(const std::string& n, const std::vector<Room>& r)
    : name(n), rooms(r)
  {
  }
  bool book(const Person& person, int maxPrice)
  {
    // Einen freien Raum finden, der dem Preis genügt
    // Wichtig: Per Referenz auf den Raum zugreifen!
    for (Room& room : rooms)
    {
      if (room.book(person, maxPrice))
      {
        return true;
      }
    }
    // Keinen Raum gefunden
    return false;
  }
  std::string toString()
  {
    std::string output = "Belegung Hotel " + name + ":\n"
      + "=============================\n";
    for (Room room : rooms)
    {
      output += "Raum " + room.name + ":\n";
      for (Person person : room.persons)
      {
        output += person.toString() + "\n";
      }
      if (room.persons.empty())  // analog zu .size() == 0
      {
        output += "  Leer\n";
      }
      output += "-----------------------------\n";
    }
    return output;
  }
  const std::string name;
  std::vector<Room> rooms;
};

int main()
{
  // Auch Listen von komplexeren Objekten können
  // mit {} befüllt werden:
  const std::vector<Room> rooms = {
    Room("101", 2, 40),
    Room("102", 2, 50),
    Room("103", 6, 20),
    Room("104", 1, 70)
  };
  Hotel hotel("California", rooms);
  hotel.book(Person("Melanie", "Muster", 42), 60);
  hotel.book(Person("Markus", "Muster", 41), 60);
  std::cout << hotel.toString() << std::endl;
  return 0;
}
