⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pai21.c

📁 C实现的MUD,对大家基本入门网络游戏很有帮助!
💻 C
字号:
// pai21.c 21点牌// make by 猫部猫(Catyboy)#include <ansi.h>#define MAX_PAI  52inherit ITEM;int has_start;mapping player;			// 玩家IDmapping player_data;// 参数int game_start;			// 1局是否开始?string who_play;		// 正在出牌的人// 牌容器int remain;				// 所剩的牌数量mixed pai_on_desk;		// 可以使用的牌		mapping player_hand;	// 玩家手上的牌// 计数器mapping counter = ([]);string *suit_str = ({  WHT"方块"NOR , HIB"梅花"NOR ,HIR"红桃"NOR , HBWHT BLK"黑桃"NOR});string *suit_char = ({ "D","C","H","S"});string *rank_str = ({ "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" });int pai_number(int pai);int pai_color(int pai);object get_player(string id);int is_playing(object ob);int sizeof_pai(mixed* p);void restore_player_data();int pick_out();int pick_in(string to, int card);string id_to_pai(int id);int do_pass(string arg);int do_nextone(string arg);string view_pai(string which);void finish_21();int auto_order();void msg(object me,object who,string msg){	if(me)		message_vision(msg,me,who);	else		tell_room(environment(this_object()),msg,0);}int c21(mixed* inv){	int i,j,sum,temp;	sum = 0;	temp = 0;	for(i=0;i<inv[0];i++)	{		j = pai_number(inv[i+1]);		if(j == 14)		{			temp ++;			j = 11;		}		else			j = (j>10?10:j);		sum+=j;	}				for(;sum>21&&temp>0;temp--)		sum -= 10;	return sum;}void reset_pai(){	// 重置牌(牌盒,玩家的牌)	int i;	string* key;		for(i=0;i<MAX_PAI;i++)		pai_on_desk[i]=i;	remain=MAX_PAI;	key = keys(player);	for(i=0;i<sizeof(key);i++)		player_hand[key[i]]=allocate(MAX_PAI);	who_play = 0;}int reset_all(){	// 重置整个游戏	int i;	has_start = 0;	if(sizeof(player)!=0)		msg(this_player(),0,"$N重新置牌了。\n");		player = ([]);	player_hand = ([]);	pai_on_desk = allocate(MAX_PAI);	reset_pai();	counter = ([]);	return 1;}void create(){	set_name("21点牌桌", ({"card desk","pai","pai21"}));	set_weight(10000000);	if( clonep() )		set_default_object(__FILE__);	else {		set("long", "一张桌子,上面放着一些牌,使用方法请使用(helppai)命令。\n");		set("unit", "张");		set("value", 1);        set("no_get",1);	}	player = ([]);	reset_all();}void init(){	// 帮助	add_action("do_help", "helppai");	// 基本指令    add_action("do_reset", "reset");		// 重置整个游戏	add_action("do_restart", "restart");	// 重新游戏	add_action("do_join", "join");			// 加入牌局	add_action("do_start", "start");		// 开始游戏		add_action("do_xipai", "xipai");		// 洗牌	add_action("do_view", "view");			// 看牌			add_action("do_nextone", "next");		// 催促下一个	add_action("do_pass", "pass");			// 不要牌		// 扩展指令	add_action("do_chupai", "play");		// 玩	add_action("do_daopai", "daopai");		// 倒牌	// 计数器	add_action("do_showc", "showc");		// 显示计数器}int do_reset(string arg){	if(arg == "counter")	{		if(!is_playing(this_player()))			return notify_fail("你都不玩牌啊!\n");		msg(this_player(),0,"$N复位计数器了。\n");		counter = ([]);		return 1;	}	if(!this_object()->id(arg))		return 0;			return reset_all();}int do_restart(string arg){	int i;	string* key;	if(!is_playing(this_player()))		return notify_fail("你都不玩,开始什么啊!\n");	if(!has_start)		return notify_fail("游戏还没有开始。\n");	if(sizeof(player)!=0)		msg(this_player(),0,"$N开始新的一轮牌局了。\n\n");	reset_pai();	restore_player_data();	msg(0,0,"在开始游戏之前(play),请各位洗牌(xipai)。\n");	return 1;}int do_join(string arg){	object me;	me = this_player();	if(has_start)		return notify_fail("牌局已经开始,不能加入了。\n");	if(is_playing(me))		return notify_fail("你已经参加了。\n");		// add player	player[me->query("id")]="yes";	player_hand[me->query("id")]=allocate(MAX_PAI);	msg(me,0,"$N加入牌局了。\n");	return 1;}int do_start(string arg){	if(!is_playing(this_player()))		return notify_fail("你都不玩,开始什么啊!\n");		if(has_start)		return notify_fail("牌局已经开始了。\n");	has_start = 1;	msg(this_player(),0,"$N开始了牌局。\n\n");	auto_order();	msg(0,0,"在开始游戏之前(play),请各位洗牌(xipai)。\n");	return 1;}int do_xipai(string arg){	int i,sum,rand,which,temp;	mixed* pai;	if(!is_playing(this_player()))		return notify_fail("你都不玩,洗什么牌啊!\n");		pai = pai_on_desk;	sum = remain;	rand = sum;		for(i=0;i<sum;i++)	{		which = random(rand);		temp = pai[rand-1];		pai[rand-1] = pai[which];		pai[which] = temp;		rand --;	}	msg(this_player(),0,"$N洗了洗桌面的牌。\n");	return 1;}int do_chupai(string arg){	int i,sum,j,done,temp,id;	mixed* inv;	string cmd;	object ob;			if(!is_playing(this_player()))		return notify_fail("你都不玩啊!\n");	if(who_play==0)		who_play = this_player()->query("id");	if(who_play!=this_player()->query("id"))		return notify_fail("还没有轮到到你啊。\n");	done = 0;			if((id = pick_out())==-1)		return 0;	if(!pick_in(this_player()->query("id"),id))		return 0;	msg(this_player(),0,"$N摸了一张"+id_to_pai(id)+"。\n");	done = 1;	// check is over 21,if over pass	inv = player_hand[this_player()->query("id")];	sum = c21(inv);				msg(this_player(),0,"$N手上有"HIY+sum+"点"NOR"了。\n");	if(sum>21)	{		do_pass(HIR"爆了!!!"NOR"\n");		return 1;	}		ob = get_player(player[who_play]);	if(ob)	{		who_play = player[who_play];		do_nextone("");	}	return 1;}int do_view(string arg){	mixed* pai;	string hand_name;	if(arg==""||arg==0)		arg = this_player()->query("id");	else		hand_name = arg;		pai = player_hand[arg];	if(pai==0)		return notify_fail("牌局没有这个玩家。\n");		if(hand_name)		write(hand_name+":");	write(view_pai(arg)+"\n");	return 1;}string extra_long(){	object me,who;	string r,key;	mixed *idx;	int i;	me = this_player();	idx = keys(player);		r = sprintf("牌盒里面有%d张牌\n",remain);		if(sizeof(player)>0)	{		r+="******************************************\n";		for(i=0;i<sizeof(idx);i++)		{			key = idx[i];			who = get_player(key);			if(who)				r = r + key + ":"+view_pai(key)+"\n";		}		r = r + "******************************************\n";	}	return r;}int pick_out(){	int s,id;			if(remain>0)	{		remain--;		s = remain;		id = pai_on_desk[s];		pai_on_desk[s]=-1;		return id;	}	else	{		msg(0,0,"没有牌了");		return -1;	}}int pick_in(string to, int card){	int s;	mixed* pai;			pai = player_hand[to];	s = pai[0];	s++;	pai[s]=card;	pai[0]++;	return 1;}object get_player(string id){	if(stringp(player[id]))		return find_player(id);	return 0;}int is_playing(object ob){	int i;	string id;	id = ob->query("id");	if(stringp(player[id]))		return 1;	return 0;}int sizeof_pai(mixed* p){		return p==0?0:p[0];}string view_pai(string which){	mixed* pai;	int show_all,i,j;	string s,p;	pai = player_hand[which];	if(pai==0)		return 0; 	if(sizeof_pai(pai)==0)		return "没有牌";	s = "";	for(i=0;i<pai[0];i++)	{		p = id_to_pai(pai[i+1]);		s+= p +" ";	}	return sprintf("%s:%d点",s,c21(pai));}int do_nextone(string arg){	object ob;	string id;	if(!is_playing(this_player()))		return notify_fail("你都不玩牌啊!\n");	if(who_play==0)		return notify_fail("现在是谁出牌啊?\n");	id = who_play;	ob = get_player(id);		if(ob==0)		return msg(0,0,"有玩家缺场了,请重新开始游戏(reset pai)。\n");	if(this_player()->query("id")!=id)		msg(this_player(),ob,"$N对$n说道:到你了。\n");	else		msg(this_player(),0,"对自己说道:到我啦!\n");	return 1;}int do_pass(string arg){	string old,str;	string* key;	mixed* inv;	int i,temp;	if(!is_playing(this_player()))		return notify_fail("你都不玩牌啊!\n");	if(who_play!=this_player()->query("id"))		return notify_fail("还没有到你啊!\n");	if(!arg)		arg = "PASS!!";	msg(this_player(),0,"$N说道:"+arg+"\n");	old = who_play;	who_play = player[who_play];	key = keys(player);	for(i=0;i<sizeof(key);i++)		if(player[key[i]]==old)			player[key[i]] = player[old];	player[old] = "";					if(player[who_play] == "")	{		msg(0,0,"大家都不要了。\n");		finish_21();		return 1;	}	do_nextone("");	return 1;}string id_to_pai(int id){	int i,j;	if(id <0)		return HIR"???"NOR;	if(id == 52)		return HIY"小鬼"NOR + "JS";	if(id>=53)		return HIY"大鬼"NOR + "JB";	i = id/13;	j = id-i*13;	return suit_str[i] + suit_char[i] + rank_str[j];}int pai_to_id(string id){	int ic1=-1,ic2=-1;	string c1,c2;	c1 = id[0..0];	c2 = id[1..sizeof(id)-1];	if(c1=="J")return c2=="S"?52:53;	if(c1==suit_char[0]) ic1=0;	if(c1==suit_char[1]) ic1=1;	if(c1==suit_char[2]) ic1=2;	if(c1==suit_char[3]) ic1=3;	if(ic1==-1)return -1;	if(sscanf(c2,"%d",ic2)!=1)	{		if(c2 == "J") ic2 = 11;		if(c2 == "Q") ic2 = 12;		if(c2 == "K") ic2 = 13;		if(c2 == "A") ic2 = 14;		if(ic2==-1) return -2;	}	ic2 -=2;	return ic1*13+ic2;}int auto_order(){	int i;	string* key;	string who,start_one;	key = keys(player);	start_one = key[0];	who = "";	for(i=0;i<sizeof(key);i++)	{		if(get_player(key[i]))		{			if(who =="")				who = key[i];			else			{				player[who] = key[i];				who = key[i];			}		}	}	player[who] = start_one;	return 1;}int do_showc(string arg){	string r;	mixed *idx;	int i;	idx = keys(counter);		r = "计数表(Scoreboard)\n-----------------\nID        分数\n-----------------\n";	for(i=0;i<sizeof(idx);i++)		r = sprintf("%s%-14s%10d\n", r,idx[i],counter[idx[i]]);	r += "-----------------\n";	msg(0,0,r);	return 1;}void press_counter(string id,int num){	counter[id]=counter[id]+num;}int do_daopai(string arg){	int i,id;		if(!is_playing(this_player()))		return notify_fail("你都不玩,搞什么啊!\n");	if(!has_start)		return notify_fail("游戏还没有开始。\n");	if(remain>0)	{		id = pai_on_desk[0];		for(i=1;i<remain;i++)			pai_on_desk[i-1] = pai_on_desk[i];		pai_on_desk[remain-1] = id;		msg(this_player(),0,"$N倒了一下牌。\n");		return 1;	}	else		return notify_fail("没有牌了。\n");}int pai_number(int pai){	if(pai==52)		return 15;	if(pai==53)		return 16;	return pai-pai/13*13+2;}int pai_color(int pai){	if(pai>=52)		return 5;	return pai/13+1;}void save_player_data(){	string* inv;	int i;	inv = keys(player);	player_data = ([]);	for(i=0;i<sizeof(inv);i++)		player_data[inv[i]] = player[inv[i]];}void restore_player_data(){	int i;	string* key;	if(!player_data)		return;	key = keys(player_data);	for(i=0;i<sizeof(key);i++)		player[key[i]] = player_data[key[i]];}int sort_21(string str1, string str2){	int c1,c2;	string temp;	sscanf(str1,"%s:%d",temp,c1);	sscanf(str2,"%s:%d",temp,c2);		if(c1==c2)		return 0;	if(c1>21&&c2>21)		return (c1<c2)?-1:1;	if(c1>21)		c1 = -1;	if(c2>21)		c2 = -1;	return (c1>c2)?-1:1;}void finish_21(){	string* key;	mixed* inv2;	mixed* inv;	string str,r,id;	int i,maxn,fen,k,lpoint;	key = keys(player);	inv2 = allocate(sizeof(player));	for(i=0;i<sizeof(key);i++)	{		str = key[i];		inv2[i] = str + ":" + c21(player_hand[str]);	}			inv = sort_array(inv2,"sort_21",this_object());		lpoint = -1;	r = "结果\n-----------------\nID        点数       得分\n-----------------\n";	for(i=0;i<sizeof(inv);i++)	{		sscanf(inv[i],"%s:%d",id,k);		if(k != lpoint)		{			fen = sizeof(inv) - i - 1;			lpoint = k;		}		if(i==0)maxn=k;		if(k==maxn)r+=HIY;		if(k>21)		{			r+=HIR;			fen = 0;		}		r = sprintf("%s%-14s%5d%12d\n", r,id,k,fen);		r+=NOR;		press_counter(id,fen);	}	r += "-----------------\n\n";	msg(0,0,r);		reset_pai();	restore_player_data();	msg(0,0,"请各位重新洗牌(xipai)开始新的一局。\n");}int do_help(string arg){	this_player()->start_more( @HELP玩21点牌桌使用方法:——[开始游戏]———————————————帮助命令:helppai加入命令:join     加入游戏开始命令:start     开始以后不能再加入重置命令:reset pai   结束游戏——[游戏命令]———————————————重新游戏:restart  摸牌:play     进行游戏不再要牌: pass——[其它命令]———————————————洗牌命令:xipai看牌命令:view [玩家ID] 观察玩家手上的牌催促命令:next     催促正在出牌的人——[计数牌使用]——————————————显示: showc重置: reset counter——[游戏规则]———————————————游戏开始以后,每人轮流摸牌直到不摸为止。最后根据每人手上的点数决定胜负。点数 > 21 为输,点数<21的时候点数大者胜。J,Q,k为10点,A可以为1点或者为11点。——————————————————————			make by 猫部猫(Catyboy) v1.0HELP	);        return 1;}mixed t(){	return pai_on_desk;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -