qishi.c

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

C
657
字号
/* <SecCrypt CPL V3R05> */
 
/* weiqi playing room for Bugworld 
  based on Chinese GB LPMud server
  written by Shaoyu Wang in Dec. 1996
*/

#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    // jie banned-position possibly exists
#define WQ_NO_JIE 6          // currently no jie-banned position
#define WQ_WINNING 9

#define WQ_POS_OCCUPIED -2
#define WQ_JIE_BANNED  -3
#define WQ_NO_QI_BANNED -4

inherit ROOM;

int bsize;  // board size bsize*bsize, bsize <= 19
int * game = allocate(361);  // records the current board
int * move = allocate(512);  // records the playing sequence
int move_index;
int * eat_flag = allocate(512);  // records eating information

int 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 use
string lastlastmove; //for undo use
int WQ_Started; // for undo and refresh use
int WQ_Undoed; // for undo use
string turn;     // either "black" or "white"

mapping pl = allocate_mapping(2); // black player and white player
int *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 handicap
string *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" });

void create ()
{
  set ("short", "入神坐照室");
  set ("long", @LONG
    
只见好大一间房中,除了一张石桌、两只石凳之外,空荡荡的一无
所有,石桌上刻着纵横十九道棋路,对放着一盒黑子、一盒白子。这棋
室中除了几椅棋子之外不设一物,当是免得对局者分心。墙上贴了一张
小帖子(tie)。
LONG);

  set("objects", ([ /* sizeof() == 4 */
      __DIR__"obj/table" : 1,
      __DIR__"obj/seat" : 2,
  ]));
  set("item_desc", ([ 
      "tie":
"
在这里您可以下围棋或五子棋,以下告诉您下棋的步骤:
一、先找好对手,然后分别用 sit black 和 sit white 入座;
二、使用 new 开始一盘新的棋局:new [-5] [-b(numbers)] [-h(numbers)]
    其中 -5 代表下五子棋,不选即为下围棋;
  -b指定所用棋盘的大小;
    -h指定让子的数目;
  例如:
  围棋:new
  十五乘十五的五子棋:new -5 -b15
  让九子围棋:new -h9
三、使用 play 轮流走棋:例如 play d4 等等。
四、使用 refresh观看棋盘。
五、使用 undo 悔棋。(目前只提供五子棋的悔棋功能。)
六、使用 leave 站起来开路。
"
  ]));
  set("exits", ([ /* sizeof() == 1 */
      "north" : __DIR__"club3",
  ]));

  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_resign","resign");
   add_action("do_new","new");   // new game command
   add_action("do_undo","undo"); //undo last move
   add_action("do_refresh","refresh");

}

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;   
   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="";
   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());
//   if(pl["black"] || pl["white"]) return 1;
   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) {
        color=bd[(i-1)*bsize+j];
        if(color==WQ_BLANK) qi_flag=1;
         else if(color==mycolor){
          alist[aindex]=(i-1)*bsize+j; aindex++;
        }
     }
     if(i<bsize-1) {
        color=bd[(i+1)*bsize+j];
        if(color==WQ_BLANK) qi_flag=1;
          else if(color==mycolor) {
          alist[aindex]=(i+1)*bsize+j; aindex++;
        }
     }

⌨️ 快捷键说明

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