piggy.c

来自「C实现的MUD,对大家基本入门网络游戏很有帮助!」· C语言 代码 · 共 2,054 行 · 第 1/4 页

C
2,054
字号
        renew("all");
        message_vision("$N让出了"+CDIR[dir]+"边的位置,不打算拱下去了。\n",  me);
        return  1;
}
/******************************************************************************/
//  players  declare  dealing.

int  do_deal(string  arg)
{
        int  i  =  NUM,  cnt,  j;
        object  me=this_player();
        string  dir  =  search_my_dir(me);
        string  *name  =  ({}),  dir2,  str;

        if  (dir  ==  "none")
        {
	me->delete_temp("piggy/seating");
	return  notify_fail("对不起,你没有入座,无法要求发牌。\n");
        }
        if  (!all_have("players"))
	return  notify_fail("还没凑齐四个人,没法开牌局。\n");
        if  (TABLE[dir]["status"]  ==  "asked_for_deal"  &&  TABLE["cond"]  ==  "等人")
        {
	while(i--)
	{
	        dir2  =  DIR[i];
	        if  (TABLE[dir2]["status"]  !=  "asked_for_deal")
		name  +=  ({TABLE[dir2]["player_name"]});
	        continue;
	}
	j  =  sizeof(name);
	switch  (j)
	{
	        case  1:  str  =  name[0];  break;
	        case  2:  str  =  name[0]+"和"+name[1];break;
	        case  3:  str  =  name[0]+"、"+name[1]+"和"+name[2];  break;
	        default:  tell_room(HERE,  "函数错误:发牌。请告诉酸黄瓜。\n");  break;
	}
	return  notify_fail("对不起,"+str+"还没准备好呢。\n");
        }
        if  (TABLE[dir]["status"]  !=  "filled"  ||  TABLE["cond"]  !=  "等发牌")
	return  notify_fail("对不起,现在不是发牌的时候。\n");
        TABLE[dir]["status"]="asked_for_deal";
        message_vision("$N说道:我准备好了,发牌吧。\n",  me);
        if  (all_have("req_deal"))
        {
	message_vision("\n大家都准备好了,由$N负责发牌。\n\n",  me);
	TABLE["cond"]="等卖牌";
	deal_cards("east");
	deal_cards("north");
	deal_cards("west");
	deal_cards("south");
	if  (!is_dir(GAMEINFO["rlead"]))
	        GAMEINFO["rlead"]=search_my_dir(me);
	tell_room(HERE,  "请用「sell」卖牌,「pass」停卖。\n");
        }
        return  1;
}
/******************************************************************************/
//  do_sell,  for  selling  cards  of  course.

int  do_sell(string  arg)
{
        object  me=this_player();
        string  dir;
        string  card,  flag="a",  suit;
        int  rank,  index;

        if(!in_table(me))
	return  notify_fail("对不起,你并不在拱猪。\n");
        if(TABLE["cond"]  !=  "等卖牌")
	return  notify_fail("对不起,现在不能卖牌。\n");
        dir=search_my_dir(me);
        if(TABLE[dir]["status"]  ==  "passed")
	return  notify_fail("对不起,你已经决定停卖了。\n");
        if(!arg)
	return  notify_fail("请用  sell  [-m]  <card>  来卖牌。\n");
        if  (sscanf(arg,  "-%s  %s",  flag,  card)  !=  2)
	card=arg;
        else  if  (flag  !=  "m")
	return  notify_fail("对不起,只能选择  [-m]。\n");
        if  (!(index=card_numb(card)))
	return  notify_fail("对不起,「"+card+"」并不是一张牌。\n");
        index--;
        if  (!is_my_card(me,  index))
	return  notify_fail("对不起,"+CARDS[index]["name"]+"不在你手里。\n");
        if(!is_sellable(index))
	return  notify_fail("对不起,只能卖猪(黑桃Q)、羊(方片J)、变压器(草花T)或血(红桃A)。\n");
        card=CARDS[index]["misc"];
        SOLD[card]=({flag,  (dir=search_my_dir(me))});
        if  (member_array(card,  TABLE[dir]["sold"])  ==  -1)
	TABLE[dir]["sold"]+=({card});
        tell_object(me,  "你决定"+(flag=="a"?"暗":"明")+"卖"+CCARD[card]+"。\n");
        return  1;
}

int  do_claim(string  arg)
{
        object  me=this_player();
        string  dir=search_my_dir(me),  str,  claimer;
        int  i=NUM,j=CARDNO+1;

        if  (TABLE["cond"]  !=  "出牌")
	return  notify_fail("对不起,现在并不在出牌。\n");
        switch(arg)
        {
	case  "all":
	        if  (dir  ==  CLAIM["claimer"])
		return  notify_fail("你已经发出要求,请等别人的回音。\n");
	        if  (CLAIM["claimer"]  !=  "")
		return  notify_fail("已经有人发出要求了,请先否决。\n");
	        CLAIM[dir]="yes";
	        CLAIM["claimer"]  =  dir;
	        str  =  "$N认为自己手中的牌都大了:\n";
	        str  +=  display_suit(dir,  "spade");
	        str  +=  display_suit(dir,  "heart");
	        str  +=  display_suit(dir,  "diamond");
	        str  +=  display_suit(dir,  "club");
	        str  +=  "\n请用「yes」表示同意,「no」表示反对。\n";
	        message_vision(str,  me);
	        break;
	case  "yes":
	        if  (CLAIM["dir"]  ==  "yes")
		return  notify_fail("你已经同意了。\n");
	        if  (!is_dir(CLAIM["claimer"]))
		return  notify_fail("对不起,没人要求摊牌。\n");
	        CLAIM[dir]="yes";
	        message_vision("$N摊牌道:我同意。\n",  me);
	        if  (all_have("agreed_claim"))
	        {
		while  (i--)
		{
		        if  (TABLE[DIR[i]]["card"]!=0)
		        {
			TABLE[CLAIM["claimer"]]["collected"]  +=
			        ({TABLE[DIR[i]]["card"]});
		                TABLE[CLAIM["claimer"]]["card"]  =  0;
		        }
		}
		while(j--)
		{
		        if  (is_dir(CARDS[j]["status"]))
		        {
			TABLE[CLAIM["claimer"]]["collected"]  +=  ({j});
			CARDS[j]["status"]  =  "played";
			if  (j==3)
			{
			        tell_room(HERE,HIB+TABLE[CLAIM["claimer"]]["player_name"]+"吃了猪头!\n"+NOR);
			        PIG_OWNER=CLAIM["claimer"];
			}
		        }
		        continue;
		}
	  	GAMEINFO["round"]=13;
		finish_round();
	        }
	        break;
	case  "no":
	        if  (!is_dir(CLAIM["claimer"]))
		return  notify_fail("对不起,没有人要求摊牌。\n");
	        message_vision("$N不同意,请继续打下去。\n",  me);
	        while  (i--)
		CLAIM[DIR[i]]  =  "no";
	        CLAIM["claimer"]  =  "";
	        break;
	default:
	        return  notify_fail("请用「all」表示你想全收,「yes」表示同意,「no」表示反对。\n");
	        break;
        }
        return  1;
}

int  do_pass(string  arg)
{
        object  me=this_player();
        string  dir=search_my_dir(me),  str;

        if  (!in_table(me))
	return  notify_fail("对不起,你并不在拱猪。\n");
        if  (TABLE["cond"]  !=  "等卖牌")
	return  notify_fail("对不起,现在不能卖牌或停卖。\n");
        if  (TABLE[dir]["status"]=="passed")
	return  notify_fail("你已经决定停卖了。\n");
        TABLE[dir]["status"]="passed";
        message_vision("$N说道:我停卖。\n",  me);
        if  (all_have("pass"))
        {
	TABLE["cond"]="出牌";
	GAMEINFO["round"]=1;
	str  =  "\n大家都停卖了,";
	str  +=  display_sell();
	str  +=  "\n一切就绪,开拱!\n";
	str  +=  "这把由"+TABLE[GAMEINFO["rlead"]]["player_name"]+"先出!\n\n";
	GAMEINFO["next"]=GAMEINFO["rlead"];
	tell_room(HERE,  str);
        }
        return  1;
}
int  do_play(string  card)
{
        object  me=this_player();
        int  numb;

        if  (!in_table(me))
	return  notify_fail("对不起,你并不在拱猪。\n");
        if  (!card)
	return  notify_fail("请用  play  <card>  出牌。\n");
        if  (TABLE["cond"]  !=  "出牌")
	return  notify_fail("对不起,现在不能出牌。\n");
        if  (GAMEINFO["next"]  !=  search_my_dir(me))
	return  notify_fail("对不起,现在不该你出牌。\n");
        if  (is_dir(CLAIM["claimer"]))
	return  notify_fail("对不起,请等到"+TABLE[CLAIM["claimer"]]["player_name"]+"的全收要求有结果后再出牌。\n");
        if  (!(numb=card_numb(card)))
	return  notify_fail("对不起,无法分辨  "+card+"。\n");
        numb--;
        if  (!is_playable(me,  numb))
	return  1;

        CARDS[numb]["status"]="played";
        TABLE[GAMEINFO["next"]]["card"]=numb;
        if  (GAMEINFO["next"]  ==  GAMEINFO["rlead"])
	GAMEINFO["suit"]=CARDS[numb]["suit"];
        if  (!is_sellable(numb))
	message_vision("$N"+(CARDS[numb]["suit"]  ==  GAMEINFO["suit"]?"出":"垫")
		+"了一张"+CARDS[numb]["name"]+"。\n",  me);
        else  if(SOLD[CARDS[numb]["misc"]][0]  !=  "not")
	message_vision(  "$N出"  +  (SOLD[CARDS[numb]["misc"]][0]=="m"  ?
		"明"  :  "暗")  +  "卖的"+CARDS[numb]["name"]+"!\n",  me);
	else  message_vision("$N"+(CARDS[numb]["suit"]  ==  GAMEINFO["suit"]?
		"出":"垫")  +"了一张"+CARDS[numb]["name"]+"。\n",  me);
        if(all_have("cards"))
	finish_round();
        else  GAMEINFO["next"]=next_player(GAMEINFO["next"]);
        if  (is_dir(GAMEINFO["next"]))
	tell_room(HERE,  "下面该由"+TABLE[GAMEINFO["next"]]["player_name"]+"出牌。\n");
        return  1;
}
/******************************************************************************/
object  find_me(string  dir)
{
        object  player;
        string  id=TABLE[dir]["player_id"];

        if  (!(player=present(id,  HERE)))
        {
	tell_room(HERE,  TABLE[dir]["player_name"]+"不在房间里!\n");
	tell_room(HERE,  "清理房间中……\n");
	renew("all");
	tell_room(HERE,  "请重新凑人!\n");
        }

        return  player;
}
int  score_player(string  dir)
{
        int  score,  tscore=0,  *collected=TABLE[dir]["collected"],  i=13,  j,  full=0;
        object  player;

//  do  hearts  first;

        while(i--)
        {
	j  =  i+14;
	if(member_array(j,  collected)  ==  -1)
	        continue;
	score+=CARDS[j]["worth"];
	collected-=({j});
	continue;
        }
        if  (score==-20003)
        {
	score  =  20000;
	full  =  1;
        }
//        else  score  =  (score  /  10)  *  10;
//        tell_room(HERE,  "so  far  after  hearts  score  is  "+score+"\n");
        if  (SOLD["blood"][0]  ==  "m")  score  =  score  *  4;		//  明卖
        else  if  (SOLD["blood"][0]  ==  "a")  score  =  score  *  2;	//  暗卖

//  then  pig.  the  rules  i  go  by  are  that  if  收全红,猪变正。

        if  (member_array(3,  collected)  !=  -1)
        {
	if  (SOLD["pig"][0]=="m")  tscore  =  4*CARDS[3]["worth"];
	else  if  (SOLD["pig"][0]=="a")  tscore  =  2*CARDS[3]["worth"];
	else  tscore  =  CARDS[3]["worth"];
	collected  -=  ({3});
	if  (full)  score=score-tscore;
	else  score  +=  tscore;
        }
        else  full  =  0;
//        tell_room(HERE,  "so  far  after  pig  score  is  "+score+"\n");
        

//  then  sheep.
        if  (member_array(30,  collected)  !=  -1)
        {
	score  =  score  /  100  *  100;
                if  (SOLD["sheep"][0]=="m")  tscore  =  4*CARDS[30]["worth"];
                else  if  (SOLD["sheep"][0]=="a")  tscore  =  2*CARDS[30]["worth"];
	else  tscore  =  CARDS[30]["worth"];
                collected  -=  ({30});
	score  +=  tscore;
        }
        else  full  =  0;
//        tell_room(HERE,  "so  far  after  sheep  score  is  "+score+"\n");

//  then  doubler.
        if  (member_array(44,  collected)  !=  -1)
        {
                if  (SOLD["doubler"][0]=="m")  tscore  =  8;
                else  if  (SOLD["doubler"][0]=="a")  tscore  =  4;
	else  tscore  =  2;
                collected  -=  ({44});
	if  (score  ==  0)  score  =  tscore  *  CARDS[44]["worth"]/2;
	else
	{
	        score  =  (score/1000)*1000;
	        score  =  score  *  tscore;
	}
        }
        else  full=0;
        if  (full)  FULL=dir;
        else  FULL="";

        return  score/100;
}
string  find_large()
{
        mapping  card,  lcard;
        string  dir;
        int  i=NUM,  mark=0;

        if  (is_dir(CLAIM["claimer"]))
	return  CLAIM["claimer"];
        dir=GAMEINFO["rlead"];
        while(i--)
        {
	lcard=CARDS[TABLE[dir]["card"]];
	card=CARDS[TABLE[DIR[i]]["card"]];
	if  (card["misc"]  ==  "pig")
	        mark  =  1;
	if  (card["suit"]==GAMEINFO["suit"]  &&  card["rank"]>lcard["rank"])
	        dir=DIR[i];
	continue;
        }
        i=NUM;
        while(i--)
        {
	TABLE[dir]["collected"]+=({TABLE[DIR[i]]["card"]});
	continue;
        }
        if  (mark)
        {
	PIG_OWNER=dir;
	tell_room(HERE,  HIB+TABLE[dir]["player_name"]+"吃了猪头!\n"NOR);
        }
        return  dir;
}
void  finish_round()
{
        int  i=NUM,  j=CARDNO,  score,  k;
        string  dir=find_large();
        object  me;

        if  (GAMEINFO["round"]  ==  13)
        {
	TABLE["cond"]  =  "算分";
	while(j--)
	{
	        if  (CARDS[j+1]["status"]  !=  "played")
		tell_room(HERE,"函数错误:finish_round。"+CARDS[j+1]["name"]+"还没打过。\n");
	        continue;
	}
	score_player(PIG_OWNER);
	if  (!is_dir(FULL))
  	    while(i--)
	    {
	        score=score_player(DIR[i]);
	        me=find_me(DIR[i]);
	        me->add("piggy/score",  score);
	        me->add("piggy/hand_played",  1);
	        SCORING["hand"][DIR[i]]+=score;
	        if  ((SCORING["sitting"][DIR[i]]+=score)  <  LIMIT)
		PIGHEAD+=({DIR[i]});
	        continue;
	    }
	else
	        while(i--)
	        {
		(me=find_me(DIR[i]))->add("piggy/hand_played",  1);
		if(FULL  !=  DIR[i])
		{
		        PIGHEAD+=({DIR[i]});
		        continue;
		}
		me->add("piggy/score",  score=score_player(FULL));
		SCORING["hand"][FULL]+=score;
		SCORING["sitting"][FULL]+=score;
		continue;
	        }
	if  (k=sizeof(PIGHEAD))
	        while(k--)
		find_me(PIGHEAD[k])->add("piggy/head_received",  1);
	tell_room(HERE,  display_score());
	if  (sizeof(PIGHEAD))
	{
	        all_have("given_head");
	        renew("sitting");
	}
	else  renew("hand");
	return;
        }
        GAMEINFO[GAMEINFO["suit"]]++;
        GAMEINFO["rlead"]=dir;
        GAMEINFO["next"]=dir;
        find_me(dir);
        tell_room(HERE,  display_table(dir));
        renew("round");
        return;
}
string  next_player(string  dir)
{
        switch  (dir)
        {
	case  "east":
	        return  "north";
	case  "north":
	        return  "west";
	case  "west":
	        return  "south";
	case  "south":
	        return  "east";
	default:
	        return  "函数错误:next_player。\n";
        }
}
int  deal_cards(string  dir)
{
        int  j  =  CARDNO  /  4;
        mapping  card=([]);

        while  (j--)
        {
	card  =  CARDS[random(CARDNO)+1];
	if  (card["status"]!="undealt")
	{
	        j++;
	        continue;
	}
	card["status"]=dir;
	continue;
        }
        display_cards(search_dir(dir));
        return  1;
}

int  display_cards(object  player)
{
        string  str,  dir=search_my_dir(player);

        str  =  "你手中的牌如下:\n";
        str  +=  display_suit(dir,  "spade");
        str  +=  display_suit(dir,  "heart");
        str  +=  display_suit(dir,  "diamond");
        str  +=  display_suit(dir,  "club");
        tell_object(player,  str+"\n\n");
        return  1;
}
string  check_collected(string  dir,  string  suit)
{
        string  str="",  toreturn;
        int  size  =  sizeof(TABLE[dir]["collected"]),  i  =  13,  count,  base;

        if  (!size)
	return  "";
        switch  (suit)
        {
	case  "spade":
	        str  +=  "\n  "+HIB"黑桃:"NOR;
	        base=1;
	        break;
	case  "heart":
	        str  +=  "\n  "+HIR"红桃:"NOR;
	        base=14;
	        break;
	case  "diamond":
	        str  +=  "\n  "+HIR"方片:"NOR;
	        base=27;
	        break;
	case  "club":
	        str  +=  "\n  "+HIB"草花:"NOR;
	        base=40;
	        break;
	default:
	        return  "函数错误:display_suit。\n";
        }
        while  (i--)
        {
	if  (member_array((i+base),  TABLE[dir]["collected"])  !=  -1
	  &&  CARDS[i+base]["worth"]  !=  0)
	{
	        count++;
	        str  +=  CNUM[CARDS[i+base]["rank"]]+",";
	}
	continue;
        }
        if  (!count  ||  !str)
	return  "";
        toreturn=str[0..(strlen(str)-3)];
        return  toreturn;
}
string  display_suit(string  dir,  string  suit)

⌨️ 快捷键说明

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