Outils d'utilisateurs

Outils du Site


javaquarium

Ceci est une ancienne révision du document !


Javaquarium

Partie 1.1

main.cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
#include <iterator>
 
namespace ecs {
    namespace entity {
        using id = size_t;
        using entities = std::vector<id>;
    }
 
    namespace component {
        using name = std::string;
        using is_male = bool;
        using detail = std::pair<name, is_male>;
        using detail_component = std::pair<entity::id, detail>;
 
        enum class type { algue, poisson };
        using type_component = std::pair<entity::id, type>;
    }
 
    namespace system {
        using details = std::vector<component::detail_component>;
        using types = std::vector<component::type_component>;
    }
 
    namespace internal {
        entity::entities _entities;
        system::details _details;
        system::types _types;
    }
 
    entity::id create_entity() {
        const auto id = internal::_entities.empty() ? 1 : internal::_entities.back() + 1;
        internal::_entities.push_back(id);
        return id;
    }
 
    void add_algue() {
        const auto id = create_entity();
        internal::_types.push_back(std::make_pair(id, component::type::algue));
    }
 
    void add_poisson(component::name n, component::is_male m) {
        const auto id = create_entity();
        internal::_types.push_back(std::make_pair(id, component::type::poisson));
        internal::_details.push_back(std::make_pair(id, make_pair(n, m)));
    }
 
    void print_algues() {
        const auto count = std::count_if(begin(internal::_types), end(internal::_types), 
            [](auto p){ return (p.second == component::type::algue); });
        std::cout << "algues: " << count;
    }
 
    void print_poissons() {
        std::cout << "poissons: ";
        std::transform(begin(internal::_details), end(internal::_details), 
            std::ostream_iterator<std::string>(std::cout, ", "),
            [](auto p){ return (p.second.first + " [" + (p.second.second ? 'M' : 'F') + ']'); });
    }
 
    void print() {
        print_algues();
        std::cout << ". ";
        print_poissons();
        std::cout << std::endl;
    }
}
 
int main() {
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_poisson("toto", true);
    ecs::add_algue();
    ecs::add_poisson("titi", false);
    ecs::add_poisson("tata", true);
    ecs::add_algue();
 
    ecs::print();
 
    return 0;   
}

affiche :

algues: 4. poissons: toto [M], titi [F], tata [M],

Commentaires

Mauvaise encapsulation = pas de garanties fortes sur les comportements.

int main() {
	ecs::internal::_entities.push_back(0);
	ecs::internal::_entities.push_back(0);
}

Partie 1.2

main.cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
#include <iterator>
#include <cassert>
 
namespace ecs {
    namespace entity {
        using id = size_t;
        using entities = std::vector<id>;
    }
 
    namespace component {
        using name = std::string;
        using is_male = bool;
        using detail = std::pair<name, is_male>;
        using detail_component = std::pair<entity::id, detail>;
 
        enum class type { algue, Mérou, Thon, PoissonClown, Sole, Bar, Carpe };
        using type_component = std::pair<entity::id, type>;
 
        bool is_algue(type t) { return (t == type::algue); }
        bool is_poisson(type t) { return !is_algue(t); }
        bool is_carnivore(type t) { return (t == type::Mérou || t == type::Thon || t == type::PoissonClown); }
        bool is_herbivore(type t) { return (t == type::Sole || t == type::Bar || t == type::Carpe); }
        std::string to_string(type t) {
            static const std::string types[] = { "Algue", "Mérou", "Thon", "Poisson-clown", 
                "Sole", "Bar", "Carpe" };
            const auto i = static_cast<size_t>(t);
            return types[i];
        }
    }
 
    namespace system {
        using details = std::vector<component::detail_component>;
        using types = std::vector<component::type_component>;
    }
 
    namespace internal {
        entity::entities _entities;
        system::details _details;
        system::types _types;
    }
 
    entity::id create_entity() {
        const auto id = internal::_entities.empty() ? 1 : internal::_entities.back() + 1;
        internal::_entities.push_back(id);
        return id;
    }
 
    entity::id add_algue() {
        const auto id = create_entity();
        internal::_types.push_back(std::make_pair(id, component::type::algue));
        return id;
    }
 
    entity::id add_poisson(component::type t, component::name n, component::is_male m) {
        assert(is_poisson(t));
        const auto id = create_entity();
        internal::_types.push_back(std::make_pair(id, t));
        internal::_details.push_back(std::make_pair(id, make_pair(n, m)));
        return id;
    }
 
    void remove_entity(entity::id id) {
        const auto entities_it = std::remove(internal::_entities.begin(), internal::_entities.end(), id);
        internal::_entities.erase(entities_it, internal::_entities.end());
 
        const auto details_it = std::remove_if(internal::_details.begin(), internal::_details.end(), 
            [id](auto p){ return (p.first == id); });
        internal::_details.erase(details_it, internal::_details.end());
 
        const auto types_it = std::remove_if(internal::_types.begin(), internal::_types.end(),
            [id](auto p){ return (p.first == id); });
        internal::_types.erase(types_it, internal::_types.end());
    }
 
    void eat(entity::id eater, entity::id target) {
        assert(eater != target);
 
        const auto eater_it = std::find_if(begin(internal::_types), end(internal::_types),
            [eater](auto p){ return (p.first == eater); });
        const auto target_it = std::find_if(begin(internal::_types), end(internal::_types),
            [target](auto p){ return (p.first == target); });
 
        assert(is_poisson(eater_it->second));
        assert(is_carnivore(eater_it->second) || (is_herbivore(eater_it->second) && is_algue(target_it->second)));
 
        remove_entity(target); //eat
    }
 
    void print_algues() {
        const auto count = std::count_if(begin(internal::_types), end(internal::_types), 
            [](auto p){ return (p.second == component::type::algue); });
        std::cout << "algues: " << count;
    }
 
    void print_poissons() {
        std::cout << "poissons: ";
        std::transform(begin(internal::_details), end(internal::_details), 
            std::ostream_iterator<std::string>(std::cout, ", "),
            [](auto p){ return (p.second.first + " [" + (p.second.second ? 'M' : 'F') + ']'); });
    }
 
    void print() {
        print_algues();
        std::cout << ". ";
        print_poissons();
        std::cout << std::endl;
    }
}
 
int main() {
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    const auto algue = ecs::add_algue();
    const auto carnivore = ecs::add_poisson(ecs::component::type::Mérou, "toto", true);
    const auto poisson = ecs::add_poisson(ecs::component::type::Mérou, "titi", false);
    const auto herbivore = ecs::add_poisson(ecs::component::type::Mérou, "tata", true);
    ecs::add_poisson(ecs::component::type::Mérou, "tuto", false);
    ecs::add_poisson(ecs::component::type::Mérou, "tyty", true);
    ecs::print();
 
    ecs::remove_entity(poisson);
    ecs::print();
 
    ecs::eat(herbivore, algue);
    ecs::eat(carnivore, herbivore);
    ecs::print();
 
    return 0;   
}

affiche :

algues: 8. poissons: toto [M], titi [F], tata [M], tuto [F], tyty [M], 
algues: 8. poissons: toto [M], tata [M], tuto [F], tyty [M], 
algues: 7. poissons: toto [M], tuto [F], tyty [M],

Commentaire

typage fort

enum class type { algue, Mérou, Thon, PoissonClown, Sole, Bar, Carpe };
void add_poisson(component::name n, component::is_male m, component::type t) {
	assert(is_poisson(t));
	...
}
 
enum class type { algue, poisson };
enum class race { Mérou, Thon, PoissonClown, Sole, Bar, Carpe };
void add_poisson(component::name n, component::is_male m, component::race r) {
	// assert(is_poisson(t)); pas necessaire
	...
}

idem:

void eat(entity::id eater, entity::id target) {
	const auto eater_it = std::find(begin(internal::_types), end(internal::_types),
		[eater](auto p){ return (p.first == eater); });
	const auto target_it = std::find(begin(internal::_types), end(internal::_types),
		[target](auto p){ return (p.first == target); });
 
	assert(is_poisson(eater_it->second));
	assert(is_carnivore(eater_it->second) || 
            (is_herbivore(eater_it->second) && is_poisson(target_it->second)));
 
	remove_entity(target); //eat
}

Partie 2.1

main.cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
#include <iterator>
#include <cassert>
#include <random>
 
namespace ecs {
    namespace entity {
        using id = size_t;
        using entities = std::vector<id>;
    }
 
    namespace component {
        using name = std::string;
        using is_male = bool;
        using detail = std::pair<name, is_male>;
        using detail_component = std::pair<entity::id, detail>;
 
        enum class type { algue, Mérou, Thon, PoissonClown, Sole, Bar, Carpe };
        using type_component = std::pair<entity::id, type>;
 
        bool is_algue(type t) { return (t == type::algue); }
        bool is_poisson(type t) { return !is_algue(t); }
        bool is_carnivore(type t) { return (t == type::Mérou || t == type::Thon || t == type::PoissonClown); }
        bool is_herbivore(type t) { return (t == type::Sole || t == type::Bar || t == type::Carpe); }
        std::string to_string(type t) {
            static const std::string types[] = { "Algue", "Mérou", "Thon", "Poisson-clown", "Sole", "Bar", "Carpe" };
            const auto i = static_cast<size_t>(t);
            assert(true);
            return types[i];
        }
    }
 
    namespace system {
        using details = std::vector<component::detail_component>;
        using types = std::vector<component::type_component>;
    }
 
    namespace internal {
        entity::entities _entities;
        system::details _details;
        system::types _types;
 
        std::random_device _random_device;
        std::default_random_engine _random_engine { _random_device() };
    }
 
    entity::id create_entity() {
        const auto id = internal::_entities.empty() ? 1 : internal::_entities.back() + 1;
        internal::_entities.push_back(id);
        return id;
    }
 
    entity::id add_algue() {
        const auto id = create_entity();
        internal::_types.push_back(std::make_pair(id, component::type::algue));
        return id;
    }
 
    entity::id add_poisson(component::type t, component::name n, component::is_male m) {
        assert(is_poisson(t));
        const auto id = create_entity();
        internal::_types.push_back(std::make_pair(id, t));
        internal::_details.push_back(std::make_pair(id, make_pair(n, m)));
        return id;
    }
 
    void remove_entity(entity::id id) {
        const auto entities_it = std::remove(internal::_entities.begin(), internal::_entities.end(), id);
        internal::_entities.erase(entities_it, internal::_entities.end());
 
        const auto details_it = std::remove_if(internal::_details.begin(), internal::_details.end(), 
            [id](auto p){ return (p.first == id); });
        internal::_details.erase(details_it, internal::_details.end());
 
        const auto types_it = std::remove_if(internal::_types.begin(), internal::_types.end(),
            [id](auto p){ return (p.first == id); });
        internal::_types.erase(types_it, internal::_types.end());
    }
 
    void eat(entity::id eater, entity::id target) {
        assert(eater != target);
 
        const auto eater_it = std::find_if(begin(internal::_types), end(internal::_types),
            [eater](auto p){ return (p.first == eater); });
        const auto target_it = std::find_if(begin(internal::_types), end(internal::_types),
            [target](auto p){ return (p.first == target); });
 
        assert(is_poisson(eater_it->second));
        assert(is_carnivore(eater_it->second) || (is_herbivore(eater_it->second) && is_algue(target_it->second)));
 
        remove_entity(target); //eat
    }
 
    entity::id random_entity() {
        std::uniform_int_distribution<size_t> distribution(0, internal::_entities.size() - 1);
        const auto index = distribution(internal::_random_engine);
        return internal::_entities[index];
    }
 
    entity::id random_poisson() {
        std::uniform_int_distribution<size_t> distribution(0, internal::_details.size() - 1);
        const auto index = distribution(internal::_random_engine);
        return internal::_details[index].first;
    }
 
    void print_algues() {
        const auto count = std::count_if(begin(internal::_types), end(internal::_types), 
            [](auto p){ return (p.second == component::type::algue); });
        std::cout << "algues: " << count;
    }
 
    void print_poissons() {
        std::cout << "poissons: ";
        std::transform(begin(internal::_details), end(internal::_details), std::ostream_iterator<std::string>(std::cout, ", "),
            [](auto p){ return (p.second.first + " [" + (p.second.second ? 'M' : 'F') + ']'); });
    }
 
    void print() {
        print_algues();
        std::cout << ". ";
        print_poissons();
        std::cout << std::endl;
    }
}
 
int main() {
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_poisson(ecs::component::type::Mérou, "toto", true);
    ecs::add_poisson(ecs::component::type::Mérou, "titi", false);
    ecs::add_poisson(ecs::component::type::Mérou, "tata", true);
    ecs::add_poisson(ecs::component::type::Mérou, "tuto", false);
    ecs::add_poisson(ecs::component::type::Mérou, "tyty", true);
    ecs::print();
 
    for (size_t i {}; i < 50; ++i) {
        std::uniform_int_distribution<size_t> distribution(0, ecs::internal::_types.size() - 1);
        auto index = distribution(ecs::internal::_random_engine);
        const auto eater = ecs::internal::_types[index];
 
        index = distribution(ecs::internal::_random_engine);
        const auto target = ecs::internal::_types[index];
 
        if (eater.first == target.first)
            continue;
 
        if (is_algue(eater.second))
            continue;
 
        if (is_herbivore(eater.second) && is_poisson(target.second))
            continue;
 
        std::cout << "   " << eater.first << " mange " << target.first << std::endl;
        ecs::remove_entity(target.first); // eat
 
        ecs::print();
    }
 
    return 0;   
}

affiche :

algues: 8. poissons: toto [M], titi [F], tata [M], tuto [F], tyty [M], 
   13 mange 3
algues: 7. poissons: toto [M], titi [F], tata [M], tuto [F], tyty [M], 
   12 mange 6
algues: 6. poissons: toto [M], titi [F], tata [M], tuto [F], tyty [M], 
   10 mange 12
algues: 6. poissons: toto [M], titi [F], tata [M], tyty [M], 
   13 mange 10
algues: 6. poissons: toto [M], tata [M], tyty [M], 
   13 mange 7
algues: 5. poissons: toto [M], tata [M], tyty [M], 
   13 mange 4
algues: 4. poissons: toto [M], tata [M], tyty [M], 
   13 mange 9
algues: 4. poissons: tata [M], tyty [M], 
   11 mange 2
algues: 3. poissons: tata [M], tyty [M], 
   11 mange 5
algues: 2. poissons: tata [M], tyty [M], 
   13 mange 11
algues: 2. poissons: tyty [M], 
   13 mange 8
algues: 1. poissons: tyty [M], 
   13 mange 1
algues: 0. poissons: tyty [M], 

Partie 2.2

main.cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
#include <iterator>
#include <cassert>
#include <random>
#include <tuple>
 
namespace ecs {
    namespace entity {
        using id = size_t;
        using entities = std::vector<id>;
    }
 
    namespace component {
        using name = std::string;
        using is_male = bool;
        using detail = std::pair<name, is_male>;
        using detail_component = std::pair<entity::id, detail>;
 
        enum class type { algue, Mérou, Thon, PoissonClown, Sole, Bar, Carpe };
        using pv = size_t;
        using type_component = std::tuple<entity::id, type, pv>;
 
        bool is_algue(type t) { return (t == type::algue); }
        bool is_poisson(type t) { return !is_algue(t); }
        bool is_carnivore(type t) { return (t == type::Mérou || t == type::Thon || t == type::PoissonClown); }
        bool is_herbivore(type t) { return (t == type::Sole || t == type::Bar || t == type::Carpe); }
        std::string to_string(type t) {
            static const std::string types[] = { "Algue", "Mérou", "Thon", "Poisson-clown", "Sole", "Bar", "Carpe" };
            const auto i = static_cast<size_t>(t);
            assert(true);
            return types[i];
        }
    }
 
    namespace system {
        using details = std::vector<component::detail_component>;
        using types = std::vector<component::type_component>;
    }
 
    namespace internal {
        entity::entities _entities;
        system::details _details;
        system::types _types;
 
        std::random_device _random_device;
        std::default_random_engine _random_engine { _random_device() };
    }
 
    entity::id create_entity() {
        const auto id = internal::_entities.empty() ? 1 : internal::_entities.back() + 1;
        internal::_entities.push_back(id);
        return id;
    }
 
    entity::id add_algue() {
        const auto id = create_entity();
        internal::_types.push_back(std::make_tuple(id, component::type::algue, 10));
        return id;
    }
 
    entity::id add_poisson(component::type t, component::name n, component::is_male m) {
        assert(is_poisson(t));
        const auto id = create_entity();
        internal::_types.push_back(std::make_tuple(id, t,10));
        internal::_details.push_back(std::make_pair(id, make_pair(n, m)));
        return id;
    }
 
    void remove_entity(entity::id id) {
        const auto entities_it = std::remove(internal::_entities.begin(), internal::_entities.end(), id);
        internal::_entities.erase(entities_it, internal::_entities.end());
 
        const auto details_it = std::remove_if(internal::_details.begin(), internal::_details.end(), 
            [id](auto p){ return (p.first == id); });
        internal::_details.erase(details_it, internal::_details.end());
 
        const auto types_it = std::remove_if(internal::_types.begin(), internal::_types.end(),
            [id](auto p){ return (std::get<0>(p) == id); });
        internal::_types.erase(types_it, internal::_types.end());
    }
 
    void eat(entity::id eater, entity::id target) {
        assert(eater != target);
 
        const auto eater_it = std::find_if(begin(internal::_types), end(internal::_types),
            [eater](auto p){ return (std::get<0>(p) == eater); });
        const auto target_it = std::find_if(begin(internal::_types), end(internal::_types),
            [target](auto p){ return (std::get<0>(p) == target); });
 
        assert(is_poisson(std::get<1>(*eater_it)));
        assert(is_carnivore(std::get<1>(*eater_it)) || (is_herbivore(std::get<1>(*eater_it)) && is_algue(std::get<1>(*target_it))));
 
        remove_entity(target); //eat
    }
 
    entity::id random_entity() {
        std::uniform_int_distribution<size_t> distribution(0, internal::_entities.size() - 1);
        const auto index = distribution(internal::_random_engine);
        return internal::_entities[index];
    }
 
    entity::id random_poisson() {
        std::uniform_int_distribution<size_t> distribution(0, internal::_details.size() - 1);
        const auto index = distribution(internal::_random_engine);
        return internal::_details[index].first;
    }
 
    void print_algues() {
        const auto count = std::count_if(begin(internal::_types), end(internal::_types), 
            [](auto p){ return (std::get<1>(p) == component::type::algue); });
        std::cout << "algues: " << count;
    }
 
    void print_poissons() {
        std::cout << "poissons: ";
        std::transform(begin(internal::_details), end(internal::_details), std::ostream_iterator<std::string>(std::cout, ", "),
            [](auto p){ return (p.second.first + " [" + (p.second.second ? 'M' : 'F') + ']'); });
    }
 
    void print() {
        print_algues();
        std::cout << ". ";
        print_poissons();
        std::cout << std::endl;
    }
}
 
int main() {
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_algue();
    ecs::add_poisson(ecs::component::type::Mérou, "toto", true);
    ecs::add_poisson(ecs::component::type::Mérou, "titi", false);
    ecs::add_poisson(ecs::component::type::Mérou, "tata", true);
    ecs::add_poisson(ecs::component::type::Mérou, "tuto", false);
    ecs::add_poisson(ecs::component::type::Mérou, "tyty", true);
    ecs::print();
 
    for (size_t i {}; i < 50; ++i) {
        std::uniform_int_distribution<size_t> distribution(0, ecs::internal::_types.size() - 1);
        auto index = distribution(ecs::internal::_random_engine);
        const auto eater = ecs::internal::_types[index];
 
        index = distribution(ecs::internal::_random_engine);
        auto & target = ecs::internal::_types[index];
 
        if (std::get<0>(eater) == std::get<0>(target))
            continue;
 
        if (is_algue(std::get<1>(eater)))
            continue;
 
        if (is_herbivore(std::get<1>(eater)) && is_poisson(std::get<1>(target)))
            continue;
 
        std::get<2>(target) -= 2; // eat
        std::cout << "   " << std::get<0>(eater) << " mange " << std::get<0>(target) <<
            " reste " << std::get<2>(target) << std::endl;
 
        ecs::print();
    }
 
    return 0;   
}

Partie 3.1

Partie 3.2

Partie 3.3

javaquarium.1461973728.txt.gz · Dernière modification: 2016/04/30 01:48 par gbdivers