pigroom.1

来自「C实现的MUD,对大家基本入门网络游戏很有帮助!」· 1 代码 · 共 515 行

1
515
字号
// pigroom.c 拱猪房#include <pig.h>inherit F_CLEAN_UP;inherit ROOM;int *specials = ({ 10, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 35, 47 });string 	*seat = ({ "north", "west", "south", "east" });mapping chinese_seat = ([ 	"north": "北边",	"west" : "西边",	"south": "南边",	"east" : "东边",]);int pig_stage;int round_no, roundcard_count;string *round_order = allocate(4);int bid_flag;string bidcard_str;object server;mapping	pl = allocate_mapping(4), 	cards = allocate_mapping(4),	card_count = allocate_mapping(4),	roundcards = allocate_mapping(4),	picks = allocate_mapping(4),	pick_count = allocate_mapping(4),	passed = allocate_mapping(4),	current_pig = allocate_mapping(4),	hscore = allocate_mapping(4),	tscore = allocate_mapping(4);	string	dealer;int	*allow_playbid = allocate(4);int 	*oldcards = allocate(52), 	*newcards = allocate(52);void pig_init();void bid_init();void after_bid();void round_init(string w);void after_round();void play_init();void after_play();void after_round();void after_hand();string refresh_str(string dir);string picks_str();string table_str(string dir);string score_str();void reset()	// set this room to no_reset{}void pig_init(){	int i;	pig_stage = PIG_INITTING;	for (i = 0; i < 4; i++) {		tscore[seat[i]] = hscore[seat[i]] = 0;		cards[seat[i]] = allocate(13);		picks[seat[i]] = allocate(16);	}	for (i = 0; i < 52; i++)		oldcards[i] = i;}void bid_init(){	int i;	pig_stage = PIG_BIDDING;	bidcard_str = "";	bid_flag = 0;	for (i = 0; i < 4; i++) {		allow_playbid[i] = 1;		passed[seat[i]] = 0;	}}void play_init(){	int i, j;	pig_stage = PIG_PLAYING;	round_no = 1;	for (i = 0; i < 4; i++) {		pick_count[seat[i]] = 0;		card_count[seat[i]] = 13;		for (j = 0; j < 16; j++)			picks[seat[i]][j] = 53;	}	round_init(dealer);}void round_init(string rw){	int i;	for (i = 0; i < 4; i++) 		roundcards[seat[i]] = -1;	roundcard_count = 0;	round_order = PIG_D->order_turn(rw);	if (pig_stage == PIG_PLAYING)		tell_object(pl[rw], refresh_str(rw));}	void init(){	add_action("do_sit", "sit");	add_action("do_leave", "leave");	add_action("do_deal", "deal");	add_action("do_bid", "bid");	add_action("do_bid", "sell");	add_action("do_pass", "pass");	add_action("do_play", "play");	add_action("do_refresh", "refresh");}string round_str()	// what happened in this round ?{	string r, cs; 	int i;	if (!objectp(pl[cs = round_order[roundcard_count]]))		r = sprintf("现在轮到%s出:", chinese_seat[cs]);	else		r = sprintf("现在轮到%s出:", pl[cs]->query("name"));	for (i = 0; i < roundcard_count; i++)		r = sprintf("%s%s,", r, PIG_D->card_str(roundcards[round_order[i]]));	return r + "\n";}string picks_str(){	int i;        string r;         for (i = 0; i < 4; i++) {		if (objectp(pl[seat[i]]))                	r = pl[seat[i]]->query("name");		else 			r = chinese_seat[seat[i]];                if (pick_count[seat[i]] > 0) {                        r += "捡了下面这些牌:\n";                        r += PIG_D->refresh(picks[seat[i]], 0, pick_count[seat[i]] - 1);                }                else                        r = "";        }	return "捡牌情况:\n" + r;}string refresh_str(string dir){	if (dir != "north" && dir != "west" && dir != "south" && dir != "east")		return PIG_D->refresh(cards[dir], 0, card_count[dir] - 1);	return "";}	string table_str(string dir)	// what's going on in table ?{	int i;	mapping rseat = ([]);	string r, z = "";	if (dir != "north" && dir != "west" && dir != "south" && dir != "east")		dir == "north";	if (pig_stage == PIG_PLAYING) { // if in playing mode		if (dir != "north" && dir != "west" && dir != "south" 			&& dir != "east")			rseat = PIG_D->order_turn("north");		else			rseat = PIG_D->order_turn(dir);		r = "桌上面正在激烈的拱着!!\n";		r = sprintf("%s现在是第%s轮\n", r, chinese_number(round_no));		r += "卖了的牌:" + bidcard_str + "\n\n";		r = sprintf("%s%24s(%s)\n", r, "", pl[rseat[2]]->query("name"));	// writes north name		r = sprintf("%s%26s%s\n", r, "", 			PIG_D->card_str(roundcards[rseat[2]]));		r = sprintf("%s%4s%16s%6s%6s%6s%s\n", r, "", "(" + 			pl[rseat[3]]->query("name") + ")", 			PIG_D->card_str(roundcards[rseat[3]]), "", 			PIG_D->card_str(roundcards[rseat[1]]), "(" +			pl[rseat[1]]->query("name") + ")");		r = sprintf("%s%26s%s\n", r, "",			PIG_D->card_str(roundcards[rseat[0]]));		r = sprintf("%s%24s(%s)\n", r, "", pl[rseat[0]]->query("name"));		r += picks_str();	}	else {	        r = "这是一张专门用于拱猪的四方桌。\n\n";		for (i = 0; i < 4; i++) 			if (objectp(pl[seat[i]])) {				if (pl[seat[i]] == server) z = "@"; else z = "";				r = sprintf("%s%s的椅子上坐的是:%s(%s)%s。\n", r,				chinese_seat[seat[i]], pl[seat[i]]->query("name"),				pl[seat[i]]->query("id"), z);			}			else				r = sprintf("%s%4s的椅子是空的。如果你想玩,可以用 sit %-5s 坐上去。\n",				r, chinese_seat[seat[i]], seat[i]);	}	return r;}string scoreboard_str(){	int i;	string r;	r = "拱猪成绩表(Scoreboard)\n--------------\n姓名     盘分   总分\n--------------\n";	for (i = 0; i < 4; i++)		if (objectp(pl[seat[i]]))			r = sprintf("%s%-14s%-10d%-10d\n", r,			(string)pl[seat[i]]->query("name"),			(int)hscore[seat[i]], (int)tscore[seat[i]]);	return r;}void score_reset(){	int i;	for (i = 0; i < 4; i++)		tscore[seat[i]] = 0;}int do_sit(string arg){	object me = this_player();	if (!arg || (arg != "north" && arg != "west" && arg != "south" && arg != "east"))		return notify_fail("你想坐在哪里?\n");	map_delete(pl, (string)me->query_temp("pigging_seat"));			if (!objectp(pl[arg])) {		if (!sizeof(pl)) {			pig_init();			server = me;			write("你现在是桌长。\n");			round_order = PIG_D->order_turn(dealer = arg);		}		pl[arg] = me;		me->set_temp("pigging_seat", arg);		message_vision("$N坐上了" + chinese_seat[arg] + "的位子。\n", me);		if (sizeof(pl) == 3)			tell_room(this_object(), "现在是三缺一,你们只再需要一个玩家就可以开拱了。\n");		if (sizeof(pl) == 4)			tell_room(this_object(), "好,可以发牌了。桌长请用 deal 命令。\n");		pig_stage = PIG_DEALING;		return 1;	}	else		return notify_fail("这个位子已经有人了。\n");}int do_leave(string arg){	int i;	object me = this_player();	if (!me->query_temp("pigging_seat", arg))		return notify_fail("你现在没有在拱猪。\n");	else if (server == me) {		message_vision("桌长$N不想再拱下去了。\n", me);		server = 0;		for (i = 0; i < 4; i++) 			if (objectp(pl[seat[i]])) {				message_vision("$N站了起来。\n", pl[seat[i]]);				pl[seat[i]]->delete_temp("pigging_seat");				map_delete(pl, seat[i]);			}		pig_stage = PIG_INITTING;		return 1;	}	else {		map_delete(pl, (string)me->query_temp("pigging_seat"));		me->delete_temp("pigging_seat");		message_vision("$N不想再拱了,站了起来。\n", me);		return 1;	}}void do_assign_cards()	// assign cards to players{	int i, j, k = 0;	for (i = 0; i < 13; i++)		for (j = 0; j < 4; j++) 			cards[seat[j]][i] = newcards[k++];	for (i = 0; i < 4; i++) {		cards[seat[i]] = sort_array(cards[seat[i]], 1);		tell_object(pl[seat[i]], PIG_D->refresh(cards[seat[i]], 0, 12));		card_count[seat[i]] = 13;	}}int do_deal(string arg){	int i, j, k;	object me = this_player();	if (me != server)		return notify_fail("你不是桌长!\n");	if (pig_stage != PIG_DEALING)		return notify_fail("现在不能发牌。\n");	PIG_D->shuffle(oldcards, newcards, 2);	for (i = 0; i < 13; i++)		for (j = 0; j < 4; j++) 			cards[seat[j]][i] = newcards[k++];	for (i = 0; i < 4; i++) {		cards[seat[i]] = sort_array(cards[seat[i]], 1);		tell_object(pl[seat[i]], PIG_D->refresh(cards[seat[i]], 0, 12));		card_count[seat[i]] = 13;        }	PIG_D->pig_announce("发完牌了,有谁要卖牌的没有?\n");	PIG_D->pig_announce("如果你卖完了牌,打一下 pass 。\n");	bid_init();	return 1;}int do_refresh(string arg){	object me = this_player();	if (!me->query_temp("pigging_seat"))		return notify_fail("你没有在拱猪。\n");	if (pig_stage < PIG_BIDDING)		return notify_fail("你手上没有牌。\n");	write(refresh_str(me->query_temp("pigging_seat")));	return 1;}int do_bid(string arg){	object me = this_player();	int c, b;	string ts;	if (!me->query_temp("pigging_seat"))		return notify_fail("你没有在拱猪。\n");	if (pig_stage != PIG_BIDDING)		return notify_fail("现在不是卖牌的时候。\n");	if (!arg)		return notify_fail("你想卖什么?\n");	if ((c = PIG_D->is_validcard(arg)) == -1 ||		!PIG_D->has_card(cards[me->query_temp("pigging_seat")], 0, 12, c))		return notify_fail("你手上没有这张牌。\n");	if (!(b = PIG_D->is_validbid(c)))		return notify_fail("这张牌不能被卖。\n");	if (bid_flag & b)		return notify_fail("这张牌已经被卖过了。\n");	bid_flag |= b;	switch (b) {	case BID_SPIG :		allow_playbid[0] = 0; break;	case BID_HACE :		allow_playbid[1] = 0; break;	case BID_DSHEEP :		allow_playbid[2] = 0; break;	case BID_CTRANS :		allow_playbid[3] = 0; break;	}	message_vision("$N说道:我卖" + PIG_D->card_str(c) + "!\n", me);	ts = "";	if (bidcard_str != "") ts = ",";	bidcard_str = PIG_D->card_str(c) + "(" + me->query("name") + ")" +		ts + bidcard_str;	return 1;}int do_pass(string arg){	object me = this_player();	int i;	if (!me->query_temp("pigging_seat"))		return notify_fail("你没有在拱猪。\n");	if (pig_stage != PIG_BIDDING)		return notify_fail("你想干什么?\n");	if (passed[me->query_temp("pigging_seat")] == 1)		return notify_fail("你已经停卖了。\n");	passed[me->query_temp("pigging_seat")] = 1;	message_vision("$N说道:我停卖!\n", me);	for (i = 0; i < 4; i++) 		if ((int)passed[seat[i]] == 0)			return 1;	for (i = 0; i < 4; i++)		passed[seat[i]] = 0;	PIG_D->pig_announce("全部停卖,开拱!!\n");	PIG_D->pig_announce("这把由" + pl[dealer]->query("name") + "先出。\n");	play_init();	return 1;}void after_play(){	if (roundcard_count++ < 3) // still within a round		tell_object(pl[round_order[roundcard_count]], 			table_str(round_order[roundcard_count]));	else		after_round();}void after_round(){	string rw;	// removes the 1st round bidcard play limit		allow_playbid[SUIT(roundcards[round_order[0]])] = 1;		// finds the winner of last round 		rw = PIG_D->card_cmp4(roundcards, SUIT(roundcards[round_order[0]]));				message_vision("$N的" + PIG_D->card_str(roundcards[rw]) + "最大。\n", pl[rw]);		// adds the special cards to the winner if any		for (i = 0; i < 4; i++)			for (j = 0; j < 16; j++)				if (roundcards[seat[i]] == specials[j]) {					picks[rw][pick_count[rw]++] = roundcards[seat[i]];						roundcards[seat[i]] == SPIG;					dealer = seat[i];				}		// sort the picks array		picks[rw] = sort_array(picks[rw], 1);		// stuff we do after a hand is completed		if (round_no++ == 13) {			collect_all = "";			for (i = 0; i < 4; i++) {				current_pig[seat[i]] = 0;				hscore[seat[i]] = PIG_D->count_score(picks[seat[i]], bid_flag);				if (hscore[seat[i]] == 1000)					collect_all = seat[i];			}			if (collect_all != "")				for (i = 0; i < 4; i++) {					tscore[seat[i]] += hscore[seat[i]];					if (tscore[seat[i]] <= -1000) {						pl[seat[i]]->add("pighead", 1);						current_pig[seat[i]] = 1;					}				}			else {				for (i = 0; i < 4; i++)					if (seat[i] != collect_all) {						pl[seat[i]]->add("pighead", 1);						current_pig[seat[i]] = 1;					}			}			tell_object(this_object(), scoreboard_str());			}		else			round_init(rw);	}	else {		tell_object(this_object(), round_str());		tell_object(pl[round_order[roundcard_count]], 			refresh_str(round_order[roundcard_count]));	}}	int do_play(string arg){	object me = this_player();	int i, c, sc, nbc = 0, cpos = -1;	string ms;	if (!(ms = me->query_temp("pigging_seat")))		return notify_fail("你没有在拱猪。\n");	if (pig_stage != PIG_PLAYING)		return notify_fail("现在不是出牌阶段。\n");	if (ms != round_order[roundcard_count])		return notify_fail("还没轮到你出牌。\n");	if (!arg || (c = PIG_D->is_validcard(arg)) == -1)		return notify_fail("你要出哪张牌?\n");	for (i = 0; i < card_count[ms]; i++) 		if (cards[ms][i] == c) {			cpos = i; break;		}	if (cpos == -1)		return notify_fail("你手里没有这张牌。\n");	if (roundcard_count > 0 && (sc = PIG_D->has_suit(cards[ms], 0, 		card_count[ms] - 1, SUIT(roundcards[round_order[0]]))) > 0 && 		SUIT(c) != SUIT(roundcards[round_order[0]]))		return notify_fail("你不能出这张牌。\n");	if (roundcard_count == 0 || sc > 1) {		switch (c) {		case SPIG :			if (!allow_playbid[SPADE])				nbc = 1;			break;		case HACE :			if (!allow_playbid[HEART])				nbc = 1;			break;		case DSHEEP : 			if (!allow_playbid[DIAMOND])				nbc = 1;			break;		case CTRANS :			if (!allow_playbid[CLUB])				nbc = 1;			break;		}		if (nbc)			return notify_fail("卖过的牌不能在第一轮出。\n");	}	for (i = cpos; i < card_count[ms] - 1; i++)		cards[ms][i] = cards[ms][i+1];	cards[ms][13 - round_no] = 53;	roundcards[ms] = c;	card_count[ms]--;	message_vision("$N出了一张" + PIG_D->card_str(c) + "。\n", me);	after_play();	return 1;}

⌨️ 快捷键说明

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