C++17 In Detail

04 May 2020

Spaceship Generator for May the 4th in C++ - Enter The Game!

Spaceship Random Generator, C++

4th May is the Star Wars Day so why not join the celebration and build some space ships? Of course in C++ :)

Read on and see how to join the game and get a chance to win some extras!

The submission dealine is over, I'm in the process of gathering the results. Stay tuned for the final summary and thanks for all of your solutions!

The Task

Your task is simple: write a spaceship random generator which can create amazing spaceships (*)!

(*) Not to mistake with the spaceship operator for C++20 :)

For example:

Spaceship with ionizing engine, small wings, regular cabin, tie fighter style fuselage and rocket launcher weapon.

How to do it?

Below, you can find my super-advanced prototype that is written is C… C++ something… legacy. Update it to modern C++, use as many new C++ features and show some cool programming techniques and patterns.

The Starting Legacy Code

Have a look:

#include <string> 
#include <cstring> 
#include <iostream>
#include <vector>  
#include <fstream>
#include <random>
#include <algorithm>

char partsFileName[128] = "vehicle_parts.txt";

std::vector<std::string> allParts;

class Spaceship {
public:
    static void GenerateShip(SpaceShip *pOutShip);

    void Print() {
        // print code...
    }
private:
    std::string _engine;
    std::string _fuselage;
    std::string _cabin;
    std::string _large_wings; // optional
    std::string _small_wings;  // optional
    std::string _armor;
    std::string _weapons[4]; // max weapon count is 4
};

void Spaceship::GenerateShip(Spaceship *pOutShip) {
    std::vector<std::string> engineParts;
    std::vector<std::string> fuselageParts;
    std::vector<std::string> cabinParts;
    std::vector<std::string> wingsParts;
    std::vector<std::string> armorParts;
    std::vector<std::string> weaponParts;

    for (const auto& str : allParts) {
        if (str.rfind("engine") != std::string::npos)
            engineParts.push_back(str);
        else if (str.rfind("fuselage") != std::string::npos)
            fuselageParts.push_back(str);
        else if (str.rfind("cabin") != std::string::npos)
            cabinParts.push_back(str);
        else if (str.rfind("wings") != std::string::npos)
            wingsParts.push_back(str);
        else if (str.rfind("armor") != std::string::npos)
            armorParts.push_back(str);
        else if (str.rfind("weapon") != std::string::npos)
            weaponParts.push_back(str);
    }

    std::random_device rd;
    std::mt19937 g(rd());

    std::shuffle(engineParts.begin(), engineParts.end(), g);
    std::shuffle(fuselageParts.begin(), fuselageParts.end(), g);
    std::shuffle(cabinParts.begin(), cabinParts.end(), g);
    std::shuffle(wingsParts.begin(), wingsParts.end(), g);
    std::shuffle(armorParts.begin(), armorParts.end(), g);
    std::shuffle(weaponParts.begin(), weaponParts.end(), g);

    // select parts:
    pOutShip->_engine = engineParts[0];
    pOutShip->_fuselage = fuselageParts[0];
    pOutShip->_cabin = cabinParts[0];
    pOutShip->_armor = armorParts[0];
    pOutShip->_large_wings = wingsParts[0];
    pOutShip->_weapons[0] = weaponParts[0];
}

int main(int argc, char* argv[]) {
    if (argc > 1) {
        strcpy(partsFileName, argv[1]);
    }    

    std::cout << "parts loaded from: " << partsFileName << '\n';

    std::ifstream file(partsFileName);
    if (file.is_open()) {
        std::string line;
        while (std::getline(file, line)) {
            allParts.push_back(line);
        }
        file.close();
    }     

    Spaceship sp;
    Spaceship::GenerateShip(&sp);
    sp.Print();
}

As you can see above the program consists of several parts:

  • It reads all the lines from a given file and stores it in a global vector of strings. Yes… global, as it’s the best way to program such programs :)
  • Of course almost no error checking needed :)
  • Then we define a Spaceship with the best possible name sp.
  • Later the spaceship is passed to a generator function that does the main job:
    • It sorts the input parts and groups them into separate containers.
    • Then it shuffles the parts containers
    • We can then use the first objects in those containers and assign them to the appropriate member variables of the output spaceship
  • At the end, the main function invokes a print member function that shows the generated spaceship.

Can you write better code? :)

Enter the Game And Win

Each participant will get a chance to win the following reward:

3-month Educative.io service and 15$ Amazon.com Gift Card

I have 5 of those “packs” for 5 people.

educative.io is a learning platform with “Rich, text-based courses with embedded coding environments make learning a breeze”. They have more than 265.000 learners, many courses, and learning tracks. For example, they have learning tracks to machine learning, DevOps but also Python, Java, and C++ (My course about C++17 is there!).

The winners will be selected randomly from all of the participants and announced in two weeks. You have one week to send me the working code. See the full rules below.

Rules

The submission dealine is over, I'm in the process of gathering the results. Stay tuned for the final summary and thanks for all of your solutions!

Deadline of submission: next Monday 11th May by midnight CEST

Requirements:

  • the program must read vehicle parts from a separate file
    • each line ends with a type of a part: engine, weapon, wings, fuselage, armor (you may add your types)
    • You can use your custom format and files, but please send me it later so I can test. Keep it simple though.
  • the program must then select parts randomly and assign it to a new spaceship
  • each spaceship must have:
    • one engine
    • one fuselage part
    • one cabin
    • optional small wings
    • optional large wings
    • one armor part
    • up to four weapons attached
    • you might invent and add some extra rules to the spaceship design if you like
  • the program must have a function that will then display the parts of the created spaceship to the console
  • Use of Modern C++ techniques is highly recommended
  • The program must compile with GCC 10.0 and with no extra dependencies! It can use the Standard Library only
    • C++2a parameter will be used
  • Please have fun and use your creativity and Modern C++ to write something cool :)
    • My sample code is really really bad. Please fix it, use better design patterns, error checking, modern C++ features, better class designs and features.

Please send me the submissions to bartlomiej DOT filipek @bfilipek.com. You can use links to Wandbox or Compiler explorer (to make my life easier).
Also, please Include a description of the major features and techniques used.

In two weeks time I will select some of the interesting submissions and share it on the separate blog post (if you agree).

If you have questions, or if you like me to clarify something, then don't hesitate and ask in comments or via email.

Test Playground

You can use below playground to experiment with the code:

(It uses GCC 9.3 to compile the code, so only a limited of C++20 features is available)

Extra Discounts!

Additionally, if you want to use some modern features in your submissions and you’d like to learn more about them, you can use this solid discount for my books:

The coupons are valid till the end of Monday, 11th May

If you like my work and you want to get extra C++ content, exlusive articles and weekly curated news, then check out my Patreon website:

© 2017, Bartlomiej Filipek, Blogger platform
Disclaimer: Any opinions expressed herein are in no way representative of those of my employers. All data and information provided on this site is for informational purposes only. I try to write complete and accurate articles, but the web-site will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use.
This site contains ads or referral links, which provide me with a commission. Thank you for your understanding.