推 F23ko:謝謝回答,但我需要花些時間去思考..... 08/01 19:47
※ 引述《F23ko (純潔)》之銘言:
: 但是有一些比較複雜的東西
: 例如:
: 匿名函式
: (塞到委派中的匿名函式,讀取起來有困難,我要怎麼知道委派中的匿名函式是哪一個?)
請幫你的class多一個屬性,上面記載現在是哪一個。
: 二元樹的節點
: (我怎麼知道哪個節點連接哪個節點?只能全部讀取出來,寫入檔案嗎?
: 這樣到讀檔的時候又要再重新插入一次)
有兩種比較直接的方法存二元樹:
1. 假如是Complete binary tree,那可以讓Node的編號從Node[1]開始,Node[n]的
Children一定是Node[2*n]跟Node[2*n+1],這樣你只要照層數BFS下來存就好。
2. 如果是任意的binary tree,那除了硬填成Complete來處理以外,你也可以用DFS
遞迴下去,除了照DFS順序存資料以外再加存「過程」,比如回到上一層的這個動作
,然後讀出來就可以完全照這個順序重現。
但事實上,假設你的二元樹有確保某些性質,讓它不會因為資料進來的順序而造
成(有影響的)改變,或是你根本沒有用到那麼詳細的二元樹性質,那其實你就DFS
或BFS跑一次資料一一存下來就好了,下次讀檔再重建。重建的樹可能跟原本長得不
一樣,但是如果用不上那些性質那就不需要困擾自己,比如說你建個Binary search
tree只是為了加速查找的速度,順序對你來說是不重要的。至於你說「到讀檔的時候
又要再重新插入一次」,那存得再爛大不了也就是O(nlogn) vs O(n)而已,但卻可以
讓你不用多存資料以外的其它資訊,也不用為讀檔寫出一個新的Function,而只要使
用原本的Insert就好了。
: =======================================================================
: 還有所謂的「遊戲記錄檔」之類的東西
: 就是能將遊戲給「錄」下來
: 我覺得是,將玩家以及AI的指令、亂數記錄下來後,再用遊戲的引擎去播放
: 很好,我覺得這會造成程式中「散佈」一堆紀錄、播放用的程式碼
: 撰寫、除錯起來可能會有困難......
你沒有想到一點,那就是這堆紀錄、播放用的程式碼本身就可以拿來當作Debug
Code,所以你應該讓它能夠被拿掉而完全不影響原本的程式。所以第一種方法是你可
以這樣做:
#define REPLAY
.
.
.
// 一般執行用的Code
#if REPLAY
// Replay用的Code
#endif
// 一般執行用的Code
這樣你要對原本的Code做Debug,就把#define那行註解掉就好。
第二種方法是寫一個獨立的class,並提供Method來做動作記錄:
class Replay
{
// 要定義的屬性包括所有要記錄的資訊
public void SaveAction(Action Act);
public Action GetNextAction();
public bool Save(string Filename);
}
然後你要記錄某個動作就在該處call SaveAction()這樣,要播放就是一個迴圈
跑GetNextAction()然後照著拿出來的Action做動作,最後用Save()直接寫成檔這樣
。
而Action也是個class,唯一的重點是它要實做出一些Method,其中一個Method
代表在遊戲中實際去做這個動作。另外還要有存取檔案的功能,這樣Replay就只要依
序Call每個存下來Action的存入功能就能存檔,同樣的反覆Create新的空Action做讀
取直到不能讀也就是讀檔完成了。但依情況而定,存取檔案也可以做在Replay那一層
裡面,但還是要有提供出Method把資料交給Replay就是。
以上不是唯二的方法,我也只是線上隨想隨寫,但這應該是很直覺且也不算太差
的做法。其中可能有些小錯或沒想詳細,不過方向應該大致沒問題。
: 所以我覺得我想的方法不好
: 請問這種功能一般是如何實現?
--
「如果你沒法給我個解釋的話,死一萬次也不能彌補你的過錯!」
「我沒辦法死一萬次賠妳啊。」
「可是你有辦法半死兩萬次,知道嗎,嗯?」
--蓮.席斯塔
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 111.250.175.242