00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <cmath>
00022
00023 #include "util/messaginghub.h"
00024 #include "statistics.h"
00025 #include "vehicle.h"
00026 #include "viewcalculation.h"
00027 #include "attack.h"
00028 #include "spfst.h"
00029 #include "widgets/textrenderer.h"
00030
00031
00032 double StatisticsCalculator::strength( const ContainerBase* c, bool recurse )
00033 {
00034 double s = 0;
00035 const Vehicle* veh = dynamic_cast<const Vehicle*>(c);
00036 if ( veh ) {
00037 s = veh->typ->productionCost.energy + veh->typ->productionCost.material;
00038 AttackFormula af( c->getMap() );
00039 s *= (af.strength_experience( veh->experience) + af.defense_experience( veh->experience))/2 + 1.0 ;
00040 s *= af.strength_damage( veh->damage );
00041 s/=10000;
00042 }
00043
00044 if ( recurse )
00045 for ( ContainerBase::Cargo::const_iterator i = c->getCargo().begin(); i != c->getCargo().end(); ++i )
00046 if ( *i )
00047 s += strength( *i, recurse );
00048
00049 return s;
00050 }
00051
00052 int StatisticsCalculator::unitCount( const ContainerBase* c, bool recurse )
00053 {
00054 int counter = 1;
00055 if ( recurse )
00056 for ( ContainerBase::Cargo::const_iterator i = c->getCargo().begin(); i != c->getCargo().end(); ++i )
00057 if ( *i )
00058 counter += unitCount( *i, recurse );
00059 return counter;
00060 }
00061
00062
00063 Resources StatisticsCalculator::resource(const ContainerBase* c, bool recurse )
00064 {
00065 Resources res = c->baseType->productionCost;
00066 for ( int r = 0; r < 3; ++r )
00067 res.resource(r) += c->getAvailableResource( maxint, r, 0 );
00068
00069 if ( recurse )
00070 for ( ContainerBase::Cargo::const_iterator i = c->getCargo().begin(); i != c->getCargo().end(); ++i )
00071 if ( *i )
00072 res += resource(*i, recurse);
00073
00074 return res;
00075 }
00076
00077 int StatisticsCalculator::unitCost( const ContainerBase* c, bool recurse )
00078 {
00079 Resources res = c->baseType->productionCost;
00080
00081 if ( recurse )
00082 for ( ContainerBase::Cargo::const_iterator i = c->getCargo().begin(); i != c->getCargo().end(); ++i )
00083 if ( *i )
00084 res.material += unitCost(*i, recurse);
00085
00086 return res.material;
00087 }
00088
00089
00090 ASCString getVisibilityStatistics( GameMap* actmap )
00091 {
00092 ASCString msg;
00093
00094 computeview ( actmap, 0, true );
00095
00096 for ( int i = 0; i < actmap->getPlayerCount(); i++ ) {
00097 if ( actmap->player[i].exist() ) {
00098 msg += ASCString("#fontsize=14#Player ") + ASCString::toString( i ) + ": "+ actmap->player[i].getName() + "#fontsize=12#\n" ;
00099 int notVisible = 0;
00100 int fogOfWar = 0;
00101 int visible = 0;
00102 int viewDominance = 0;
00103 for ( int x = 0; x < actmap->xsize; x++ )
00104 for ( int y = 0; y < actmap->ysize; y++ ) {
00105 MapField* fld = actmap->getField ( x, y );
00106 VisibilityStates vs = fieldVisibility ( fld, i );
00107 switch ( vs ) {
00108 case visible_not:
00109 ++notVisible;
00110 break;
00111 case visible_ago:
00112 ++fogOfWar;
00113 break;
00114 default:
00115 ++visible;
00116 }
00117
00118 if ( vs == visible_all || vs == visible_now ) {
00119 int maxView = -1;
00120 for ( int p = 0; p < actmap->getPlayerCount(); ++p )
00121 if ( actmap->getPlayer(p).stat != Player::supervisor )
00122 if ( fld->view[p].view > maxView )
00123 maxView = fld->view[p].view;
00124
00125 if ( fld->view[i].view == maxView )
00126 ++viewDominance;
00127 }
00128
00129 }
00130 msg += ASCString(" not visible: ") + ASCString::toString(notVisible ) + " fields\n";
00131 msg += ASCString(" fog of war: ") + ASCString::toString(fogOfWar ) + " fields\n";
00132 msg += ASCString(" visible: ") + ASCString::toString(visible ) + " fields\n";
00133 msg += ASCString(" view dominant: ") + ASCString::toString(viewDominance ) + " fields\n\n";
00134 }
00135 }
00136
00137 computeview ( actmap, 0 , false );
00138
00139 return msg;
00140 }
00141
00142 ASCString getPlayerStrength( GameMap* gamemap )
00143 {
00144 ASCString message;
00145 for ( int i = 0; i< gamemap->getPlayerCount(); ++i ) {
00146 double strength = 0;
00147 Resources r;
00148 Resources total;
00149 for ( Player::VehicleList::iterator j = gamemap->player[i].vehicleList.begin(); j != gamemap->player[i].vehicleList.end(); ++j ) {
00150 strength += StatisticsCalculator::strength( *j, false );
00151 r += (*j)->typ->productionCost;
00152 total += StatisticsCalculator::resource( *j, false );
00153 }
00154
00155 for ( Player::BuildingList::iterator j = gamemap->player[i].buildingList.begin(); j != gamemap->player[i].buildingList.end(); ++j ) {
00156 total += StatisticsCalculator::resource( *j, false );
00157 }
00158
00159 message += ASCString("#fontsize=14#Player ") + ASCString::toString( i ) + ": "+ gamemap->player[i].getName() + "#fontsize=12#\n" ;
00160 message += "strength: ";
00161 ASCString s;
00162 s.format("%9.0f", ceil(strength) );
00163 message += s + "\n";
00164 message += "Unit production cost ";
00165 for ( int k = 1; k < 2; ++k ) {
00166 message += resourceNames[k];
00167 message += ": " + ASCString::toString(r.resource(k)/1000 ) + "k\n";
00168 }
00169 message += "Unit count: " + ASCString::toString( int( gamemap->player[i].vehicleList.size())) + "\n";
00170 message += "Material index: " + ASCString::toString( total.material/1000 ) + "k\n";
00171 message += "\n\n";
00172
00173 }
00174 return message;
00175 }
00176
00177
00178
00179 void pbpplayerstatistics( GameMap* gamemap )
00180 {
00181 ASCString msg;
00182 {
00183 StatusMessageWindowHolder smw = MessagingHub::Instance().infoMessageWindow( "calculating... " );
00184
00185 msg = "#fontsize=18#Map Statistics for " + gamemap->maptitle + "#fontsize=12#\n\n";
00186
00187 msg += "#fontsize=16#Visibility#fontsize=12#\n";
00188 msg += getVisibilityStatistics( gamemap );
00189
00190 msg += "#fontsize=16#Strength#fontsize=12#\n";
00191 msg += getPlayerStrength( gamemap );
00192 }
00193
00194 ViewFormattedText vft ( "Map Statistics", msg, PG_Rect(-1,-1,600,600));
00195 vft.Show();
00196 vft.RunModal();
00197 }
00198