void GenerateStats (CUniverse &Universe, CXMLElement *pCmdLine) { int i; printf("STATS\n\n"); int iItemTypes = 0; for (i = 0; i < Universe.GetItemTypeCount(); i++) { CItemType *pType = Universe.GetItemType(i); // Do not count virtual items if (pType->IsVirtual()) continue; iItemTypes++; } printf("Item types:\t\t%d\n", iItemTypes); printf("Ship classes:\t\t%d\n", Universe.GetShipClassCount()); printf("Station types:\t\t%d\n", Universe.GetStationTypeCount()); }
void GenerateEncounterTable (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i, j; // Get the criteria from the command line SEncounterCriteria Criteria; ParseEncounterCriteria(pCmdLine->GetAttribute(CRITERIA_ATTRIB), &Criteria); bool bAll = pCmdLine->GetAttributeBool(ALL_ATTRIB); // Generate a table of all matching encounters CSymbolTable Table(FALSE, TRUE); // Loop over all items for this level and add them to // a sorted table. for (i = 0; i < Universe.GetStationTypeCount(); i++) { CStationType *pType = Universe.GetStationType(i); int iLevel = pType->GetLevel(); if (iLevel == 0 && !bAll) continue; // If we don't match the criteria, then continue if (!MatchesEncounterCriteria(Criteria, pType->GetAttributes())) continue; // Get the category and name CString sCategory = pType->GetDataField(FIELD_CATEGORY); CString sName = pType->GetDataField(FIELD_NAME); if (*sName.GetASCIIZPointer() == '(') sName = strSubString(sName, 1, -1); // Figure out the sort order char szBuffer[1024]; wsprintf(szBuffer, "%02d%s%s", pType->GetLevel(), sCategory.GetASCIIZPointer(), sName.GetASCIIZPointer()); Table.AddEntry(CString(szBuffer), (CObject *)pType); } // Generate a list of columns to display CStringArray Cols; Cols.AppendString(FIELD_LEVEL); Cols.AppendString(FIELD_CATEGORY); Cols.AppendString(FIELD_NAME); if (pCmdLine->GetAttributeBool(FIELD_ARMOR_CLASS)) Cols.AppendString(FIELD_ARMOR_CLASS); if (pCmdLine->GetAttributeBool(FIELD_HP)) Cols.AppendString(FIELD_HP); if (pCmdLine->GetAttributeBool(FIELD_FIRE_RATE_ADJ)) Cols.AppendString(FIELD_FIRE_RATE_ADJ); if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT)) Cols.AppendString(FIELD_TOTAL_COUNT); if (pCmdLine->GetAttributeBool(FIELD_CAN_ATTACK)) Cols.AppendString(FIELD_CAN_ATTACK); if (pCmdLine->GetAttributeBool(FIELD_EXPLOSION_TYPE)) Cols.AppendString(FIELD_EXPLOSION_TYPE); // If we need to output total count, then load the table CSymbolTable TotalCount(TRUE, TRUE); if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT)) { if (error = LoadTotalCount(TOTAL_COUNT_FILENAME, TotalCount)) return; } // If we've got any entries in the table, output now if (Table.GetCount()) { // Output the header for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); printf(Cols.GetStringValue(j).GetASCIIZPointer()); } printf("\n"); // Output each row for (i = 0; i < Table.GetCount(); i++) { CStationType *pType = (CStationType *)Table.GetValue(i); for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); CString sField = Cols.GetStringValue(j); CString sValue = pType->GetDataField(sField); if (strEquals(sField, FIELD_FIRE_RATE_ADJ)) printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_TOTAL_COUNT)) { double rCount = 0.0; CString sKey = strFromInt(pType->GetUNID(), FALSE); EntryInfo *pEntry; if (TotalCount.Lookup(sKey, (CObject **)&pEntry) == NOERROR) rCount = pEntry->rTotalCount; printf("%.2f", rCount); } else printf(sValue.GetASCIIZPointer()); } printf("\n"); } printf("\n"); } else printf("No entries match criteria.\n"); }
void RunEncounterSim (CUniverse &Universe, CXMLElement *pCmdLine) { int iRuns = pCmdLine->GetAttributeIntegerBounded(COUNT_ATTRIB, 1, -1, DEFAULT_RUN_COUNT); int iTimeOut = DEFAULT_TIME_OUT; // Get the station criteria CString sCriteria = strPatternSubst(CONSTLIT("%s t"), pCmdLine->GetAttribute(DEFENDERS_ATTRIB)); CDesignTypeCriteria DefenderCriteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &DefenderCriteria) != NOERROR) { printf("ERROR: Unable to parse defenders criteria.\n"); return; } bool bAll = pCmdLine->GetAttributeBool(CONSTLIT("all")); // Get the criteria from the command line. Always append 's' because we // want ship classes. sCriteria = strPatternSubst(CONSTLIT("%s s"), pCmdLine->GetAttribute(ATTACKERS_ATTRIB)); CDesignTypeCriteria AttackerCriteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &AttackerCriteria) != NOERROR) { printf("ERROR: Unable to parse attackers criteria.\n"); return; } // Create a viewer, if desired CSimViewer Viewer; if (pCmdLine->GetAttributeBool(VIEWER_ATTRIB)) Viewer.Create(); // Print headers printf("Encounter\tLevel"); int iAttacker; for (iAttacker = 0; iAttacker < Universe.GetShipClassCount(); iAttacker++) { CShipClass *pAttackerClass = Universe.GetShipClass(iAttacker); if (!pAttackerClass->MatchesCriteria(AttackerCriteria)) continue; printf("\t%s", pAttackerClass->GetName().GetASCIIZPointer()); } printf("\n"); // Loop over all defenders int iDefender; for (iDefender = 0; iDefender < Universe.GetStationTypeCount(); iDefender++) { CStationType *pDefenderType = Universe.GetStationType(iDefender); if (!bAll && pDefenderType->GetLevel() == 0) continue; if (!pDefenderType->MatchesCriteria(DefenderCriteria)) continue; // Compute an enemy of the station CSovereign *pAttackerSovereign = GetAttackerSovereign(Universe, pDefenderType); if (pAttackerSovereign == NULL) { printf("ERROR: Unable to find enemy sovereign of encounter: %s [%x].\n", pDefenderType->GetNounPhrase().GetASCIIZPointer(), pDefenderType->GetUNID()); return; } printf("%s [%x]\t%d", pDefenderType->GetNounPhrase().GetASCIIZPointer(), pDefenderType->GetUNID(), pDefenderType->GetLevel()); // Loop over all attackers for (iAttacker = 0; iAttacker < Universe.GetShipClassCount(); iAttacker++) { CShipClass *pAttackerClass = Universe.GetShipClass(iAttacker); if (!pAttackerClass->MatchesCriteria(AttackerCriteria)) continue; // Do several runs so we can get some statistical data int iAttackerSurvived = 0; int iRun; for (iRun = 0; iRun < iRuns; iRun++) { EResults iResult = RunEncounter(Universe, Viewer, pDefenderType, pAttackerClass, pAttackerSovereign); if (iResult == resultError) return; // Did the attacker survive? if (iResult != resultAttackerDestroyed) iAttackerSurvived++; } // Output results for this attacker int iSurvivability = 100 * iAttackerSurvived / iRuns; printf("\t%d%%", iSurvivability); } printf("\n"); } Viewer.Destroy(); }
void GenerateEncounterTable (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i, j; // Get the criteria from the command line. Always append 't' because we // want station types. CString sCriteria = strPatternSubst(CONSTLIT("%s t"), pCmdLine->GetAttribute(CRITERIA_ATTRIB)); // Parse it CDesignTypeCriteria Criteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR) { printf("ERROR: Unable to parse criteria.\n"); return; } bool bAll = pCmdLine->GetAttributeBool(ALL_ATTRIB); // Generate a table of all matching encounters CSymbolTable Table(FALSE, TRUE); // Loop over all items for this level and add them to // a sorted table. for (i = 0; i < Universe.GetStationTypeCount(); i++) { CStationType *pType = Universe.GetStationType(i); int iLevel = pType->GetLevel(); if (iLevel == 0 && !bAll) continue; // If we don't match the criteria, then continue if (!pType->MatchesCriteria(Criteria)) continue; // Get the category and name CString sCategory = pType->GetDataField(FIELD_CATEGORY); CString sName = pType->GetDataField(FIELD_NAME); if (*sName.GetASCIIZPointer() == '(') sName = strSubString(sName, 1, -1); // Figure out the sort order char szBuffer[1024]; wsprintf(szBuffer, "%02d%s%s", pType->GetLevel(), sCategory.GetASCIIZPointer(), sName.GetASCIIZPointer()); Table.AddEntry(CString(szBuffer), (CObject *)pType); } // Generate a list of columns to display TArray<CString> Cols; Cols.Insert(FIELD_LEVEL); Cols.Insert(FIELD_CATEGORY); Cols.Insert(FIELD_NAME); for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (!strEquals(sAttrib, CONSTLIT("all")) && !strEquals(sAttrib, CONSTLIT("criteria")) && !strEquals(sAttrib, CONSTLIT("encountertable")) && !strEquals(sAttrib, CONSTLIT("nologo"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Cols.Insert(sAttrib); } } #if 0 if (pCmdLine->GetAttributeBool(FIELD_ARMOR_CLASS)) Cols.Insert(FIELD_ARMOR_CLASS); if (pCmdLine->GetAttributeBool(FIELD_HP)) Cols.Insert(FIELD_HP); if (pCmdLine->GetAttributeBool(FIELD_FIRE_RATE_ADJ)) Cols.Insert(FIELD_FIRE_RATE_ADJ); if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT)) Cols.Insert(FIELD_TOTAL_COUNT); if (pCmdLine->GetAttributeBool(FIELD_CAN_ATTACK)) Cols.Insert(FIELD_CAN_ATTACK); if (pCmdLine->GetAttributeBool(FIELD_EXPLOSION_TYPE)) Cols.Insert(FIELD_EXPLOSION_TYPE); #endif // If we need to output total count, then load the table CSymbolTable TotalCount(TRUE, TRUE); if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT)) { if (error = LoadTotalCount(TOTAL_COUNT_FILENAME, TotalCount)) return; } // If we've got any entries in the table, output now if (Table.GetCount()) { // Output the header for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); printf(Cols[j].GetASCIIZPointer()); } printf("\n"); // Output each row for (i = 0; i < Table.GetCount(); i++) { CStationType *pType = (CStationType *)Table.GetValue(i); for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Cols[j]; CString sValue = pType->GetDataField(sField); if (strEquals(sField, FIELD_FIRE_RATE_ADJ)) printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_TOTAL_COUNT)) { double rCount = 0.0; CString sKey = strFromInt(pType->GetUNID(), false); EntryInfo *pEntry; if (TotalCount.Lookup(sKey, (CObject **)&pEntry) == NOERROR) rCount = pEntry->rTotalCount; printf("%.2f", rCount); } else printf(sValue.GetASCIIZPointer()); } printf("\n"); } printf("\n"); } else printf("No entries match criteria.\n"); }
void GenerateStationFrequencyTable (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j; printf("STATION FREQUENCY TABLE\n\n"); // Figure out which columns to show TArray<CString> Cols; Cols.Insert(CONSTLIT("Level")); Cols.Insert(CONSTLIT("Freq")); Cols.Insert(CONSTLIT("Name")); Cols.Insert(CONSTLIT("Type")); Cols.Insert(CONSTLIT("Environment")); // Print the header for (i = 0; i < Cols.GetCount(); i++) { if (i != 0) printf("\t"); printf("%s", (LPSTR)Cols[i]); } printf("\n"); // For all levels, 1-25 int iLevel; for (iLevel = 1; iLevel <= MAX_ITEM_LEVEL; iLevel++) { CSymbolTable Sort(FALSE, TRUE); // Find all stations for this level and add them to // a sorting table for (i = 0; i < Universe.GetStationTypeCount(); i++) { CStationType *pType = Universe.GetStationType(i); if (pType->GetFrequencyByLevel(iLevel) > 0) { char szBuffer[256]; wsprintf(szBuffer, "%02d %s", ftCommon - pType->GetFrequencyByLevel(iLevel), pType->GetName().GetASCIIZPointer()); Sort.AddEntry(CString(szBuffer), (CObject *)pType); } } // Print out the stations for this level if (Sort.GetCount() > 0) { for (i = 0; i < Sort.GetCount(); i++) { CStationType *pType = (CStationType *)Sort.GetValue(i); for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); if (strEquals(Cols[j], CONSTLIT("Level"))) printf("%d", iLevel); else if (strEquals(Cols[j], CONSTLIT("Freq"))) printf((LPSTR)FrequencyChar(pType->GetFrequencyByLevel(iLevel))); else if (strEquals(Cols[j], CONSTLIT("Name"))) printf((LPSTR)pType->GetName()); else if (strEquals(Cols[j], CONSTLIT("Type"))) { if (pType->HasAttribute(CONSTLIT("enemy"))) printf("Enemy"); else if (pType->HasAttribute(CONSTLIT("debris"))) printf("Debris"); else printf("Friend"); } else if (strEquals(Cols[j], CONSTLIT("Environment"))) { bool bElements = false; if (pType->HasAttribute(CONSTLIT("envAir"))) { if (bElements) printf(", "); printf("envAir"); bElements = true; } if (pType->HasAttribute(CONSTLIT("envEarth"))) { if (bElements) printf(", "); printf("envEarth"); bElements = true; } if (pType->HasAttribute(CONSTLIT("envFire"))) { if (bElements) printf(", "); printf("envFire"); bElements = true; } if (pType->HasAttribute(CONSTLIT("envWater"))) { if (bElements) printf(", "); printf("envWater"); bElements = true; } if (!bElements) printf("None"); } } printf("\n"); } } } }
void GenerateEncounterTable (CUniverse &Universe, CXMLElement *pCmdLine, CIDTable &EntityTable) { ALERROR error; int i, j; // Get the criteria from the command line. Always append 't' because we // want station types. CString sCriteria = strPatternSubst(CONSTLIT("%s t"), pCmdLine->GetAttribute(CRITERIA_ATTRIB)); // Parse it CDesignTypeCriteria Criteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR) { printf("ERROR: Unable to parse criteria.\n"); return; } bool bAll = pCmdLine->GetAttributeBool(ALL_ATTRIB); bool bOnlyNotRandom = pCmdLine->GetAttributeBool(ONLY_NOT_RANDOM_ATTRIB); // Generate a table of all matching encounters CSymbolTable Table(FALSE, TRUE); // Loop over all items for this level and add them to // a sorted table. for (i = 0; i < Universe.GetStationTypeCount(); i++) { CStationType *pType = Universe.GetStationType(i); int iLevel = pType->GetLevel(); // If we're selecting all types, then do it if (bAll) ; // If we only want non-random types, then skip any random encounters. else if (bOnlyNotRandom) { if (pType->CanBeEncounteredRandomly()) continue; } // Otherwise we skip anything except random encounters. else { if (!pType->CanBeEncounteredRandomly()) continue; } // If we don't match the criteria, then continue if (!pType->MatchesCriteria(Criteria)) continue; // Get the category and name CString sCategory = pType->GetDataField(FIELD_CATEGORY); CString sName = pType->GetDataField(FIELD_NAME); if (*sName.GetASCIIZPointer() == '(') sName = strSubString(sName, 1, -1); // Figure out the sort order char szBuffer[1024]; wsprintf(szBuffer, "%02d%s%s%08x", iLevel, sCategory.GetASCIIZPointer(), sName.GetASCIIZPointer(), pType->GetUNID()); Table.AddEntry(CString(szBuffer), (CObject *)pType); } // Generate a list of columns to display TArray<CString> Cols; Cols.Insert(FIELD_LEVEL); Cols.Insert(FIELD_CATEGORY); Cols.Insert(FIELD_NAME); for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, ONLY_NOT_RANDOM_ATTRIB) && !strEquals(sAttrib, CONSTLIT("encountertable"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Cols.Insert(sAttrib); } } // If we need to output total count, then load the table CDesignTypeStats TotalCount; if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT) || pCmdLine->GetAttributeBool(FIELD_COUNT_DISTRIBUTION)) { if (error = LoadDesignTypeStats(&TotalCount)) return; } // If we've got any entries in the table, output now if (Table.GetCount()) { // Output the header for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); printf(Cols[j].GetASCIIZPointer()); } printf("\n"); // Output each row for (i = 0; i < Table.GetCount(); i++) { CStationType *pType = (CStationType *)Table.GetValue(i); for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Cols[j]; // Get the value CString sValue; if (strEquals(sField, FIELD_ENTITY)) { CString *pValue; if (EntityTable.Lookup(pType->GetUNID(), (CObject **)&pValue) == NOERROR) sValue = *pValue; else sValue = CONSTLIT("?"); } else sValue = pType->GetDataField(sField); // Format and output if (strEquals(sField, FIELD_FIRE_RATE_ADJ)) printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_TOTAL_COUNT)) { SDesignTypeInfo *pInfo = TotalCount.GetAt(pType->GetUNID()); double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0); printf("%.2f", rCount); } else if (strEquals(sField, FIELD_COUNT_DISTRIBUTION)) { SDesignTypeInfo *pInfo = TotalCount.GetAt(pType->GetUNID()); printf("%s", (pInfo ? pInfo->sDistribution : NULL_STR).GetASCIIZPointer()); } else printf(sValue.GetASCIIZPointer()); } printf("\n"); } printf("\n"); } else printf("No entries match criteria.\n"); }