作者laechan (眼镜男)
看板mud_sanc
标题Re: [wizs]问题请教(八)
时间Sun May 13 21:51:38 2007
※ 引述《amosdeus (幽素)》之铭言:
: 问题一、请问要怎样设定当打完某些MOB後会出现新的房间,比如打完A,B两支MOB之
: 後,会在某地出现通往下个地方的房间。(类似试练洞窟七层打完旁边四支才
: 会出现明王才能到下个地方)
假设该房间档名为 FELID_ROOM,那个房间往 down 方向是接
FELID_DOWN 这个房间,在 mob a 自订 die 函数...
void die(object ppl)
{
object r=find_object_or_load(FELID_ROOM);
if(!r->query("exits/down"))
{
r->set("mob_a_die",1);
// mob b 的写法类似
// 接着马上判断是不是两支都死了
if(r->query("mob_a_die") && r->query("mob_b_die"))
r->set("exits/down",FELID_DOWN);
}
::die(); // 执行怪物原先的 die
}
上面的写法可以更简单,有兴趣的 wiz 可自行练习最佳化。
: 问题二、请要要怎样写一个小游戏,MOB会随机出四个数字让玩家猜,比如答案是1234
: 玩家猜2637 会回答 1A1B 第二猜6237 会回答 2A,预定让玩家猜测六次超过
: 就失败拿不到物品
: 以上 谢谢
: Plain@Sanc
这个不是"小"游戏。
大抵上这个一般是写在房间里面,以前我的分身之一 skuld 有写一只
怪物叫猜数字机宾果先生,总共 316 行,底下是全部的程式码...
// 猜数字机宾果先生(bingo)
// Writed by Skuld for [fun] for ppl && wiz in 04-25-98
// Urd 协力制作与加判别式, Belldandy 协助叙述(提供CD65)
// laechan debug in 1998.4.26
#include <config.h>
#define BINGO "猜数字机宾果先生"
inherit OBJECT;
mixed kitty=({ /* add by Belldandy for [fun] */
"叙述",
"小宝躲在土丘後时, 受了一点擦伤",
"敌军对小宝开始猛烈的炮轰, 小宝受了一些伤害",
"敌军轰破土丘的一角, 小宝因此被流弹划伤了脸",
"小宝用机枪扫射, 混乱中左手臂中了敌人一枪",
"小宝要躲到另一个土丘後疗伤时, 左大腿却不幸被子弹打中",
"小宝将手榴弹拼命往敌阵丢, 但是寡不敌众, 手榴弹全部丢完了",
"小宝身上的弹药都快用完了, 敌人也慢慢向他包围",
"小宝已经粮尽弹绝了, 他决定拿起圣剑出去乱砍一番",
"小宝向敌军猛冲猛砍, 可是敌军的炮弹也拼命向他身上招呼",
"小宝身上已经弹痕累累, 濒临死亡的边缘了",
});
void create()
{
seteuid(getuid(this_object()));
set("id",({"bingo"}));
set("short",BINGO"(bingo)");
set("long",@..
这是一部可以玩猜数字的游戏机, 取名宾果游戏, 规则与一般的
宾果游戏一样, 在玩之前, 请您一定要先阅读(read)游戏规则说
明(play)与注意事项(note), 否则如发生故障等问题, 本人一概
不予负责。
Skuld in 04-25-1998
PS. 游戏中发生任何问题, 若损害到玩家的权利, 将不适用於赔
偿条款, 因本机种目前的性质编号为ppl-unget(不牵涉到任
何利益事项, 玩家自愿测试).
Urd in 04-25-1998
..
);
set("mass",500000);
set("prevent_get",1);
set("prevent_sac",1);
set("prevent_auc",1);
set("save",0);
}
void init()
{
add_action("read_some","read");
add_action("start_bingo","start");
add_action("input_num","input");
add_action("giveup","giveup");
add_action("giveup","cancel"); // add by Belldandy
add_action("show_num","show"); // add by Urd
}
int read_some(string str)
{
object ppl=this_player();
if(str=="note")
{
write(@..
BINGO 使用注意事项:
--------------------------------------------------
1. 测试中, 免费使用, 目前提供多人使用, 单向猜
题模式, 发生任何与机器无关的问题时, quit再
进来即可. 有 bug 请回报, 谢谢.
2. 目前的指令有 start, input, giveup 三种, 基
本顺序为 start->input, giveup 为中断执行.
请不要随意乱按, 以免造成不必要的困扰.
Skuld in 04-25-1998
PS. 加入 cancel 指令, 不必 quit 也会自动清除故
障原因, 不过若是在正常游戏状态下, 则得重新
再玩.
Belldandy in 1998.4.25
--------------------------------------------------
..
);
if(!ppl->query_temp("note")) // add check by Laechan.
ppl->set_temp("bingo/note",1);
if(ppl->query_temp("bingo/play") &&
!ppl->query("skuld/bingo"))
ppl->set("skuld/bingo",1);
return 1;
}
if(str=="play")
{
write(@..
BINGO游戏规则说明:
--------------------------------------------------
1. 此游戏基本上是猜一组四位数字, 模式是由机器
跑出数字, 由玩家来猜, 此数字各个位数之间完
全不相同如(1234,5138,3789), 且不为零开头.
简单言之, 就是位在 1234 到 9876 之间.
2. 按下 start 开始(限玩家资料中没有[游戏中]参
数) , 此时机器会跑出一组数字, 完毕後便会出
现请玩家输入数字的讯息, 指令为 input.
3. 输入的原则, 此数必须介於 1234 到 9876 之间
, 且各个位数之间完全不相同. 输入完毕, 机器
会判别你得几a几b, 并显示.
4. 答对, 超过 10 次没答对或下 giveup 指令时,
游戏停止.
Belldandy in 1998.4.25
PS. 合法的数字例子有 1234, 1023, 9876, 4065, 1305.
Laechan in 1998.4.25
--------------------------------------------------
..
);
if(!ppl->query_temp("bingo/play"))
ppl->set_temp("bingo/play",1);
if(ppl->query_temp("bingo/note") &&
!ppl->query("skuld/bibingo"))
ppl->set("skuld/bingo",1);
return 1;
}
write("你要读什麽??\n");
return 1;
}
int start_bingo()
{
object ppl;
int num;
num=1023+random(8854); // 修改 1234->1023 by Laechan.
ppl=this_player();
if(!ppl->query("skuld/bingo")) // 没看过 play 与 note 的人
{
write("请先把 note 与 play 都 read 过一遍, ok ????\n");
return 1;
}
if(ppl->query_temp("bingo/starting")) // 已经处於[游戏中]状态
{
write("你已经在玩了! (假如不是, 请按 cancel 重新再玩) \n");
return 1;
}
write("你按下 START 後, 机器开始跑数字中......");
ppl->set_temp("bingo/starting",1);
call_out("run_number",0,ppl,num);
return 1;
}
int run_number(object ppl,int num) // 跑出数字的副程式
{
int n1,n2,n3,n4,ntmp;
if(!ppl) return 1;
if(ppl->query_temp("bingo/inputing")) // 存在着[输入中]参数时
{
write("bug!! 请按 cancel 清除故障!\n");
return 1;
}
if(ppl && ppl->query_temp("bingo/starting"))
{
n1=(num-(num%1000))/1000; // n1 = (num-千位数以下的部份)/1000
ntmp=num%1000;
n2=(ntmp-(ntmp%100))/100; // n2 = (千位数以下的部份-百位数以下的部份)/100
ntmp=ntmp%100;
n3=(ntmp-(ntmp%10))/10; // n3 = (百位数以下的部份-十位数以下的部份)/10
n4=ntmp%10; // n4 = 十位数以下的部份(个位数).
if(n1==n2 || n1==n3 || n1==n4 || n2==n3 || n2==n4 || n3==n4)
// 有产生相互间相同号码情形时
{
ntmp=1023+random(8854); // 跑出另一组号码, 原号码放弃
call_out("run_number",0,ppl,ntmp);
return 1;
}
else
{
write("ok!\n 你可以开始下 input 猜数字了!\n");
write("小宝刚开始深入敌阵, 便陷入了敌军的包围!\n"); // add by Belldandy
ppl->set_temp("bingo/n1",n1);
ppl->set_temp("bingo/n2",n2);
ppl->set_temp("bingo/n3",n3);
ppl->set_temp("bingo/n4",n4); // 将四个号码依序纪录在玩家档案中
ppl->set_temp("bingo/inputing",1); // 加入[输入中]判别
return 1;
}
}
}
int input_num(string str)
{
object ppl;
int starting,inputing,n1,n2,n3,n4,num,a,b,t;
int m1,m2,m3,m4,ntmp;
ppl=this_player();
starting=ppl->query_temp("bingo/starting");
inputing=ppl->query_temp("bingo/inputing");
n1=ppl->query_temp("bingo/n1");
n2=ppl->query_temp("bingo/n2");
n3=ppl->query_temp("bingo/n3");
n4=ppl->query_temp("bingo/n4"); // 读取机器跑出的四个号码
if(!starting) // 没有在[游戏中]的状态时
{
write("你要先按 start 开始喔!\n");
return 1;
}
if(starting && !inputing) // 在游戏中的状态, 但没有[输入中]的状态
{
if(n1 && n2 && n3 && n4) // 却有四个号码存在时
write("机器故障中, 请按 cancel 排除故障.\n");
else // 去除上面原因, 就表示机器正在跑数字
write("机器还在跑数字中, 请稍候....\n");
return 1;
}
if(!str || str=="") // 没有输入数字时
{
write("你要猜哪个数字是正确答案??\n");
return 1;
}
num=atoi(str); // 整数化
if(num<1023 || num>9876) // 简单判别修改 check1 by Laechan.
{
write("你输入的数字 "+str+" 是不合法的(check1), 请再重新输入一次.\n");
return 1;
}
m1=(num-(num%1000))/1000;
ntmp=num%1000;
m2=(ntmp-(ntmp%100))/100;
ntmp=ntmp%100;
m3=(ntmp-(ntmp%10))/10;
m4=ntmp%10; // 取得玩家所输入的四个数字
if(m1==m2 || m1==m3 || m1==m4 || m2==m3 || m2==m4 || m3==m4) // check2
{
write("你输入的数字 "+str+" 是不合法的(check2), 请再重新输入一次.\n");
return 1;
}
if(m1==n1 || m1==n2 || m1==n3 || m1==n4) // 第一个数的判别
{
if(m1==n1)
a=a+1; // 得到 1a
else
b=b+1; // 得到 1b
}
if(m2==n1 || m2==n2 || m2==n3 || m2==n4)
{
if(m2==n2)
a=a+1; // 得到 1a
else
b=b+1; // 得到 1b
}
if(m3==n1 || m3==n2 || m3==n3 || m3==n4)
{
if(m3==n3)
a=a+1; // 得到 1a
else
b=b+1; // 得到 1b
}
if(m4==n1 || m4==n2 || m4==n3 || m4==n4)
{
if(m4==n4)
a=a+1; // 得到 1a
else
b=b+1; // 得到 1b
}
// 由上面可以得到玩家得几 a 几 b
write("你输入 "+str+" , 得到 "+a+"a"+b+"b.\n");
ppl->add_temp("bingo/t",1); // add by Laechan
t=ppl->query_temp("bingo/t"); // 次数累记
if(a==4) // 完全猜中时
{
write("你猜中了, 恭喜你!\n");
write("在你努力了"+t+"小时後, 终於救出了被敌军包围的小宝!\n");
if(t<=3) // 在三次内完全猜中时
{
shout(ppl->query("short")+"只花了"+t+"小时便"+
"英勇地解救了被敌军包围的小宝!\n");
} // add by Belldandy
ppl->delete_temp("bingo");
return 1;
}
if(t>10) // 猜数字超过 10 次时
{
write("很抱歉, 你猜了超过 10 次都没猜中, 公布答案 : ");
write(""+n1+""+n2+""+n3+""+n4+".\n");
write("小宝被敌军乱刀乱枪惨忍地杀死了! 你解救失败!\n"); // add by Belldandy
ppl->delete_temp("bingo");
return 1;
}
write(kitty[t]+", 请继续加油, 只要你猜中便可以解救他!\n");
// add kitty by Belldandy ^_^
return 1;
}
int giveup()
{
write("游戏的资料删除中......");
this_player()->delete_temp("bingo");
if(!this_player()->query_temp("bingo"))
write("ok! 你可以重新开始.\n");
else
write("无法删除, 请 quit 再进来即可.\n");
return 1;
}
int show_num(string str) // add by Urd
{
object ppl;
int n1,n2,n3,n4;
ppl=this_player();
n1=ppl->query_temp("bingo/n1");
n2=ppl->query_temp("bingo/n2");
n3=ppl->query_temp("bingo/n3");
n4=ppl->query_temp("bingo/n4");
if(!wizardp(ppl)) return 1;
if(str!="num")
{
write("语法: list num.\n");
return 1;
}
write("机器预测的数字是 "+n1+""+n2+""+n3+""+n4+".\n");
return 1;
}
经过精简的话大概 200 行就可以搞定,实体物件可自行 clone,
位置在 ~laechan/goddess~/skuld/tool/bingo.c
Laechan
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.225.4.91
1F:推 holymichael:威!大推数字宾果先生 05/14 02:49
2F:推 amosdeus:唔~ 感谢 不过没有权限观看。 05/14 19:03
3F:推 laechan:不用看啊,clone出来试就知道了.程式码则在上面. 05/15 19:28