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 + -
显示快捷键?