給了策劃配置公式的地方,須要將策劃配置的公式文本轉化爲可執行的腳本代碼:
好比:self->mHp*2+target->2mMp*GetHit()+ self_mon->4mDan/1000 ==> self:lf_mHp(0)*2+dst:lf_mMp(2)*GetHit()+ src:lf_mDan(4)/1000正則表達式
意思就是
1 指針變量凡是含有self的都變爲src,target的都替換爲dst
2 調用的屬性前面的係數要提取出來
3 屬性多是多種多樣的,因此提取方法不能寫死。spa
當時時間緊急,對正則表達式也不熟,按照字符串分割的方法實現了。指針
代碼以下:code
1 void TestFormula(std::string& for_text) 2 { 3 using std::string; 4 using std::vector; 5 string::size_type pos = 0; 6 string searchStr = "->"; 7 string replaceStr = "#"; 8 9 if (for_text.find(searchStr) == string::npos) 10 { 11 return; 12 } 13 14 while ( (pos = for_text.find(searchStr, pos)) != string::npos) 15 { 16 if ((for_text.size() >= pos + 2 && for_text[pos + 2] == 'm') || (for_text.size() >= pos + 3 && for_text[pos + 3] == 'm' && for_text[pos + 2] >= '0' && for_text[pos + 2] <= '9')) 17 { 18 for_text.replace(pos, searchStr.size(), replaceStr); 19 } 20 pos++; 21 } 22 23 vector<string> lVector; 24 vector<string> rVector; 25 int lastSplitIdx = 0; 26 string lastText(""); 27 for (string::size_type i = 0; i < for_text.size(); i++) 28 { 29 if (for_text[i] == '+' || for_text[i] == '-' || for_text[i] == '*' || for_text[i] == '/' 30 || for_text[i] == '#' || for_text[i] == '(' || for_text[i] == ')' || for_text[i] == ',') 31 { 32 if (for_text[i] == '#') 33 { 34 lastText = for_text.substr(lastSplitIdx, i - lastSplitIdx); 35 } 36 else 37 { 38 if (lastText.size() > 0) 39 { 40 lVector.push_back(lastText); 41 rVector.push_back(for_text.substr(lastSplitIdx, i - lastSplitIdx)); 42 } 43 lastText = ""; 44 } 45 lastSplitIdx = i + 1; 46 } 47 } 48 if (lastSplitIdx != for_text.size()) 49 { 50 if (lastText.size() > 0) 51 { 52 lVector.push_back(lastText); 53 rVector.push_back(for_text.substr(lastSplitIdx, lastText.size() - lastSplitIdx)); 54 } 55 } 56 57 if (lVector.size() == 0 || rVector.size() == 0 || lVector.size() != rVector.size()) 58 { 59 return; 60 } 61 62 pos = 0; 63 int parseIdx = 0; 64 while ( ( pos = for_text.find(replaceStr, pos)) != string::npos) 65 { 66 string leftStr = lVector.at(parseIdx); 67 string rightStr = rVector.at(parseIdx); 68 string oldStr = leftStr + replaceStr + rightStr; 69 string category = rightStr.substr(0, 1); 70 string ower = leftStr; 71 if (category == "0" || category == "1" || category == "2" || category == "3" || category == "4") 72 { 73 rightStr = rightStr.substr(1, rightStr.size()); 74 } 75 else 76 { 77 category = "0"; 78 } 79 if (leftStr.find("self", 0) != string::npos) 80 { 81 ower = "src"; 82 } 83 else if (leftStr.find("target", 0) != string::npos) 84 { 85 ower = "dst"; 86 } 87 string newStr = ower + ":lf_" + rightStr + "(" + category + ")"; 88 for_text.replace(pos - leftStr.size(), oldStr.size(), newStr); 89 parseIdx++; 90 pos++; 91 } 92 } 93 int main() 94 { 95 std::string text("self->mHp*2+target->2mMp*GetHit()+self_mon->4mDan/1000"); 96 std::cout << text.c_str() << std::endl; 97 TestFormula(text); 98 std::cout<<text.c_str()<<std::endl; 99 100 return 0; 101 }
運行結果:orm
頗費周折有木有~~~,還有不少臨界狀態須要檢查,一不留神可能就踩到坑裏了。blog
索性,看了看正則表達式,發現很是好用。代碼少不少,結果如出一轍。字符串
1 void TestFormulaRegex(std::string& for_text) 2 { 3 using std::string; 4 std::regex pat("([A-Za-z_]+)->([0-4]*)(m[A-Za-z]+)"); 5 string::const_iterator startPos = for_text.begin(); 6 string::const_iterator endPos = for_text.end(); 7 std::smatch mat; 8 while (std::regex_search(startPos, endPos, mat, pat)) 9 { 10 string object(mat[1].first, mat[1].second); 11 string category(mat[2].first, mat[2].second); 12 string attrName(mat[3].first, mat[3].second); 13 if (category.compare("") == 0) 14 { 15 category = "0"; 16 } 17 if (object.find("self", 0) != string::npos) 18 { 19 object = "src"; 20 } 21 else if (object.find("target", 0) != string::npos) 22 { 23 object = "dst"; 24 } 25 string replaceStr(object + ":lf_" + attrName + "(" + category + ")"); 26 for_text.replace(mat[0].first, mat[0].second, replaceStr); 27 startPos = for_text.begin(); 28 endPos = for_text.end(); 29 } 30 }