codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
/* * RPGの戦闘風ネタコード:詳細は以下のソース by ID:7ckg3apKP */ #include <vector> #include <map> #include <string> #include <algorithm> #include <math.h> #define _1D6_ (rand()%6+1) #define _nD6_(n) (rand()%(n*6)+n) // コマンド ---------------------------- typedef enum { COM_NONE, COM_ATTACK, COM_DEFFENCE, COM_USE_ITEM, COM_SPECIAL } COMMAND; /* ---- ここから ---- */ // 結果 ---------------------------- typedef enum { RES_NONE, RES_WIN, RES_LOOSE } RESULT; // アイテム ---------------------------- typedef struct { int atk, def; std::string name; } ITEM; // PC/NPC ---------------------------- typedef struct _tChr { int atk, def, agi, hp, maxhp, cdef; std::string name; std::vector<ITEM> inv; _tChr(int a, int d, int g, int h) : atk(a),def(d),agi(g),hp(h),maxhp(h),cdef(d){} } CHARACTER; typedef struct { CHARACTER *ch; COMMAND com; int agi; } REQ; // 戦闘処理 ---------------------------- class FightProc { private: typedef void (*Proc)(CHARACTER *c1, CHARACTER *c2); std::map<COMMAND, Proc> dic; std::vector<REQ> vec; public: void setDic(COMMAND com, Proc proc) { dic[com] = proc; } void addCommand(CHARACTER *c, COMMAND com); RESULT doit(CHARACTER *c1, CHARACTER *c2); }; bool sortByAgi(const REQ &r1, const REQ &r2) { return r1.agi < r2.agi; } void FightProc::addCommand(CHARACTER *c, COMMAND com) { REQ r = {c, com, c->agi + _1D6_ }; vec.push_back(r); } RESULT FightProc::doit(CHARACTER *c1, CHARACTER *c2) { std::sort(vec.begin(), vec.end(), sortByAgi); RESULT res = RES_NONE; std::vector<REQ>::iterator it = vec.begin(); for(;it != vec.end() && res == RES_NONE; ++it) { Proc p = dic[(*it).com]; if((*it).ch == c1) { p(c1, c2); } else if((*it).ch == c2) { p(c2, c1); } else { // nop } if(c2->hp<1) res = RES_WIN; else if(c1->hp<1) res = RES_LOOSE; } vec.clear(); return res; } /* ---- ここまではスルーで。以降拡張 ---- */ void onAttack(CHARACTER *c1, CHARACTER *c2) { c1->def = c1->cdef; int d = max(c1->atk + _1D6_ - c2->def, 0); printf("%s attacks to %s, %d damages!\n", c1->name.c_str(), c2->name.c_str(), d); c2->hp = max(c2->hp - d, 0); } void onDefence(CHARACTER *c1, CHARACTER *c2) { c1->def = int(c1->cdef*1.5); printf("%s is defending.\n", c1->name.c_str()); } void onUseItem(CHARACTER *c1, CHARACTER *c2) { printf("under construction.\n"); } void onSpecial(CHARACTER *c1, CHARACTER *c2) { c1->def = c1->cdef; if(c1->agi + c1->hp > _nD6_(6)) { int d = max(c1->atk + _nD6_(4) - c2->def, 0); printf("%s special attack! : %s %d damages!\n", c1->name.c_str(), c2->name.c_str(), d); c2->hp = max(c2->hp - d, 0); } else { printf("%s special attack! : miss!\n", c1->name.c_str()); } } // ---------------------------- FightProc fp; void init() { srand(time(0)); // ★コマンド辞書の追加: // 追加したCOMMAND のプロシジャは以下のように追加 // プロシジャは、void 名称(CHARACTER *c1, CHARACTER *c2) の形を取り、 // 第1引数が「それをしている」とする。第2引数は「されている」 // fp.setDic(COM_ATTACK, onAttack); fp.setDic(COM_DEFFENCE, onDefence); fp.setDic(COM_USE_ITEM, onUseItem); fp.setDic(COM_SPECIAL, onSpecial); } void hr() { printf("**-----------------------------------------\n"); } void showStatus(CHARACTER &c) { printf("NAME:%s, ATK:%d, DEF:%d, AGI:%d, HP:%d/%d\n", c.name.c_str(), c.atk, c.def, c.agi, c.hp, c.maxhp); } int main() { init(); //atk, def, agi, hp CHARACTER player(_1D6_+6, _1D6_+6, _1D6_+6, _1D6_*2+12); // 多分ヒューマン CHARACTER monster(_1D6_+2, _1D6_+2, _1D6_+4, _1D6_*2+8); // 多分ゴブリン player.name = std::string("Takashi"); monster.name = std::string("Goblin"); hr(); showStatus(player); showStatus(monster); hr(); fp.addCommand(&player, COM_ATTACK); fp.addCommand(&player, COM_DEFFENCE); fp.addCommand(&player, COM_SPECIAL); fp.addCommand(&player, COM_ATTACK); for(int i=0; i<4; ++i) { fp.addCommand(&monster, COMMAND(rand()%2+1)); } switch(fp.doit(&player, &monster)) { case RES_WIN: printf("** you win **\n"); break; case RES_LOOSE: printf("** you loose **\n"); break; default: printf("next command ->\n"); break; } hr(); showStatus(player); showStatus(monster); hr(); return 0; }
Private
[
?
]
Run code
Submit