C++,
pasted
on Nov 14:
|
/*
* 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;
}
|
Output:
|
**-----------------------------------------
NAME:Takashi, ATK:8, DEF:7, AGI:8, HP:16/16
NAME:Goblin, ATK:8, DEF:6, AGI:5, HP:20/20
**-----------------------------------------
Goblin is defending.
Takashi attacks to Goblin, 3 damages!
Goblin attacks to Takashi, 7 damages!
Goblin attacks to Takashi, 2 damages!
Goblin is defending.
Takashi special attack! : miss!
Takashi attacks to Goblin, 1 damages!
Takashi is defending.
next command ->
**-----------------------------------------
NAME:Takashi, ATK:8, DEF:10, AGI:8, HP:7/16
NAME:Goblin, ATK:8, DEF:9, AGI:5, HP:16/20
**-----------------------------------------
|
|