Пример #1
0
int main(int argc, char *argv[]) {
    int dims = 2;
    int nr_particles = 5;
    if (argc > 1)
        dims = atoi(argv[1]);
    if (argc > 2)
        nr_particles = atoi(argv[2]);
    System *system = init_system(nr_particles, dims);
    print_system(system);
    printf("total mass = %lf\n", total_mass(system));
    double cms[dims];
    center_of_mass(system, cms);
    print_position(cms, dims);
    free_system(system);
    return EXIT_SUCCESS;
}
Пример #2
0
bool game::dump_stats( const std::string &what, dump_mode mode,
                       const std::vector<std::string> &opts )
{
    try {
        loading_ui ui( false );
        load_core_data( ui );
        load_packs( _( "Loading content packs" ), { mod_id( "dda" ) }, ui );
        DynamicDataLoader::get_instance().finalize_loaded_data( ui );
    } catch( const std::exception &err ) {
        std::cerr << "Error loading data from json: " << err.what() << std::endl;
        return false;
    }

    std::vector<std::string> header;
    std::vector<std::vector<std::string>> rows;

    int scol = 0; // sorting column

    std::map<std::string, standard_npc> test_npcs;
    test_npcs[ "S1" ] = standard_npc( "S1", { "gloves_survivor", "mask_lsurvivor" }, 4, 8, 10, 8,
                                      10 /* DEX 10, PER 10 */ );
    test_npcs[ "S2" ] = standard_npc( "S2", { "gloves_fingerless", "sunglasses" }, 4, 8, 8, 8,
                                      10 /* PER 10 */ );
    test_npcs[ "S3" ] = standard_npc( "S3", { "gloves_plate", "helmet_plate" },  4, 10, 8, 8,
                                      8 /* STAT 10 */ );
    test_npcs[ "S4" ] = standard_npc( "S4", {}, 0, 8, 10, 8, 10 /* DEX 10, PER 10 */ );
    test_npcs[ "S5" ] = standard_npc( "S5", {}, 4, 8, 10, 8, 10 /* DEX 10, PER 10 */ );
    test_npcs[ "S6" ] = standard_npc( "S6", { "gloves_hsurvivor", "mask_hsurvivor" }, 4, 8, 10, 8,
                                      10 /* DEX 10, PER 10 */ );

    std::map<std::string, item> test_items;
    test_items[ "G1" ] = item( "glock_19" ).ammo_set( "9mm" );
    test_items[ "G2" ] = item( "hk_mp5" ).ammo_set( "9mm" );
    test_items[ "G3" ] = item( "ar15" ).ammo_set( "223" );
    test_items[ "G4" ] = item( "remington_700" ).ammo_set( "270" );
    test_items[ "G4" ].emplace_back( "rifle_scope" );

    if( what == "AMMO" ) {
        header = {
            "Name", "Ammo", "Volume", "Weight", "Stack",
            "Range", "Dispersion", "Recoil", "Damage", "Pierce"
        };
        auto dump = [&rows]( const item & obj ) {
            // a common task is comparing ammo by type so ammo has multiple repeat the entry
            for( const auto &e : obj.type->ammo->type ) {
                std::vector<std::string> r;
                r.push_back( obj.tname( 1, false ) );
                r.push_back( e.str() );
                r.push_back( to_string( obj.volume() / units::legacy_volume_factor ) );
                r.push_back( to_string( to_gram( obj.weight() ) ) );
                r.push_back( to_string( obj.type->stack_size ) );
                r.push_back( to_string( obj.type->ammo->range ) );
                r.push_back( to_string( obj.type->ammo->dispersion ) );
                r.push_back( to_string( obj.type->ammo->recoil ) );
                damage_instance damage = obj.type->ammo->damage;
                r.push_back( to_string( damage.total_damage() ) );
                r.push_back( to_string( damage.empty() ? 0 : ( *damage.begin() ).res_pen ) );
                rows.push_back( r );
            }
        };
        for( const itype *e : item_controller->all() ) {
            if( e->ammo ) {
                dump( item( e, calendar::turn, item::solitary_tag {} ) );
            }
        }

    } else if( what == "ARMOR" ) {
        header = {
            "Name", "Encumber (fit)", "Warmth", "Weight", "Storage", "Coverage", "Bash", "Cut", "Acid", "Fire"
        };
        auto dump = [&rows]( const item & obj ) {
            std::vector<std::string> r;
            r.push_back( obj.tname( 1, false ) );
            r.push_back( to_string( obj.get_encumber() ) );
            r.push_back( to_string( obj.get_warmth() ) );
            r.push_back( to_string( to_gram( obj.weight() ) ) );
            r.push_back( to_string( obj.get_storage() / units::legacy_volume_factor ) );
            r.push_back( to_string( obj.get_coverage() ) );
            r.push_back( to_string( obj.bash_resist() ) );
            r.push_back( to_string( obj.cut_resist() ) );
            r.push_back( to_string( obj.acid_resist() ) );
            r.push_back( to_string( obj.fire_resist() ) );
            rows.push_back( r );
        };

        body_part bp = opts.empty() ? num_bp : get_body_part_token( opts.front() );

        for( const itype *e : item_controller->all() ) {
            if( e->armor ) {
                item obj( e );
                if( bp == num_bp || obj.covers( bp ) ) {
                    if( obj.has_flag( "VARSIZE" ) ) {
                        obj.item_tags.insert( "FIT" );
                    }
                    dump( obj );
                }
            }
        }

    } else if( what == "EDIBLE" ) {
        header = {
            "Name", "Volume", "Weight", "Stack", "Calories", "Quench", "Healthy"
        };
        for( const auto &v : vitamin::all() ) {
            header.push_back( v.second.name() );
        }
        auto dump = [&rows]( const item & obj ) {
            std::vector<std::string> r;
            r.push_back( obj.tname( false ) );
            r.push_back( to_string( obj.volume() / units::legacy_volume_factor ) );
            r.push_back( to_string( to_gram( obj.weight() ) ) );
            r.push_back( to_string( obj.type->stack_size ) );
            r.push_back( to_string( obj.type->comestible->get_calories() ) );
            r.push_back( to_string( obj.type->comestible->quench ) );
            r.push_back( to_string( obj.type->comestible->healthy ) );
            auto vits = g->u.vitamins_from( obj );
            for( const auto &v : vitamin::all() ) {
                r.push_back( to_string( vits[ v.first ] ) );
            }
            rows.push_back( r );
        };

        for( const itype *e : item_controller->all() ) {
            item food( e, calendar::turn, item::solitary_tag {} );

            if( food.is_food() && g->u.can_eat( food ).success() ) {
                dump( food );
            }
        }

    } else if( what == "GUN" ) {
        header = {
            "Name", "Ammo", "Volume", "Weight", "Capacity",
            "Range", "Dispersion", "Effective recoil", "Damage", "Pierce",
            "Aim time", "Effective range", "Snapshot range", "Max range"
        };

        std::set<std::string> locations;
        for( const itype *e : item_controller->all() ) {
            if( e->gun ) {
                std::transform( e->gun->valid_mod_locations.begin(),
                                e->gun->valid_mod_locations.end(),
                                std::inserter( locations, locations.begin() ),
                []( const std::pair<gunmod_location, int> &q ) {
                    return q.first.name();
                } );
            }
        }
        for( const auto &e : locations ) {
            header.push_back( e );
        }

        auto dump = [&rows, &locations]( const standard_npc & who, const item & obj ) {
            std::vector<std::string> r;
            r.push_back( obj.tname( 1, false ) );
            r.push_back( obj.ammo_type() ? obj.ammo_type().str() : "" );
            r.push_back( to_string( obj.volume() / units::legacy_volume_factor ) );
            r.push_back( to_string( to_gram( obj.weight() ) ) );
            r.push_back( to_string( obj.ammo_capacity() ) );
            r.push_back( to_string( obj.gun_range() ) );
            r.push_back( to_string( obj.gun_dispersion() ) );
            r.push_back( to_string( obj.gun_recoil( who ) ) );
            damage_instance damage = obj.gun_damage();
            r.push_back( to_string( damage.total_damage() ) );
            r.push_back( to_string( damage.empty() ? 0 : ( *damage.begin() ).res_pen ) );

            r.push_back( to_string( who.gun_engagement_moves( obj ) ) );

            for( const auto &e : locations ) {
                const auto &vml = obj.type->gun->valid_mod_locations;
                const auto iter = vml.find( e );
                r.push_back( to_string( iter != vml.end() ? iter->second : 0 ) );
            }
            rows.push_back( r );
        };
        for( const itype *e : item_controller->all() ) {
            if( e->gun ) {
                item gun( e );
                if( !gun.magazine_integral() ) {
                    gun.emplace_back( gun.magazine_default() );
                }
                gun.ammo_set( gun.ammo_type()->default_ammotype(), gun.ammo_capacity() );

                dump( test_npcs[ "S1" ], gun );

                if( gun.type->gun->barrel_length > 0 ) {
                    gun.emplace_back( "barrel_small" );
                    dump( test_npcs[ "S1" ], gun );
                }
            }
        }

    } else if( what == "RECIPE" ) {

        // optionally filter recipes to include only those using specified skills
        recipe_subset dict;
        for( const auto &r : recipe_dict ) {
            if( opts.empty() || std::any_of( opts.begin(), opts.end(), [&r]( const std::string & s ) {
            if( r.second.skill_used == skill_id( s ) && r.second.difficulty > 0 ) {
                    return true;
                }
                auto iter = r.second.required_skills.find( skill_id( s ) );
                return iter != r.second.required_skills.end() && iter->second > 0;
            } ) ) {
                dict.include( &r.second );
            }
        }

        // only consider skills that are required by at least one recipe
        std::vector<Skill> sk;
        std::copy_if( Skill::skills.begin(), Skill::skills.end(),
        std::back_inserter( sk ), [&dict]( const Skill & s ) {
            return std::any_of( dict.begin(), dict.end(), [&s]( const recipe * r ) {
                return r->skill_used == s.ident() ||
                       r->required_skills.find( s.ident() ) != r->required_skills.end();
            } );
        } );

        header = { "Result" };

        for( const auto &e : sk ) {
            header.push_back( e.ident().str() );
        }

        for( const recipe *e : dict ) {
            std::vector<std::string> r;
            r.push_back( e->result_name() );
            for( const auto &s : sk ) {
                if( e->skill_used == s.ident() ) {
                    r.push_back( to_string( e->difficulty ) );
                } else {
                    auto iter = e->required_skills.find( s.ident() );
                    r.push_back( to_string( iter != e->required_skills.end() ? iter->second : 0 ) );
                }
            }
            rows.push_back( r );
        }

    } else if( what == "VEHICLE" ) {
        header = {
            "Name", "Weight (empty)", "Weight (fueled)",
            "Max velocity (mph)", "Safe velocity (mph)", "Acceleration (mph/turn)",
            "Mass coeff %", "Aerodynamics coeff %", "Friction coeff %",
            "Traction coeff % (grass)"
        };
        auto dump = [&rows]( const vproto_id & obj ) {
            auto veh_empty = vehicle( obj, 0, 0 );
            auto veh_fueled = vehicle( obj, 100, 0 );

            std::vector<std::string> r;
            r.push_back( veh_empty.name );
            r.push_back( to_string( to_kilogram( veh_empty.total_mass() ) ) );
            r.push_back( to_string( to_kilogram( veh_fueled.total_mass() ) ) );
            r.push_back( to_string( veh_fueled.max_velocity() / 100 ) );
            r.push_back( to_string( veh_fueled.safe_velocity() / 100 ) );
            r.push_back( to_string( veh_fueled.acceleration() / 100 ) );
            r.push_back( to_string( ( int )( 100 * veh_fueled.k_mass() ) ) );
            r.push_back( to_string( ( int )( 100 * veh_fueled.k_aerodynamics() ) ) );
            r.push_back( to_string( ( int )( 100 * veh_fueled.k_friction() ) ) );
            r.push_back( to_string( ( int )( 100 * veh_fueled.k_traction( veh_fueled.wheel_area(
                                                 false ) / 2.0f ) ) ) );
            rows.push_back( r );
        };
        for( auto &e : vehicle_prototype::get_all() ) {
            dump( e );
        }

    } else if( what == "VPART" ) {
        header = {
            "Name", "Location", "Weight", "Size"
        };
        auto dump = [&rows]( const vpart_info & obj ) {
            std::vector<std::string> r;
            r.push_back( obj.name() );
            r.push_back( obj.location );
            r.push_back( to_string( int( ceil( to_gram( item( obj.item ).weight() ) / 1000.0 ) ) ) );
            r.push_back( to_string( obj.size / units::legacy_volume_factor ) );
            rows.push_back( r );
        };
        for( const auto &e : vpart_info::all() ) {
            dump( e.second );
        }

    } else {
        std::cerr << "unknown argument: " << what << std::endl;
        return false;
    }

    rows.erase( std::remove_if( rows.begin(), rows.end(), []( const std::vector<std::string> &e ) {
        return e.empty();
    } ), rows.end() );

    if( scol >= 0 ) {
        std::sort( rows.begin(), rows.end(), [&scol]( const std::vector<std::string> &lhs,
        const std::vector<std::string> &rhs ) {
            return lhs[ scol ] < rhs[ scol ];
        } );
    }

    rows.erase( std::unique( rows.begin(), rows.end() ), rows.end() );

    switch( mode ) {
        case dump_mode::TSV:
            rows.insert( rows.begin(), header );
            for( const auto &r : rows ) {
                std::copy( r.begin(), r.end() - 1, std::ostream_iterator<std::string>( std::cout, "\t" ) );
                std::cout << r.back() << "\n";
            }
            break;

        case dump_mode::HTML:
            std::cout << "<table>";

            std::cout << "<thead>";
            std::cout << "<tr>";
            for( const auto &col : header ) {
                std::cout << "<th>" << col << "</th>";
            }
            std::cout << "</tr>";
            std::cout << "</thead>";

            std::cout << "<tdata>";
            for( const auto &r : rows ) {
                std::cout << "<tr>";
                for( const auto &col : r ) {
                    std::cout << "<td>" << col << "</td>";
                }
                std::cout << "</tr>";
            }
            std::cout << "</tdata>";

            std::cout << "</table>";
            break;
    }

    return true;
}
Пример #3
0
bool game::dump_stats( const std::string& what, dump_mode mode, const std::vector<std::string> &opts )
{
    try {
        load_core_data();
    } catch( const std::exception &err ) {
        std::cerr << "Error loading data from json: " << err.what() << std::endl;
        return false;
    }
    DynamicDataLoader::get_instance().finalize_loaded_data();

    std::vector<std::string> header;
    std::vector<std::vector<std::string>> rows;

    int scol = 0; // sorting column

    std::map<std::string, standard_npc> test_npcs;
    test_npcs[ "S1" ] = standard_npc( "S1", { "gloves_survivor", "mask_lsurvivor" }, 4, 8, 10, 8, 10 /* DEX 10, PER 10 */ );
    test_npcs[ "S2" ] = standard_npc( "S2", { "gloves_fingerless", "sunglasses" }, 4, 8, 8, 8, 10 /* PER 10 */ );
    test_npcs[ "S3" ] = standard_npc( "S3", { "gloves_plate", "helmet_plate" },  4, 10, 8, 8, 8 /* STAT 10 */ );
    test_npcs[ "S4" ] = standard_npc( "S4", {}, 0, 8, 10, 8, 10 /* DEX 10, PER 10 */ );
    test_npcs[ "S5" ] = standard_npc( "S5", {}, 4, 8, 10, 8, 10 /* DEX 10, PER 10 */ );
    test_npcs[ "S6" ] = standard_npc( "S6", { "gloves_hsurvivor", "mask_hsurvivor" }, 4, 8, 10, 8, 10 /* DEX 10, PER 10 */ );

    std::map<std::string, item> test_items;
    test_items[ "G1" ] = item( "glock_19" ).ammo_set( "9mm" );
    test_items[ "G2" ] = item( "hk_mp5" ).ammo_set( "9mm" );
    test_items[ "G3" ] = item( "ar15" ).ammo_set( "223" );
    test_items[ "G4" ] = item( "remington_700" ).ammo_set( "270" );
    test_items[ "G4" ].emplace_back( "rifle_scope" );

    if( what == "AMMO" ) {
        header = {
            "Name", "Ammo", "Volume", "Weight", "Stack",
            "Range", "Dispersion", "Recoil", "Damage", "Pierce"
        };
        auto dump = [&rows]( const item& obj ) {
            // a common task is comparing ammo by type so ammo has multiple repeat the entry
            for( const auto &e : obj.type->ammo->type ) {
                std::vector<std::string> r;
                r.push_back( obj.tname( 1, false ) );
                r.push_back( e.str() );
                r.push_back( to_string( obj.volume() / units::legacy_volume_factor ) );
                r.push_back( to_string( obj.weight() ) );
                r.push_back( to_string( obj.type->stack_size ) );
                r.push_back( to_string( obj.type->ammo->range ) );
                r.push_back( to_string( obj.type->ammo->dispersion ) );
                r.push_back( to_string( obj.type->ammo->recoil ) );
                r.push_back( to_string( obj.type->ammo->damage ) );
                r.push_back( to_string( obj.type->ammo->pierce ) );
                rows.push_back( r );
            }
        };
        for( auto& e : item_controller->get_all_itypes() ) {
            if( e.second.ammo ) {
                dump( item( e.first, calendar::turn, item::solitary_tag {} ) );
            }
        }

    } else if( what == "ARMOR" ) {
        header = {
            "Name", "Encumber (fit)", "Warmth", "Weight", "Storage", "Coverage", "Bash", "Cut", "Acid", "Fire"
        };
        auto dump = [&rows]( const item& obj ) {
            std::vector<std::string> r;
            r.push_back( obj.tname( 1, false ) );
            r.push_back( to_string( obj.get_encumber() ) );
            r.push_back( to_string( obj.get_warmth() ) );
            r.push_back( to_string( obj.weight() ) );
            r.push_back( to_string( obj.get_storage() / units::legacy_volume_factor ) );
            r.push_back( to_string( obj.get_coverage() ) );
            r.push_back( to_string( obj.bash_resist() ) );
            r.push_back( to_string( obj.cut_resist() ) );
            r.push_back( to_string( obj.acid_resist() ) );
            r.push_back( to_string( obj.fire_resist() ) );
            rows.push_back( r );
        };

        body_part bp = opts.empty() ? num_bp : get_body_part_token( opts.front() );

        for( auto& e : item_controller->get_all_itypes() ) {
            if( e.second.armor ) {
                item obj( e.first );
                if( bp == num_bp || obj.covers( bp ) ) {
                    if( obj.has_flag( "VARSIZE" ) ) {
                        obj.item_tags.insert( "FIT" );
                    }
                    dump( obj );
                }
            }
        }

    } else if( what == "EDIBLE" ) {
        header = {
            "Name", "Volume", "Weight", "Stack", "Calories", "Quench", "Healthy"
        };
        for( const auto& v : vitamin::all() ) {
             header.push_back( v.second.name() );
        }
        auto dump = [&rows,&test_npcs]( const item& obj ) {
            std::vector<std::string> r;
            r.push_back( obj.tname( false ) );
            r.push_back( to_string( obj.volume() / units::legacy_volume_factor ) );
            r.push_back( to_string( obj.weight() ) );
            r.push_back( to_string( obj.type->stack_size ) );
            r.push_back( to_string( obj.type->comestible->get_calories() ) );
            r.push_back( to_string( obj.type->comestible->quench ) );
            r.push_back( to_string( obj.type->comestible->healthy ) );
            auto vits = g->u.vitamins_from( obj );
            for( const auto& v : vitamin::all() ) {
                 r.push_back( to_string( vits[ v.first ] ) );
            }
            rows.push_back( r );
        };
        for( auto& e : item_controller->get_all_itypes() ) {
            if( e.second.comestible &&
                ( e.second.comestible->comesttype == "FOOD" ||
                  e.second.comestible->comesttype == "DRINK" ) ) {

                item food( e.first, calendar::turn, item::solitary_tag {} );
                if( g->u.can_eat( food, false, true ) == EDIBLE ) {
                    dump( food );
                }
            }
        }

    } else if( what == "GUN" ) {
        header = {
            "Name", "Ammo", "Volume", "Weight", "Capacity",
            "Range", "Dispersion", "Effective recoil", "Damage", "Pierce",
            "Aim time", "Effective range", "Snapshot range", "Max range"
        };

        std::set<std::string> locations;
        for( const auto& e : item_controller->get_all_itypes() ) {
            if( e.second.gun ) {
                std::transform( e.second.gun->valid_mod_locations.begin(),
                                e.second.gun->valid_mod_locations.end(),
                                std::inserter( locations, locations.begin() ),
                                []( const std::pair<std::string, int>& e ) { return e.first; } );
            }
        }
        for( const auto &e : locations ) {
            header.push_back( e );
        }

        auto dump = [&rows,&locations]( const standard_npc &who, const item& obj ) {
            std::vector<std::string> r;
            r.push_back( obj.tname( 1, false ) );
            r.push_back( obj.ammo_type() ? obj.ammo_type().str() : "" );
            r.push_back( to_string( obj.volume() / units::legacy_volume_factor ) );
            r.push_back( to_string( obj.weight() ) );
            r.push_back( to_string( obj.ammo_capacity() ) );
            r.push_back( to_string( obj.gun_range() ) );
            r.push_back( to_string( obj.gun_dispersion() ) );
            r.push_back( to_string( obj.gun_recoil( who ) ) );
            r.push_back( to_string( obj.gun_damage() ) );
            r.push_back( to_string( obj.gun_pierce() ) );

            r.push_back( to_string( who.gun_engagement_moves( obj ) ) );

            r.push_back( string_format( "%.1f", who.gun_engagement_range( obj, player::engagement::effective ) ) );
            r.push_back( string_format( "%.1f", who.gun_engagement_range( obj, player::engagement::snapshot ) ) );
            r.push_back( string_format( "%.1f", who.gun_engagement_range( obj, player::engagement::maximum ) ) );

            for( const auto &e : locations ) {
                r.push_back( to_string( obj.type->gun->valid_mod_locations[ e ] ) );
            }
            rows.push_back( r );
        };
        for( const auto& e : item_controller->get_all_itypes() ) {
            if( e.second.gun ) {
                item gun( e.first );
                if( !gun.magazine_integral() ) {
                    gun.emplace_back( gun.magazine_default() );
                }
                gun.ammo_set( default_ammo( gun.ammo_type() ), gun.ammo_capacity() );

                dump( test_npcs[ "S1" ], gun );

                if( gun.type->gun->barrel_length > 0 ) {
                    gun.emplace_back( "barrel_small" );
                    dump( test_npcs[ "S1" ], gun );
                }
            }
        }

    } else if( what == "VEHICLE" ) {
        header = {
            "Name", "Weight (empty)", "Weight (fueled)",
            "Max velocity (mph)", "Safe velocity (mph)", "Acceleration (mph/turn)",
            "Mass coeff %", "Aerodynamics coeff %", "Friction coeff %",
            "Traction coeff % (grass)"
        };
        auto dump = [&rows]( const vproto_id& obj ) {
            auto veh_empty = vehicle( obj, 0, 0 );
            auto veh_fueled = vehicle( obj, 100, 0 );

            std::vector<std::string> r;
            r.push_back( veh_empty.name );
            r.push_back( to_string( veh_empty.total_mass() ) );
            r.push_back( to_string( veh_fueled.total_mass() ) );
            r.push_back( to_string( veh_fueled.max_velocity() / 100 ) );
            r.push_back( to_string( veh_fueled.safe_velocity() / 100 ) );
            r.push_back( to_string( veh_fueled.acceleration() / 100 ) );
            r.push_back( to_string( (int)( 100 * veh_fueled.k_mass() ) ) );
            r.push_back( to_string( (int)( 100 * veh_fueled.k_aerodynamics() ) ) );
            r.push_back( to_string( (int)( 100 * veh_fueled.k_friction() ) ) );
            r.push_back( to_string( (int)( 100 * veh_fueled.k_traction( veh_fueled.wheel_area( false ) / 2.0f ) ) ) );
            rows.push_back( r );
        };
        for( auto& e : vehicle_prototype::get_all() ) {
            dump( e );
        }

    } else if( what == "VPART" ) {
        header = {
            "Name", "Location", "Weight", "Size"
        };
        auto dump = [&rows]( const vpart_info &obj ) {
            std::vector<std::string> r;
            r.push_back( obj.name() );
            r.push_back( obj.location );
            r.push_back( to_string( int( ceil( item( obj.item ).weight() / 1000.0 ) ) ) );
            r.push_back( to_string( obj.size / units::legacy_volume_factor ) );
            rows.push_back( r );
        };
        for( const auto &e : vpart_info::all() ) {
            dump( e.second );
        }

    } else if( what == "AIMING" ) {
        scol = -1; // unsorted output so graph columns have predictable ordering

        const int cycles = 1400;

        header = { "Name" };
        for( int i = 0; i <= cycles; ++i ) {
            header.push_back( to_string( i ) );
        }

        auto dump = [&rows]( const standard_npc &who, const item &gun) {
            std::vector<std::string> r( 1, string_format( "%s %s", who.get_name().c_str(), gun.tname().c_str() ) );
            double penalty = MIN_RECOIL;
            for( int i = 0; i <= cycles; ++i ) {
                penalty -= who.aim_per_move( gun, penalty );
                r.push_back( string_format( "%.2f", who.gun_current_range( gun, penalty ) ) );
            }
            rows.push_back( r );
        };

        if( opts.empty() ) {
            dump( test_npcs[ "S1" ], test_items[ "G1" ] );
            dump( test_npcs[ "S1" ], test_items[ "G2" ] );
            dump( test_npcs[ "S1" ], test_items[ "G3" ] );
            dump( test_npcs[ "S1" ], test_items[ "G4" ] );

        } else {
            for( const auto &str : opts ) {
                auto idx = str.find( ':' );
                if( idx == std::string::npos ) {
                    std::cerr << "cannot parse test case: " << str << std::endl;
                    return false;
                }
                auto test = std::make_pair( test_npcs.find( str.substr( 0, idx ) ),
                                            test_items.find( str.substr( idx + 1 ) ) );

                if( test.first == test_npcs.end() || test.second == test_items.end() ) {
                    std::cerr << "invalid test case: " << str << std::endl;
                    return false;
                }

                dump( test.first->second, test.second->second );
            }
        }

    } else if( what == "EXPLOSIVE" ) {
        header = {
            // @todo Should display more useful data: shrapnel damage, safe range
            "Name", "Power", "Power at 5 tiles", "Power halves at", "Shrapnel count", "Shrapnel mass"
        };

        auto dump = [&rows]( const std::string &name, const explosion_data &ex ) {
            std::vector<std::string> r;
            r.push_back( name );
            r.push_back( to_string( ex.power ) );
            r.push_back( string_format( "%.1f", ex.power_at_range( 5.0f ) ) );
            r.push_back( string_format( "%.1f", ex.expected_range( 0.5f ) ) );
            r.push_back( to_string( ex.shrapnel.count ) );
            r.push_back( to_string( ex.shrapnel.mass ) );
            rows.push_back( r );
        };
        for( const auto& e : item_controller->get_all_itypes() ) {
            const auto &itt = e.second;
            const auto use = itt.get_use( "explosion" );
            if( use != nullptr && use->get_actor_ptr() != nullptr ) {
                const auto actor = dynamic_cast<const explosion_iuse *>( use->get_actor_ptr() );
                if( actor != nullptr ) {
                    dump( itt.nname( 1 ), actor->explosion );
                }
            }

            auto c_ex = dynamic_cast<const explosion_iuse *>( itt.countdown_action.get_actor_ptr() );
            if( c_ex != nullptr ) {
                dump( itt.nname( 1 ), c_ex->explosion );
            }
        }

    } else {
        std::cerr << "unknown argument: " << what << std::endl;
        return false;
    }

    rows.erase( std::remove_if( rows.begin(), rows.end(), []( const std::vector<std::string>& e ) {
        return e.empty();
    } ), rows.end() );

    if( scol >= 0 ) {
        std::sort( rows.begin(), rows.end(), [&scol]( const std::vector<std::string>& lhs, const std::vector<std::string>& rhs ) {
            return lhs[ scol ] < rhs[ scol ];
        } );
    }

    rows.erase( std::unique( rows.begin(), rows.end() ), rows.end() );

    switch( mode ) {
        case dump_mode::TSV:
            rows.insert( rows.begin(), header );
            for( const auto& r : rows ) {
                std::copy( r.begin(), r.end() - 1, std::ostream_iterator<std::string>( std::cout, "\t" ) );
                std::cout << r.back() << "\n";
            }
            break;

        case dump_mode::HTML:
            std::cout << "<table>";

            std::cout << "<thead>";
            std::cout << "<tr>";
            for( const auto& col : header ) {
                std::cout << "<th>" << col << "</th>";
            }
            std::cout << "</tr>";
            std::cout << "</thead>";

            std::cout << "<tdata>";
            for( const auto& r : rows ) {
                std::cout << "<tr>";
                for( const auto& col : r ) {
                    std::cout << "<td>" << col << "</td>";
                }
                std::cout << "</tr>";
            }
            std::cout << "</tdata>";

            std::cout << "</table>";
            break;
    }

    return true;
}
Пример #4
0
void game::dump_stats( const std::string& what, dump_mode mode )
{
    load_core_data();
    DynamicDataLoader::get_instance().finalize_loaded_data();

    std::vector<std::string> header;
    std::vector<std::vector<std::string>> rows;

    if( what == "AMMO" ) {
        header = {
            "Name", "Ammo", "Volume", "Weight", "Stack",
            "Range", "Dispersion", "Recoil", "Damage", "Pierce"
        };
        auto dump = [&rows]( const item& obj ) {
            std::vector<std::string> r;
            r.push_back( obj.tname( false ) );
            r.push_back( obj.type->ammo->type );
            r.push_back( std::to_string( obj.volume() ) );
            r.push_back( std::to_string( obj.weight() ) );
            r.push_back( std::to_string( obj.type->stack_size ) );
            r.push_back( std::to_string( obj.type->ammo->range ) );
            r.push_back( std::to_string( obj.type->ammo->dispersion ) );
            r.push_back( std::to_string( obj.type->ammo->recoil ) );
            r.push_back( std::to_string( obj.type->ammo->damage ) );
            r.push_back( std::to_string( obj.type->ammo->pierce ) );
            rows.push_back( r );
        };
        for( auto& e : item_controller->get_all_itypes() ) {
            if( e.second->ammo ) {
                dump( item( e.first, calendar::turn, item::solitary_tag {} ) );
            }
        }

    } else if( what == "EDIBLE" ) {
        header = {
            "Name", "Volume", "Weight", "Stack", "Calories", "Quench", "Healthy"
        };
        for( const auto& v : vitamin::all() ) {
             header.push_back( v.second.name() );
        }
        auto dump = [&rows]( const item& obj ) {
            std::vector<std::string> r;
            r.push_back( obj.tname( false ) );
            r.push_back( std::to_string( obj.volume() ) );
            r.push_back( std::to_string( obj.weight() ) );
            r.push_back( std::to_string( obj.type->stack_size ) );
            r.push_back( std::to_string( obj.type->comestible->get_calories() ) );
            r.push_back( std::to_string( obj.type->comestible->quench ) );
            r.push_back( std::to_string( obj.type->comestible->healthy ) );
            auto vits = g->u.vitamins_from( obj );
            for( const auto& v : vitamin::all() ) {
                 r.push_back( std::to_string( vits[ v.first ] ) );
            }
            rows.push_back( r );
        };
        for( auto& e : item_controller->get_all_itypes() ) {
            if( e.second->comestible &&
                ( e.second->comestible->comesttype == "FOOD" ||
                  e.second->comestible->comesttype == "DRINK" ) ) {

                item food( e.first, calendar::turn, item::solitary_tag {} );
                if( g->u.can_eat( food, false, true ) == EDIBLE ) {
                    dump( food );
                }
            }
        }

    } else if( what == "GUN" ) {
        header = {
            "Name", "Ammo", "Volume", "Weight", "Capacity",
            "Range", "Dispersion", "Recoil", "Damage", "Pierce"
        };
        std::set<std::string> locations;
        for( const auto& e : item_controller->get_all_itypes() ) {
            if( e.second->gun ) {
                std::transform( e.second->gun->valid_mod_locations.begin(),
                                e.second->gun->valid_mod_locations.end(),
                                std::inserter( locations, locations.begin() ),
                                []( const std::pair<std::string, int>& e ) { return e.first; } );
            }
        }
        for( const auto &e : locations ) {
            header.push_back( e );
        }

        auto dump = [&rows,&locations]( const item& obj ) {
            std::vector<std::string> r;
            r.push_back( obj.tname( false ) );
            r.push_back( obj.ammo_type() != "NULL" ? obj.ammo_type() : "" );
            r.push_back( std::to_string( obj.volume() ) );
            r.push_back( std::to_string( obj.weight() ) );
            r.push_back( std::to_string( obj.ammo_capacity() ) );
            r.push_back( std::to_string( obj.gun_range() ) );
            r.push_back( std::to_string( obj.gun_dispersion() ) );
            r.push_back( std::to_string( obj.gun_recoil() ) );
            r.push_back( std::to_string( obj.gun_damage() ) );
            r.push_back( std::to_string( obj.gun_pierce() ) );
            for( const auto &e : locations ) {
                r.push_back( std::to_string( obj.type->gun->valid_mod_locations[ e ] ) );
            }
            rows.push_back( r );
        };
        for( const auto& e : item_controller->get_all_itypes() ) {
            if( e.second->gun ) {
                item gun( e.first );
                if( gun.is_reloadable() ) {
                    gun.ammo_set( default_ammo( gun.ammo_type() ), gun.ammo_capacity() );
                }
                dump( gun );

                if( gun.type->gun->barrel_length > 0 ) {
                    gun.emplace_back( "barrel_small" );
                    dump( gun );
                }
            }
        }

    } else if( what == "VEHICLE" ) {
        header = {
            "Name", "Weight (empty)", "Weight (fueled)"
        };
        auto dump = [&rows]( const vproto_id& obj ) {
            auto veh_empty = vehicle( obj, 0, 0 );
            auto veh_fueled = vehicle( obj, 100, 0 );

            std::vector<std::string> r;
            r.push_back( veh_empty.name );
            r.push_back( std::to_string( veh_empty.total_mass() ) );
            r.push_back( std::to_string( veh_fueled.total_mass() ) );
            rows.push_back( r );
        };
        for( auto& e : vehicle_prototype::get_all() ) {
            dump( e );
        }

    } else if( what == "VPART" ) {
        header = {
            "Name", "Location", "Weight", "Size"
        };
        auto dump = [&rows]( const vpart_info *obj ) {
            std::vector<std::string> r;
            r.push_back( obj->name() );
            r.push_back( obj->location );
            r.push_back( std::to_string( int( ceil( item( obj->item ).weight() / 1000.0 ) ) ) );
            r.push_back( std::to_string( obj->size ) );
            rows.push_back( r );
        };
        for( const auto e : vpart_info::get_all() ) {
            dump( e );
        }
    }

    rows.erase( std::remove_if( rows.begin(), rows.end(), []( const std::vector<std::string>& e ) {
        return e.empty();
    } ), rows.end() );

    std::sort( rows.begin(), rows.end(), []( const std::vector<std::string>& lhs, const std::vector<std::string>& rhs ) {
        return lhs[ 0 ] < rhs[ 0 ];
    } );

    rows.erase( std::unique( rows.begin(), rows.end() ), rows.end() );

    switch( mode ) {
        case dump_mode::TSV:
            rows.insert( rows.begin(), header );
            for( const auto& r : rows ) {
                std::copy( r.begin(), r.end() - 1, std::ostream_iterator<std::string>( std::cout, "\t" ) );
                std::cout << r.back() << "\n";
            }
            break;

        case dump_mode::HTML:
            std::cout << "<table>";

            std::cout << "<thead>";
            std::cout << "<tr>";
            for( const auto& col : header ) {
                std::cout << "<th>" << col << "</th>";
            }
            std::cout << "</tr>";
            std::cout << "</thead>";

            std::cout << "<tdata>";
            for( const auto& r : rows ) {
                std::cout << "<tr>";
                for( const auto& col : r ) {
                    std::cout << "<td>" << col << "</td>";
                }
                std::cout << "</tr>";
            }
            std::cout << "</tdata>";

            std::cout << "</table>";
            break;
    }
}
Пример #5
0
ErrorCode Intx2MeshOnSphere::update_tracer_data(EntityHandle out_set, Tag & tagElem, Tag & tagArea)
{
  EntityHandle dum = 0;

  Tag corrTag;
  ErrorCode rval = mb->tag_get_handle(CORRTAGNAME,
                                           1, MB_TYPE_HANDLE, corrTag,
                                           MB_TAG_DENSE, &dum); // it should have been created
  ERRORR(rval, "can't get correlation tag");

  Tag gid;
  rval = mb->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, gid, MB_TAG_DENSE);
  ERRORR(rval,"can't get global ID tag" );

  // get all polygons out of out_set; then see where are they coming from
  Range polys;
  rval = mb->get_entities_by_dimension(out_set, 2, polys);
  ERRORR(rval, "can't get polygons out");

  // rs2 is the red range, arrival; rs1 is blue, departure;
  // there is a connection between rs1 and rs2, through the corrTag
  // corrTag is __correlation
  // basically, mb->tag_get_data(corrTag, &(redPoly), 1, &bluePoly);
  // also,  mb->tag_get_data(corrTag, &(bluePoly), 1, &redPoly);
  // we start from rs2 existing, then we have to update something

  // tagElem will have multiple tracers
  int numTracers = 0;
  rval = mb->tag_get_length(tagElem, numTracers);
  ERRORR(rval, "can't get number of tracers in simulation");
  if (numTracers < 1)
    ERRORR(MB_FAILURE, "no tracers data");
  std::vector<double>  currentVals(rs2.size()*numTracers);
  rval = mb->tag_get_data(tagElem, rs2, &currentVals[0]);
  ERRORR(rval, "can't get existing tracers values");

  // create new tuple list for tracers to other processors, from remote_cells
#ifdef MOAB_HAVE_MPI
  if (remote_cells)
  {
    int n = remote_cells->get_n();
    if (n>0) {
      remote_cells_with_tracers = new TupleList();
      remote_cells_with_tracers->initialize(2, 0, 1, numTracers, n); // tracers are in these tuples
      remote_cells_with_tracers->enableWriteAccess();
      for (int i=0; i<n; i++)
      {
        remote_cells_with_tracers->vi_wr[2*i]=remote_cells->vi_wr[2*i];
        remote_cells_with_tracers->vi_wr[2*i+1]=remote_cells->vi_wr[2*i+1];
        //    remote_cells->vr_wr[i] = 0.; will have a different tuple for communication
        remote_cells_with_tracers->vul_wr[i]=   remote_cells->vul_wr[i];// this is the corresponding red cell (arrival)
        for (int k=0; k<numTracers; k++)
          remote_cells_with_tracers->vr_wr[numTracers*i+k] = 0; // initialize tracers to be transported
        remote_cells_with_tracers->inc_n();
      }
    }
    delete remote_cells;
    remote_cells = NULL;
  }
#endif
  // for each polygon, we have 2 indices: red and blue parents
  // we need index blue to update index red?
  std::vector<double> newValues(rs2.size()*numTracers, 0.);// initialize with 0 all of them
  // area of the polygon * conc on red (old) current quantity
  // finally, divide by the area of the red
  double check_intx_area=0.;
  for (Range::iterator it= polys.begin(); it!=polys.end(); ++it)
  {
    EntityHandle poly=*it;
    int blueIndex, redIndex;
    rval =  mb->tag_get_data(blueParentTag, &poly, 1, &blueIndex);
    ERRORR(rval, "can't get blue tag");
    EntityHandle blue = rs1[blueIndex];
    rval =  mb->tag_get_data(redParentTag, &poly, 1, &redIndex);
    ERRORR(rval, "can't get red tag");
    //EntityHandle red = rs2[redIndex];
    // big assumption here, red and blue are "parallel" ;we should have an index from
    // blue to red (so a deformed blue corresponds to an arrival red)
    double areap = area_spherical_element(mb, poly, R);
    check_intx_area+=areap;
    // so the departure cell at time t (blueIndex) covers a portion of a redCell
    // that quantity will be transported to the redCell at time t+dt
    // the blue corresponds to a red arrival
    EntityHandle redArr;
    rval = mb->tag_get_data(corrTag, &blue, 1, &redArr);
    if (0==redArr || MB_TAG_NOT_FOUND==rval)
    {
#ifdef MOAB_HAVE_MPI
      if (!remote_cells_with_tracers)
        ERRORR( MB_FAILURE, "no remote cells, failure\n");
      // maybe the element is remote, from another processor
      int global_id_blue;
      rval = mb->tag_get_data(gid, &blue, 1, &global_id_blue);
      ERRORR(rval, "can't get arrival red for corresponding blue gid");
      // find the
      int index_in_remote = remote_cells_with_tracers->find(1, global_id_blue);
      if (index_in_remote==-1)
        ERRORR( MB_FAILURE, "can't find the global id element in remote cells\n");
      for (int k=0; k<numTracers; k++)
        remote_cells_with_tracers->vr_wr[index_in_remote*numTracers+k] +=
            currentVals[numTracers*redIndex+k]*areap;
#endif
    }
    else if (MB_SUCCESS==rval)
    {
      int arrRedIndex = rs2.index(redArr);
      if (-1 == arrRedIndex)
        ERRORR(MB_FAILURE, "can't find the red arrival index");
      for (int k=0; k<numTracers; k++)
        newValues[numTracers*arrRedIndex+k] += currentVals[redIndex*numTracers+k]*areap;
    }

    else
      ERRORR(rval, "can't get arrival red for corresponding ");
  }
  // now, send back the remote_cells_with_tracers to the processors they came from, with the updated values for
  // the tracer mass in a cell
#ifdef MOAB_HAVE_MPI
  if (remote_cells_with_tracers)
  {
    // so this means that some cells will be sent back with tracer info to the procs they were sent from
    (parcomm->proc_config().crystal_router())->gs_transfer(1, *remote_cells_with_tracers, 0);
    // now, look at the global id, find the proper "red" cell with that index and update its mass
    //remote_cells->print("remote cells after routing");
    int n = remote_cells_with_tracers->get_n();
    for (int j=0; j<n; j++)
    {
      EntityHandle redCell = remote_cells_with_tracers->vul_rd[j];// entity handle sent back
      int arrRedIndex = rs2.index(redCell);
      if (-1 == arrRedIndex)
        ERRORR(MB_FAILURE, "can't find the red arrival index");
      for (int k=0; k<numTracers; k++)
        newValues[arrRedIndex*numTracers+k] += remote_cells_with_tracers->vr_rd[j*numTracers+k];
    }
  }
#endif /* MOAB_HAVE_MPI */
  // now divide by red area (current)
  int j=0;
  Range::iterator iter = rs2.begin();
  void * data=NULL; //used for stored area
  int count =0;
  std::vector<double> total_mass_local(numTracers, 0.);
  while (iter != rs2.end())
  {
    rval = mb->tag_iterate(tagArea, iter, rs2.end(), count, data);
    ERRORR(rval, "can't tag iterate");
    double * ptrArea=(double*)data;
    for (int i=0; i<count; i++, ++iter, j++, ptrArea++)
    {
      for (int k=0; k<numTracers; k++)
      {
        total_mass_local[k]+=newValues[j*numTracers+k];
        newValues[j*numTracers+k]/= (*ptrArea);
      }
    }
  }
  rval = mb->tag_set_data(tagElem, rs2, &newValues[0]);
  ERRORR(rval, "can't set new values tag");


#ifdef MOAB_HAVE_MPI
  std::vector<double> total_mass(numTracers,0.);
  double total_intx_area =0;
  int mpi_err = MPI_Reduce(&total_mass_local[0], &total_mass[0], numTracers, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  if (MPI_SUCCESS != mpi_err) return MB_FAILURE;
  // now reduce total area
  mpi_err = MPI_Reduce(&check_intx_area, &total_intx_area, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  if (MPI_SUCCESS != mpi_err) return MB_FAILURE;
  if (my_rank==0)
  {
    for (int k=0; k<numTracers; k++)
      std::cout <<"total mass now tracer k=" << k+1<<" "  << total_mass[k] << "\n";
    std::cout <<"check: total intersection area: (4 * M_PI * R^2): " << 4 * M_PI * R*R << " " << total_intx_area << "\n";
  }

  if (remote_cells_with_tracers)
  {
    delete remote_cells_with_tracers;
    remote_cells_with_tracers=NULL;
  }
#else
  for (int k=0; k<numTracers; k++)
        std::cout <<"total mass now tracer k=" << k+1<<" "  << total_mass_local[k] << "\n";
  std::cout <<"check: total intersection area: (4 * M_PI * R^2): " << 4 * M_PI * R*R << " " << check_intx_area << "\n";
#endif
  return MB_SUCCESS;
}