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