ひとまず完成.
#define Sint8 signed char #define Uint8 unsigned char #include <iostream> #include <vector> #include <stack> //#include <set> using namespace std; enum { ATTR_NORMAL, ATTR_FIRE, ATTR_WATER, ATTR_THUNDER, ATTR_GLASS, ATTR_ICE, ATTR_FIGHT, ATTR_POISON, ATTR_GROUND, ATTR_FLY, ATTR_PSY, ATTR_INSECT, ATTR_ROCK, ATTR_GHOST, ATTR_DRAGON, ATTR_EVIL, ATTR_STEEL, ATTR_NUM }; static const char* ATTR_NAME[] = {//上のやつをマクロで処理 "ATTR_NORMAL", "ATTR_FIRE", "ATTR_WATER", "ATTR_THUNDER", "ATTR_GLASS", "ATTR_ICE", "ATTR_FIGHT", "ATTR_POISON", "ATTR_GROUND", "ATTR_FLY", "ATTR_PSY", "ATTR_INSECT", "ATTR_ROCK", "ATTR_GHOST", "ATTR_DRAGON", "ATTR_EVIL", "ATTR_STEEL", }; enum { EFF_XXXX,//× EFF_DULL,//△ EFF_GOOD,// EFF_COOL,//◎ EFF_NUM }; static const Sint8 ATTR_PAIR[ATTR_NUM][ATTR_NUM] = {//マクロでやったほうが良かっただろ。。。常識的に考えて。。。 //ATTR_NORMAL, {EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_DULL, EFF_XXXX, EFF_GOOD, EFF_GOOD, EFF_DULL}, //ATTR_FIRE, {EFF_GOOD, EFF_DULL, EFF_DULL, EFF_GOOD, EFF_COOL, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_DULL, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_COOL}, //ATTR_WATER, {EFF_GOOD, EFF_COOL, EFF_DULL, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_GOOD}, //ATTR_THUNDER, {EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_DULL, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_XXXX, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_GOOD}, //ATTR_GLASS, {EFF_GOOD, EFF_DULL, EFF_COOL, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_DULL, EFF_COOL, EFF_DULL, EFF_GOOD, EFF_DULL, EFF_COOL, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_DULL}, //ATTR_ICE, {EFF_GOOD, EFF_DULL, EFF_DULL, EFF_GOOD, EFF_COOL, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_DULL}, //ATTR_FIGHT, {EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_DULL, EFF_DULL, EFF_DULL, EFF_COOL, EFF_XXXX, EFF_GOOD, EFF_COOL, EFF_COOL}, //ATTR_POISON, {EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_DULL, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_DULL, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_XXXX}, //ATTR_GROUND, {EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_COOL, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_XXXX, EFF_GOOD, EFF_DULL, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL}, //ATTR_FLY, {EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_DULL, EFF_COOL, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_DULL}, //ATTR_PSY, {EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_XXXX, EFF_DULL}, //ATTR_INSECT, {EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_DULL, EFF_DULL, EFF_GOOD, EFF_DULL, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_COOL, EFF_DULL}, //ATTR_ROCK, {EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_DULL, EFF_GOOD, EFF_DULL, EFF_COOL, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_DULL}, //ATTR_GHOST, {EFF_XXXX, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_DULL, EFF_DULL}, //ATTR_DRAGON, {EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_DULL}, //ATTR_EVIL, {EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_DULL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_DULL, EFF_DULL}, //ATTR_STEEL, {EFF_GOOD, EFF_DULL, EFF_DULL, EFF_DULL, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_COOL, EFF_GOOD, EFF_GOOD, EFF_GOOD, EFF_DULL}, }; //階層のループ化をどうするか。再帰関数で上手くいくか? //enum{LOOP_COUNT = 2}; /* for(Uint8 l = 0; l < LOOP_COUNT; l++) { for(Uint8 atk = 0; atk < ATTR_NUM; atk++) { Uint8 GoodCount_local = 0; for(Uint8 def = 0; def < ATTR_NUM; def++) { if(GoodAttr[def] >= 0) continue; if(AttrPair[atk][def] >= EFF_GOOD){ ++GoodCount_local; GoodAttr[i] = } } } //*/ /* //1ループだととこうなる for(Uint8 atk = 0; atk < ATTR_NUM; atk++) { for(Uint8 def = 0; def < ATTR_NUM; def++) {//そういやSTL使っていいんじゃねえか。忘れてた if(AttrPair[atk][def] < EFF_GOOD) continue; ++GoodCount_local; GoodAttr_local.add(ATTR_NAME[def]); } if(GoodCount_local >== GoodCount){ if(GoodCount_local > GoodCount){ GoodCount = GoodCount_local; BestAttrName.clear(); GoodAttr.clear(); } BestAttrName.add(ATTR_NAME[atk]); GoodAttr.add(GoodAttr_local); } } //*/ /* //2ループだととこうなる for(Uint8 atk = 0; atk < ATTR_NUM; atk++) { for(Uint8 def = 0; def < ATTR_NUM; def++) {// if(AttrPair[atk][def] < EFF_GOOD) continue; ++GoodCount_local; GoodAttr_local.add(ATTR_NAME[def]); } //再帰でいけそうな気がしてきた。 for(Uint8 atk2 = 0; atk2 < ATTR_NUM; atk2++) { Vector<string> GoodAttr_local_local = GoodAttr_local;//stringは後で[index]すればよいから<Uint8>か? Uint8 GoodCount_local_local = GoodCount_local; for(Uint8 def = 0; def < ATTR_NUM; def++) {// if(AttrPair[atk2][def] < EFF_GOOD) continue; if(GoodAttr_local_local.exist(ATTR_NAME[def])) continue; ++GoodCount_local_local; GoodAttr_local_local.add(ATTR_NAME[def]); } if(GoodCount_local_local >== GoodCount){ if(GoodCount_local_local > GoodCount){ GoodCount = GoodCount_local_local; BestAttrName.clear(); GoodAttr.clear(); } BestAttrName.add(Pair(ATTR_NAME[atk], ATTR_NAME[atk2]));//ここの要素をリストで GoodAttr.add(GoodAttr_local_local); } } } //*/ //こうだな //PokemonWeaknessChecker().Check(2);で行けるんだっけ? class PokemonWeaknessChecker {//弱点はweaknessで良いのか? protected: //最も多くの種類の弱点をつける属性の組(COMBS)と、実際の弱点の種類(Attrs) vector<vector<Uint8> > m_Combs; vector<vector<Uint8> > m_Attrs; //再帰で受け渡すパラメータをメンバ化 stack<vector<Uint8> > m_CombsStack; stack<vector<Uint8> > m_AttrsStack; Sint8 m_DepthMax;//まあ、一応sizeと比較するのでSintで public: PokemonWeaknessChecker() {//STLって何か初期化しなきゃいけなかったっけ? m_DepthMax = 0;//一応初期化 vector<Uint8> empty; m_CombsStack.push(empty); m_AttrsStack.push(empty); } void Check(Sint8 depth) { m_DepthMax = depth;//引数で渡すのが面倒なのでメンバで持つ Search(); PrintResult(); } void Search() { Uint8 NextAttack = 0; if(m_CombsStack.top().size() > 0) NextAttack = m_CombsStack.top()[m_CombsStack.top().size()-1] + 1; for(Uint8 atk = NextAttack; atk < ATTR_NUM; atk++) { //atkの組み合わせ。 vector<Uint8> Comb = m_CombsStack.top();//copy Comb.push_back(atk); //上のatkの組み合わせにおいて有効なdefはどれかを表す vector<Uint8> Attr = m_AttrsStack.top();//copy for(Uint8 def = 0; def < ATTR_NUM; def++) {// if(ATTR_PAIR[atk][def] < EFF_COOL) continue; // if(Attr.exist(def)) continue; Sint8 d; for(d = 0; d < Attr.size(); d++) if(Attr[d] == def) break; if(d < Attr.size()) continue; Attr.push_back(def); } if(m_CombsStack.size() >= m_DepthMax){ //最下層まで来たので以前の結果と比べて、優れていれば追加 if(m_Attrs.size() == 0 || m_Attrs[0].size() <= Attr.size()){ if(m_Attrs.size() != 0 && m_Attrs[0].size() < Attr.size()){ m_Combs.clear(); m_Attrs.clear(); } m_Combs.push_back(Comb); m_Attrs.push_back(Attr); } }else{ //最下層まで再帰で行く m_CombsStack.push(Comb); m_AttrsStack.push(Attr); Search(); m_CombsStack.pop(); m_AttrsStack.pop(); } } } void PrintResult() { for(Sint8 i = 0; i < m_Combs.size(); i++){ cout << "COMBO " << (int)i << endl; cout << "atk:"; for(Sint8 j = 0; j < m_Combs[i].size(); j++){ cout << ATTR_NAME[m_Combs[i][j]]; if(j < m_Combs[i].size()-1) cout << ", "; } cout << endl; cout << "def:"; for(Sint8 j = 0; j < m_Attrs[i].size(); j++){ cout << ATTR_NAME[m_Attrs[i][j]]; if(j < m_Attrs[i].size()-1) cout << ", "; } cout << endl; cout << endl; } } }; int main(int argc, char *argv[]) { PokemonWeaknessChecker().Check(4); }
pre表記だと]が上手く表示できてなかった.
シンタックス・ハイライトだと上手くいくけど目が痛いなこりゃ.また後でいじってみる.
→スーパーpre記法で良い様子
////////////////////
トップに置く理由もないのでこちらに移動.
弱点を網羅する属性の組み合わせを探すプログラム.
ちなみに結果は以下の通り.
4つの組み合わせ
・氷,闘,地,飛
・氷,闘,地,霊
・氷,闘,地,悪
3つの組み合わせ
・氷,闘,地
2つの組み合わせ
・氷,闘
・氷,地
1つのみ
・闘
・地
参考資料ぐらいにはなるか.実戦ではなくてCPU相手に限る感じだが.