📄 pai.c
字号:
// pai.c 牌// make by 猫部猫(Catyboy)#include <ansi.h>#define DESK "desk"#define DESK2 "desk2"#define PAIS 55inherit ITEM;int has_start;mapping player; // 玩家IDmapping player_data; // 玩家资料 21点// 模式string mode; // 8,21,D2string mode2; // auto,manint game_start; // 1局是否开始?int player_counter; // 计数器 8string who_play; // 正在出牌的人 21string last_play; // 最后一个出牌的人mixed last_pai; // 最后出的牌// 牌容器mixed expai; // 不使用的的牌 id = deskmixed allpai; // 使用的牌 id = desk2mapping pai_hand; // 玩家手上的牌 id = playerid+" hand"mapping pai_out; // 玩家出的牌 id = playerid+" out"mapping pai_save; // 玩家保存的牌 id = playerid+" save"mapping pai_hide; // 玩家隐藏的牌 id = playerid+" hide"// 计数器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" });void save_player_data();void restore_player_data();void finish_21();int pai_number(int pai);int pai_color(int pai);int do_reset(string arg);int do_shunxu(string arg);int do_nextone(string arg);int do_xipai(string arg);int do_paipai(string arg);int do_pass(string arg);int pick_out(string from, int id);int pick_out2(string from, int id);int pick_in(string to,int card);string id_to_name(string id);mixed* get_pais(string id);object get_player(string id);int is_playing(object ob);int move_pai(string pid,string from,string to);int sizeof_pai(mixed* p);string view_pai(object who,string which);int do_movepai(string arg);string id_to_pai(int id);int pai_to_id(string id);void msg(string msg);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;}string mode_name(){ if(mode=="8") return "8张"; if(mode=="21") return "21点"; return "不明模式";}void reset_pai(){ int i; string* key; for(i=0;i<54;i++) allpai[i+1]=i; allpai[0]=54; for(i=0;i<expai[0];i++) pick_out("desk",expai[i+1]); key = keys(player); for(i=0;i<sizeof(key);i++) { pai_hand[key[i]]=allocate(PAIS); pai_out[key[i]]=allocate(PAIS); pai_save[key[i]]=allocate(PAIS); pai_hide[key[i]]=allocate(PAIS); } who_play = 0; last_play = 0; last_pai = ( {-1,-1,-1,-1,-1} );}int reset_all(){ int i; has_start = 0; if(sizeof(player)!=0) msg(this_player()->name()+"重新置牌了。\n"); player = ([]); player_data = ([]); pai_hand = ([]); pai_out = ([]); pai_save = ([]); pai_hide = ([]); allpai = allocate(PAIS); expai = allocate(PAIS); expai[0]=0; reset_pai(); // reset mode mode = 0; mode2 = 0; return 1; }void create(){ set_name("牌桌", ({"card desk","pai"})); 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_help2", "helppai2"); // 基本指令 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_sortpai", "sort"); add_action("do_movepai", "move"); add_action("do_shunxu", "order"); add_action("do_now", "now"); add_action("do_nextone", "next"); add_action("do_pass", "pass"); add_action("do_end", "finish"); add_action("do_setmode", "setmode"); // 扩展指令 add_action("do_paipai", "pai"); add_action("do_paipai2", "paipai"); add_action("do_mopai", "mopai"); add_action("do_chupai", "play"); add_action("do_showpai", "show"); add_action("do_hidepai", "hide"); add_action("do_takebackpai", "takeback"); add_action("do_removej", "removej"); add_action("do_daopai", "daopai"); // 计数器 add_action("do_press", "press"); add_action("do_showc", "showc"); add_action("do_removec", "removec");}int do_help(string arg){ this_player()->start_more( read_file(__DIR__ "helppai")); write("\n"); return 1;}int do_help2(string arg){ if(!arg)return 0; if(file_size(__DIR__ ""+arg+"_hlp")<0)return 0; this_player()->start_more( read_file(__DIR__ ""+arg+"_hlp")); write("\n"); return 1;}int do_reset(string arg){ if(arg == "counter") { if(!is_playing(this_player())) return notify_fail("你都不玩牌啊!\n"); write("计数器复位了。\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("重新开始了。\n"); reset_pai(); if(mode == "8") { player_counter = 0; restore_player_data(); } if(mode == "21") restore_player_data(); 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"; pai_hand[me->query("id")]=allocate(PAIS); pai_out[me->query("id")]=allocate(PAIS); pai_save[me->query("id")]=allocate(PAIS); pai_hide[me->query("id")]=allocate(PAIS); msg(me->name()+"加入牌局了。\n"); return 1;}int do_start(string arg){ if(!is_playing(this_player())) return notify_fail("你都不玩,开始什么啊!\n"); has_start = 1; msg(this_player()->name()+"开始了牌局。\n"); this_player()->start_more( read_file(__DIR__ "startpai")); write("\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"); if(arg==""||arg==0) arg = DESK; pai = get_pais(arg); if(pai==0) return notify_fail("没有这种牌,请参阅帮助。\n"); sum = pai[0]; rand = sum; for(i=0;i<sum;i++) { which = random(rand)+1; temp = pai[rand]; pai[rand] = pai[which]; pai[which] = temp; rand --; } msg(this_player()->name()+"洗了洗"+id_to_name(arg)+"的牌。\n"); return 1;}int do_sortpai(string arg){ int i,sum,which,v=0,j,it; int c1,c2; string temp; mixed* pai; if(!is_playing(this_player())) return notify_fail("你都不玩,整理什么牌啊!\n"); if(arg==""||arg==0) arg = this_player()->query("id")+" hand"; if(arg=="/c") arg = this_player()->query("id")+" hand /c"; if(sscanf(arg,"%s /c",temp)==1) { v = 1; // 以色整理 arg = temp; } pai = get_pais(arg); if(pai==0) return notify_fail("没有这种牌,请参阅帮助。\n"); sum = pai[0]; for(i=0;i<sum;i++) { for(j=0;j<sum;j++) { if(i==j)continue; if(v) { c1=pai[i+1]; c2=pai[j+1]; } else { c1 = pai[i+1]>=52?pai[i+1]:(pai[i+1]-pai[i+1]/13*13)*4+pai[i+1]/13; c2 = pai[j+1]>=52?pai[j+1]:(pai[j+1]-pai[j+1]/13*13)*4+pai[j+1]/13; } if(c1<c2) { it=pai[i+1]; pai[i+1]=pai[j+1]; pai[j+1]=it; } } } msg(this_player()->name()+"整理了一下"+id_to_name(arg)+"的牌。\n"); return 1;}int do_movepai(string arg){ int i,wi,v = 1,op; string* whichs; string which,where1,where2,temp,pstr,err; if(!is_playing(this_player())) return notify_fail("你都不玩啊!\n"); if(arg==""||arg==0) return notify_fail("格式:move which[+which2...] from where1 to where2 [/h]\n"); if(sscanf(arg,"%s from %s to %s",which,where1,where2)!=3) return notify_fail("格式:move which from where1 to where2 [/h]\n"); if(sscanf(where2,"%s /h",temp)==1) { where2 = temp; v = 0; } if(where1=="hand"|| where1=="out"|| where1=="save"|| where1=="hide") where1 = this_player()->query("id")+" "+where1; if(where2=="hand"|| where2=="out"|| where2=="save"|| where2=="hide") where2 = this_player()->query("id")+" "+where2; if(get_pais(where2)==0) return notify_fail("目的错误,请参阅帮助。\n"); whichs = explode(which,"+"); pstr = ""; op = 0; err = ""; for(i=0;i<sizeof(whichs);i++) { temp = whichs[i]; if(sscanf(temp,"%d",wi)==1) wi = pick_out2(where1,wi); else { if(where1=="desk"&&has_start) return notify_fail("已经开始了,不能移动指定的牌。\n"); wi=pick_out(where1,pai_to_id(temp)); } if(wi==-1) { err = "源或者牌号/序号错误,请参阅帮助。\n"; continue; } if(!pick_in(where2,wi)) { err = "移动牌错误。\n"; continue; } if(pstr!="") pstr += " "; pstr+= id_to_pai(wi); op ++; // if(i<5) // last_pai[i]=wi; } if(!v) pstr = chinese_number(op) +"张牌"; if(op>0) msg(this_player()->name()+"把"+pstr+"从"+id_to_name(where1)+"放到"+id_to_name(where2)+"。\n"); return err==""?1:notify_fail(err);}int do_paipai(string arg){ int i,sum,j; string* key; string cmd; if(!is_playing(this_player())) return notify_fail("你都不玩啊!\n"); if(!has_start) return notify_fail("还没有开始就派牌?\n"); if(arg==0||sscanf(arg,"%d",sum)!=1) sum = 100; key = keys(player); for(i=0;i<sum;i++) { if(sizeof_pai(allpai)==0) return 1; for(j=0;j<sizeof(key);j++) do_movepai("1 from desk to "+key[j]+" hand /h"); } return 1;}int do_mopai(string arg){ int i,sum,j; string* key; string cmd; if(!is_playing(this_player())) return notify_fail("你都不玩啊!\n"); return do_movepai("1 from desk to "+this_player()->query("id")+" hand /h");}int do_chupai(string arg){ int i,sum,j,done,temp; mixed* inv; string cmd; object ob; if(!is_playing(this_player())) return notify_fail("你都不玩啊!\n"); if(mode == "21") { } else { if(arg==0) return notify_fail("格式:play which[+which2...]\n"); } if(mode == "8") return notify_fail("使用hide命令摆牌\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(mode == "21") if(do_movepai("1 from desk to out")) { done = 1; // check is over 21,if over pass inv = get_pais(this_player()->query("id")+" out"); sum = c21(inv); msg(this_player()->name()+"手上有"HIY+sum+"点"NOR"了。\n"); if(sum>21) { do_pass(HIR"爆了!!!"NOR"\n"); return 1; } } if(done==0) done = do_movepai(arg+" from hand to out"); if(done) { ob = get_player(player[who_play]); if(ob) { who_play = player[who_play]; do_nextone(""); // tell_object(ob,"你的牌是:\n"+view_pai(ob,who_play+" hand")+"\n"); } } return 1;}int do_showpai(string arg){ int i,sum,j; string* key; string cmd; object ob; if(!is_playing(this_player())) return notify_fail("你都不玩啊!\n"); if(arg==0) return notify_fail("格式:show which[+which2...]\n"); if(who_play==0) who_play = this_player()->query("id"); do_movepai(arg+" from hand to save"); return 1;}int do_hidepai(string arg){ int i,sum,j; string* key; string cmd; object ob; if(!is_playing(this_player())) return notify_fail("你都不玩啊!\n"); if(arg==0) return notify_fail("格式:hide which[+which2...]\n"); if(who_play==0) who_play = this_player()->query("id"); do_movepai(arg+" from hand to hide /h"); return 1;}int do_takebackpai(string arg){ int i,sum,j; string* key; string cmd,where; object ob; if(!is_playing(this_player())) return notify_fail("你都不玩啊!\n"); if(arg==0) return notify_fail("格式:takeback which[+which2...] [from where]\n"); if(sscanf(arg,"%s from %s",cmd,where)!=2) { cmd = arg; where = "out"; } do_movepai(cmd+" from "+where+" to hand"+(where=="hide"?" /h":"")); return 1;}int do_view(string arg){ mixed* pai; if(arg==""||arg==0) arg = this_player()->query("id")+" hand"; if(arg=="hand"|| arg=="out"|| arg=="save"|| arg=="hide") arg= this_player()->query("id")+" "+arg; pai = get_pais(arg); if(pai==0) return notify_fail("没有这种牌,请参阅帮助。\n"); write(id_to_name(arg)+":"+view_pai(this_player(),arg)+"\n"); return 1;}string extra_long(){ object me; string r,key; mixed *idx; int i; me = this_player(); idx = keys(player); r = id_to_name(DESK) + ":" + view_pai(me,DESK)+"\n"; r = r + id_to_name(DESK2) + ":" + view_pai(me,DESK2)+"\n"; r+= "****"; if(mode&&mode!="") r+= mode_name(); r+="******************************************\n"; for(i=0;i<sizeof(idx);i++) { key = idx[i]; r = r + id_to_name(key+" hand") + ":"+view_pai(this_player(),key+" hand")+"\n"; r = r + id_to_name(key+" out") + ":"+view_pai(this_player(),key+" out")+"\n"; r = r + id_to_name(key+" save") + ":"+view_pai(this_player(),key+" save")+"\n"; r = r + id_to_name(key+" hide") + ":"+view_pai(this_player(),key+" hide")+"\n"; r = r + "**********************************************\n"; } return r;}int pick_out(string from, int id){ int i,j,s; string* p; mixed* pai; pai = get_pais(from); if(pai==0) return -1; s = pai[0]; for(i=0;i<s;i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -