📄 qiyuan4.c
字号:
// 棋苑// 标准棋房// 注意 棋房 一开始下棋后就不能允许有人走动// 不然正在下的棋房上的变数就要重新被初始了// 所以最好在下棋后禁止人物走动// 详细参看 /d/city/qiyuan/qiyuan1.c - Luky#define WQ_BLACK 1#define WQ_WHITE 2#define WQ_BLANK 0#define WQ_AUX_COLOR 8#define WQ_NOT_PLAYING 3#define WQ_PLAYING 4#define WQ_PLAYING_WUZI 7#define WQ_JIE_POSSIBLE 5#define WQ_NO_JIE 6#define WQ_WINNING 9#define WQ_POS_OCCUPIED -2#define WQ_JIE_BANNED -3#define WQ_NO_QI_BANNED -4inherit ROOM;int bsize; // board size bsize*bsize, bsize <= 19int * game = allocate(361); // records the current boardint * move = allocate(512); // records the playing sequenceint move_index;int * eat_flag = allocate(512); // records eating informationint jie_flag; // This flag is set after each 1-stone eat.int jie_x_ban, jie_y_ban; // record possible jie-banned position/* This possible jie-banned position would become real jie-banned position if putting in a stone incurs a 1-stone eat. */int status;int handicap;string lastmove; //for undo usestring lastlastmove; //for undo useint WQ_Started; // for undo and refresh useint WQ_Undoed; // for undo usestring turn; // either "black" or "white"mapping pl = allocate_mapping(2); // black player and white playerint *h_list = ({ 3*19+3, 15*19+15, 15*19+3, 3*19+15, 3*19+9, 15*19+9, 9*19+3, 9*19+15 }); // for use of handicapstring *xindex = ({ "A","B","C","D","E","F","G","H","I", "J","K","L","M","N","O","P","Q","R","S" });string *yindex = ({ "⑴","⑵","⑶","⑷","⑸","⑹","⑺","⑻","⑼", "⑽","⑾","⑿","⒀","⒁","⒂","⒃","⒄","⒅","⒆" }); string *Ucase = ({ "A","B","C","D","E","F","G","H","I","J","K", "L","M","N","O","P","Q","R","S" });string *lcase = ({ "a","b","c","d","e","f","g","h","i","j","k", "l","m","n","o","p","q","r","s" });string *nindex = ({ "1","2","3","4","5","6","7","8","9","10", "11","12","13","14","15","16","17","18","19" });string look_string();void create (){ set ("short", "棋室"); set ("long", @LONG棋苑共分四个大间,是手谈休栖的好地方。这个房间里有一张石桌,上面划着一张围棋盘。桌角摆放着棋子。另外还有两张石凳,颜色一白一黑。在门口的墙壁上贴着一张下棋指南(help)。LONG); set("no_fight", "1"); set("no_steal", "1"); set("no_sleep_room", "1"); set("no_practice","这里不允许练功。\n"); set("objects", ([ __DIR__"obj/table" : 1, __DIR__"obj/seat" : 2, ])); set("item_desc", ([ "help" : ( : look_string : ), ])); set("exits", ([ "south" : __DIR__"qiyuan1", ])); setup();}void init(){ status = WQ_NOT_PLAYING; add_action("do_sit","sit"); add_action("do_leave","leave"); add_action("do_play","play"); add_action("do_pass","pass"); add_action("do_new","new"); // new game command add_action("do_undo","undo"); //undo last move add_action("do_refresh","refresh");}string look_string(){ string msg = "欢迎到棋苑来下棋!\n" +"在这里您可以下围棋或五子棋,以下是下棋的步骤:一、先找好对手,然后分别用 sit black 和 sit white 入座;二、使用 new 开始一盘新的棋局:new [-5] [-b(numbers)] [-h(numbers)] 其中 -5 代表下五子棋,不选即为下围棋; -b 指定所用棋盘的大小; -h 指定让子的数目; 例如: 围棋 new 让九子围棋:new -h9 十五乘十五的五子棋:new -5 -b15三、使用 play 轮流走棋 例如 play d4 等等。四、使用 refresh 观看棋盘。五、使用 leave 离开棋盘。六、使用 pass 弃子认输。七、使用 undo 悔棋。目前只提供五子棋的悔棋功能。"; return msg;}void check_players(){ object bp,wp; object rm = this_object(); if(pl["black"]) { bp = pl["black"]; if(!objectp(bp) || !living(bp) || !present(bp,rm)) { map_delete(pl,"black"); if(living(bp)) bp->delete_temp("weiqi_seat"); } } if(pl["white"]) { wp = pl["white"]; if(!objectp(wp) || !living(wp) || !present(wp,rm)) { map_delete(pl,"white"); if(living(wp)) wp->delete_temp("weiqi_seat"); } } call_out("check_players",3);}int do_sit(string arg){ object me = this_player(); if(me->query_temp("weiqi_seat")) return notify_fail("你已经坐着了。\n"); if(!arg || (arg != "black" && arg != "white")) return notify_fail("你想玩黑棋还是白棋?\n"); if (objectp(pl[arg])) return notify_fail("这个位子上已经有人了!\n"); pl[arg] = me; me->set_temp("weiqi_seat",arg); if(arg == "black") message_vision("$N坐上了黑色的石凳。\n",me); else message_vision("$N坐上了白色的石凳。\n",me); return(1);}int do_leave(string arg){ string s; object me = this_player(); if(!me->query_temp("weiqi_seat")) return notify_fail("你没有在下棋。\n"); s = (string)me->query_temp("weiqi_seat"); message_vision("$N不想再下了,站了起来。\n",me); map_delete(pl,s); me->delete_temp("weiqi_seat"); status=WQ_NOT_PLAYING; delete_temp("action"); return 1;}int do_pass(string arg){ string s; object me = this_player(); if(!me->query_temp("weiqi_seat")) return notify_fail("你没有在下棋。\n"); s = (string)me->query_temp("weiqi_seat"); message_vision("$N抛下棋子,站起来长叹一声,“我输了”\n",me); map_delete(pl,s); me->delete_temp("weiqi_seat"); status=WQ_NOT_PLAYING; delete_temp("action"); return 1;}string show_game(){ int i,j; string s ="\n"; for(i=0;i<bsize;i++) { s += xindex[i]; s += " "; for(j=0;j<bsize;j++) { if(game[i*bsize+j]==WQ_BLACK) s += "●"; else if(game[i*bsize+j]==WQ_WHITE) s+="○"; else if(i==0 && j==0) s += "┌"; else if(i==0 && j==bsize-1) s += "┐"; else if(i==bsize-1 && j==0) s += "└"; else if(i==bsize-1 && j==bsize-1) s +="┘"; else if(i==0) s += "┬"; else if(j==0) s += "├"; else if(j==bsize-1) s += "┤"; else if(i==bsize-1) s += "┴"; else s += "┼"; } s += "\n"; } s += "\n "; for(i=0;i<bsize;i++) s += yindex[i]; s += "\n\n"; return(s);}int str_to_int(string s){ int i; for(i=0;i<19;i++) if(s==nindex[i]) return(i+1); return 0;}/* Here we allow handicapped game by specifying the number of handicap stones in the command line. */int do_new(string arg){ int i,j,num; object me = this_player(); object rm = environment(me); object player; string * ar; string s; if(!me->query_temp("weiqi_seat")) return notify_fail("你还没坐好呐。\n"); if(!objectp(pl["black"]) || !objectp(pl["white"]) ) return notify_fail("还没有对手呐。\n"); status = WQ_PLAYING; jie_flag = WQ_NO_JIE; turn="black"; bsize = 19; handicap = 0; if(arg) { ar = explode(arg," "); num = sizeof(ar); } else num = 0; for(i=0;i<num;i++) { s = ar[i]; if(s[0..1]=="-5") status = WQ_PLAYING_WUZI; if(s[0..1]=="-b") { bsize = str_to_int(s[2..strlen(s)-1]); if( bsize<=0 || bsize>19 ) bsize = 19; } if(s[0..1]=="-h") { handicap = str_to_int(s[2..strlen(s)-1]); if(handicap<2 || handicap>9) handicap = 0; } } if(bsize!=19 || status!=WQ_PLAYING) handicap = 0; for(i=0;i<bsize;i++) for(j=0;j<bsize;j++) game[i*bsize+j]=WQ_BLANK; if(handicap!=0) { if(handicap%2) { game[9*19+9] = WQ_BLACK; for(i=0;i<handicap-1;i++) game[h_list[i]]=WQ_BLACK; } else for(i=0;i<handicap;i++) game[h_list[i]]=WQ_BLACK; turn = "white"; } WQ_Started=0; WQ_Undoed=0; lastmove=""; lastlastmove=""; set_temp("action",1); tell_room(rm,show_game()); player = pl[turn]; if(turn=="black") message_vision("现在轮到黑方$N走棋。\n",player); else message_vision("现在轮到白方$N走棋。\n",player); return(1);}int do_refresh(string arg){ object me = this_player(); object rm = environment(me); object player; if(status==WQ_NOT_PLAYING) return notify_fail("棋盘上是空的。\n"); if (WQ_Started) { if (turn=="black") { tell_object(me,"\n白棋上一步走在了"+lastmove+"\n"); } else tell_object(me,"\n黑棋上一步走在了"+lastmove+"\n"); } tell_object(me,show_game()); player = pl[turn]; if(turn=="black") tell_object(me,"现在轮到黑方"+player->name()+"走棋。\n"); else tell_object(me,"现在轮到白方"+player->name()+"走棋。\n"); return 1;}/* Function 'no_qi' checks if the qi of stone (x,y) is 0. The qi of stone (x,y) means the qi of the block which contains (x,y). no_qi works on the data of bd[19][19] with move (x,y) set. Returns 1(no qi) or 0(has qi).*/int no_qi(int * bd, int x, int y){ int i,j; int qi_flag=0; int mycolor, color; int * alist=allocate(bsize*bsize); int * blist=allocate(bsize*bsize); int aindex=0; int bindex=0; mycolor=bd[x*bsize+y]; // should be either WQ_BLACK or WQ_WHITE alist[aindex]=x*bsize+y; aindex++; while(aindex>0 && !qi_flag) { i=alist[aindex-1]/bsize; j=alist[aindex-1]%bsize; aindex--; blist[bindex]=i*bsize+j; bindex++; bd[i*bsize+j]=WQ_AUX_COLOR; // in order to avoid infinite loop if(i>0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -