/** @file /ai/Strategizer/strategyserialization.cpp @brief Zdrojovy kod tridy ukladani dat pro AI hrace. Zdrojovy kod tridy ukladani dat pro AI hrace. @author PZ @version 0.1 */ #include "ai/Strategizer/strategyserialization.h" namespace ai_ns { namespace strategizer_ns { // CStrategySerialization class implementation CStrategySerialization::CStrategySerialization(TPacket_AI_LetsGo* WorldPointers) { SIP=WorldPointers; clearInnerStructure(); } CStrategySerialization::~CStrategySerialization() { clearInnerStructure(); } void CStrategySerialization::loadDataToInnerStructure(char* data) throw(E_8K_AI_Strategy_AIDataReadingError) { clearInnerStructure(); if (data) { try { size_t bigstrlen=strlen(data); size_t strcnt=0; MoneyAttack=readNumWithSeparator(data,strcnt,'|',bigstrlen); MoneyDefence=readNumWithSeparator(data,strcnt,'|',bigstrlen); MoneyExpansion=readNumWithSeparator(data,strcnt,'|',bigstrlen); strcnt++; bool reading_unit_info=(data[strcnt]!='@'); while (reading_unit_info) { TAIUnitInfo added_unit_info; added_unit_info.world_id=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_unit_info.unit_type=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_unit_info.global_desire=(TUnitGlobalDesire) readNumWithSeparator(data,strcnt,'|',bigstrlen); UnitsInfo.push_back(added_unit_info); reading_unit_info=(data[strcnt]!='@'); } strcnt++; bool reading_attack_info=(data[strcnt]!='@'); while (reading_attack_info) { TAIAttackInfo added_attack_info; bool reading_attacking_slots=(data[strcnt]!='|'); while (reading_attacking_slots) { TAttackingUnitSlot added_attack_slot; added_attack_slot.assigned=(readNumWithSeparator(data,strcnt,'$',bigstrlen)!=0); added_attack_slot.assigned_unit_id=readNumWithSeparator(data,strcnt,'$',bigstrlen); added_attack_slot.needed_unit_type=readNumWithSeparator(data,strcnt,'$',bigstrlen); added_attack_slot.unit_position=readNumWithSeparator(data,strcnt,'$',bigstrlen); added_attack_slot.synchronized=(readNumWithSeparator(data,strcnt,'$',bigstrlen)!=0); (added_attack_info.units_for_attack).push_back(added_attack_slot); reading_attacking_slots=(data[strcnt]!='|'); } strcnt++; added_attack_info.attack_state=(TAttackState) readNumWithSeparator(data,strcnt,'|',bigstrlen); added_attack_info.synchronization_point=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_attack_info.target_point=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_attack_info.target_unit_id=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_attack_info.attack_target_type=(TAttackTargetType) readNumWithSeparator(data,strcnt,'|',bigstrlen); AttacksInfo.push_back(added_attack_info); reading_attack_info=(data[strcnt]!='@'); } strcnt++; bool reading_build_desires=(data[strcnt]!='@'); while (reading_build_desires) { TAIBuildDesireInfo added_build_desire; added_build_desire.builder_assigned=(readNumWithSeparator(data,strcnt,'|',bigstrlen)!=0); added_build_desire.builder_id=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_build_desire.building_type=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_build_desire.build_target_point=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_build_desire.bridge_placement=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_build_desire.building_orientation=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_build_desire.started_to_build=(readNumWithSeparator(data,strcnt,'|',bigstrlen)!=0); added_build_desire.done=(readNumWithSeparator(data,strcnt,'|',bigstrlen)!=0); BuildDesiresInfo.push_back(added_build_desire); reading_build_desires=(data[strcnt]!='@'); } strcnt++; bool reading_repair_desires=(data[strcnt]!='@'); while (reading_repair_desires) { TAIRepairDesireInfo added_repair_desire; added_repair_desire.builder_assigned=(readNumWithSeparator(data,strcnt,'|',bigstrlen)!=0); added_repair_desire.builder_id=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_repair_desire.repair_target_point=readNumWithSeparator(data,strcnt,'|',bigstrlen); added_repair_desire.started_to_repair=(readNumWithSeparator(data,strcnt,'|',bigstrlen)!=0); added_repair_desire.done=(readNumWithSeparator(data,strcnt,'|',bigstrlen)!=0); RepairDesiresInfo.push_back(added_repair_desire); reading_repair_desires=(data[strcnt]!='@'); } strcnt++; } catch (E_8K_AI_Strategy_AIDataReadingError) { defaultInnerStructureInit(); } } else { defaultInnerStructureInit(); } } char* CStrategySerialization::saveDataFromInnerStructure() { char tmpbuffer[MAX_AI_DATA_LENGTH]; size_t tblen=0; addIntValueToString(MoneyAttack,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(MoneyDefence,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(MoneyExpansion,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addCharToString('@',tmpbuffer,tblen); std::UNIT_AI_INFO_CONTAINER::iterator uiIt; for(uiIt=UnitsInfo.begin();uiIt!=UnitsInfo.end();uiIt++) { addIntValueToString(uiIt->world_id,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(uiIt->unit_type,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString((int) (uiIt->global_desire),tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); } addCharToString('@',tmpbuffer,tblen); std::ATTACKS_AI_INFO_CONTAINER::iterator aiIt; for(aiIt=AttacksInfo.begin();aiIt!=AttacksInfo.end();aiIt++) { std::ATTACK_SLOTS_CONTAINER::iterator asIt; for(asIt=(aiIt->units_for_attack).begin();asIt!=(aiIt->units_for_attack).end();asIt++) { addIntValueToString(((asIt->assigned)?1:0),tmpbuffer,tblen); addCharToString('$',tmpbuffer,tblen); addIntValueToString(asIt->assigned_unit_id,tmpbuffer,tblen); addCharToString('$',tmpbuffer,tblen); addIntValueToString(asIt->needed_unit_type,tmpbuffer,tblen); addCharToString('$',tmpbuffer,tblen); addIntValueToString(asIt->unit_position,tmpbuffer,tblen); addCharToString('$',tmpbuffer,tblen); addIntValueToString(((asIt->synchronized)?1:0),tmpbuffer,tblen); addCharToString('$',tmpbuffer,tblen); } addCharToString('|',tmpbuffer,tblen); addIntValueToString(((int) (aiIt->attack_state)),tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(aiIt->synchronization_point,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(aiIt->target_point,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(aiIt->target_unit_id,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(((int) (aiIt->attack_target_type)),tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); } addCharToString('@',tmpbuffer,tblen); std::BUILD_DESIRES_AI_INFO_CONTAINER::iterator bdIt; for(bdIt=BuildDesiresInfo.begin();bdIt!=BuildDesiresInfo.end();bdIt++) { addIntValueToString(((bdIt->builder_assigned)?1:0),tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(bdIt->builder_id,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(bdIt->building_type,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(bdIt->build_target_point,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(bdIt->bridge_placement,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(bdIt->building_orientation,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(((bdIt->started_to_build)?1:0),tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(((bdIt->done)?1:0),tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); } addCharToString('@',tmpbuffer,tblen); std::REPAIR_DESIRES_AI_INFO_CONTAINER::iterator rdIt; for(rdIt=RepairDesiresInfo.begin();rdIt!=RepairDesiresInfo.end();rdIt++) { addIntValueToString(((rdIt->builder_assigned)?1:0),tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(rdIt->builder_id,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(rdIt->repair_target_point,tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(((rdIt->started_to_repair)?1:0),tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); addIntValueToString(((rdIt->done)?1:0),tmpbuffer,tblen); addCharToString('|',tmpbuffer,tblen); } addCharToString('@',tmpbuffer,tblen); char* rv=(char*) KMemAlloc((tblen+1)*sizeof(char)); memcpy(rv,tmpbuffer,tblen); rv[tblen]='\0'; return rv; } void CStrategySerialization::addIntValueToString(int added_int,char* buffer,size_t &size) { char tmppartbuffer[TEMP_NUMBER_BUFFER_LENGTH]; snprintf(tmppartbuffer, TEMP_NUMBER_BUFFER_LENGTH, "%d", added_int); size_t tbpartlen=strlen(tmppartbuffer); memcpy(buffer+size,tmppartbuffer,tbpartlen); size+=tbpartlen; } void CStrategySerialization::addCharToString(char added_char,char* buffer,size_t &size) { buffer[size]=added_char; size++; } int CStrategySerialization::readNumWithSeparator(char* data,size_t &size,char separator,size_t bigstrlen) throw(E_8K_AI_Strategy_AIDataReadingError) { char tmppartbuffer[TEMP_NUMBER_BUFFER_LENGTH]; int internal_count=0; bool found_separator=false; while ((!found_separator) && (size='0') && (data[size]<='9')) || (data[size]=='-')) { tmppartbuffer[internal_count]=data[size]; } else THROW(E_8K_AI_Strategy_AIDataReadingError,"Nesmyslny znak na vstupu AI dat."); } internal_count++; size++; } if (found_separator) return atoi(tmppartbuffer); else THROW(E_8K_AI_Strategy_AIDataReadingError,"Preteceni dat na vstupu AI dat."); } void CStrategySerialization::clearInnerStructure() { UnitsInfo.clear(); std::ATTACKS_AI_INFO_CONTAINER::iterator aiIt; for(aiIt=AttacksInfo.begin();aiIt!=AttacksInfo.end();aiIt++) (aiIt->units_for_attack).clear(); AttacksInfo.clear(); BuildDesiresInfo.clear(); RepairDesiresInfo.clear(); //UnitProducingInfo.clear(); } void CStrategySerialization::defaultInnerStructureInit() { clearInnerStructure(); MoneyAttack=0; MoneyDefence=0; MoneyExpansion=0; } TAIUnitInfo* CStrategySerialization::findUnitInfoByWorldID(int unit_world_id) { std::UNIT_AI_INFO_CONTAINER::iterator uiIt; for(uiIt=UnitsInfo.begin();uiIt!=UnitsInfo.end();uiIt++) { if (uiIt->world_id==unit_world_id) return (&(*uiIt)); } return ((TAIUnitInfo*) 0); } } }