作者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
推 holymichael:威!大推數字賓果先生 05/14 02:49
推 amosdeus:唔~ 感謝 不過沒有權限觀看。 05/14 19:03