[ create a new paste ] login | about

Link: http://codepad.org/pRHu1OGs    [ raw code | output | fork ]

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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
**-----------------------------------------
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
**-----------------------------------------


Create a new paste based on this one


Comments: