[問題] if 判斷大量狀態
看板C_and_CPP (C/C++)作者BlazarArc (Midnight Sun)時間14年前 (2012/03/11 20:09)推噓3(3推 0噓 10→)留言13則, 8人參與討論串1/3 (看更多)
語言:C或C++
問題(Question):
各位好,想請教關於在需要判斷狀態做不同動作
而狀態規模很大的情況下,是否有更好的寫法
比如說寫一個簡單的 GUI(Windows Form)
上面有很多選項,根據使用者選取不同的選項,程式需要做相對應的動作
if (useOption1 && useOption3) {
//cube 1-3-
functionA();
functionB();
}
else if (useOption1 && useOption2 && useOption4) {
//cube 12-4
functionA();
}
else if (useOption3) {
//cube --3-
functionC();
}
...
else {
functionB();
}
問題的假設:這些選項無法獨立出來,所以變成有 2^選項 種狀態
每個狀態要做的事情可能有些相關有些非相關
需要判斷的狀態還是佔整體空間的少數,而剩下的都做預設的動作
搜尋了一下,感覺跟FSM還有function pointer有關,但還是不太清楚怎麼改善
關於問題的規模
選項: 20種
狀態: 2^20
需要判斷的cube:10000
想問像這類判斷的問題,在大規模時有沒有兼具效率與可維護度的通解?
還是有書籍講到關於這方面的軟體工程知識呢?
--
如何寫出無法維護的程式碼
How To Write Unmaintainable Code
http://thc.org/root/phun/unmaintain.html
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.32.216.207
推
03/11 20:32, , 1F
03/11 20:32, 1F
推
03/11 20:32, , 2F
03/11 20:32, 2F
→
03/11 20:33, , 3F
03/11 20:33, 3F
感謝,我去看了一下,但感覺還是沒有解決問題
事實上我可以把每個判斷用一個 class State 包起來(=編碼)
用 switch 還是沒有改善重點
重點是我怎麼減低 evaluate 的次數? @@
switch (encode)
{
//cube 100100011--
10010001100:
10010001101:
10010001110:
10010001111:
doSomething1();
break;
//cube 00-00101110
00000101110:
00100101110:
doSomething2();
break;
...
default:
doSomething10001();
}
問題的重點
1. 要檢查的部分條件(cube)必須擴展成特定state(minterm)
2. 沒有保證state會不會不小心重複
3. 10000多種檢查很難維護,每一次做動作都要檢查10000多次
→
03/11 21:03, , 4F
03/11 21:03, 4F
→
03/11 21:03, , 5F
03/11 21:03, 5F
→
03/11 21:59, , 6F
03/11 21:59, 6F
→
03/11 22:00, , 7F
03/11 22:00, 7F
→
03/11 22:01, , 8F
03/11 22:01, 8F
→
03/11 22:31, , 9F
03/11 22:31, 9F
→
03/11 22:32, , 10F
03/11 22:32, 10F
→
03/12 17:20, , 11F
03/12 17:20, 11F
想到比較具體的例子如下
void MonsterDecideStrategy(State s)
{
if (s.isHpLow && s.hasExit) {
Run();
}
else if (s.isHpLow && s.hasTank) {
HideBehindTank();
}
else if (s.isHpLow && s.hasHealer) {
CallForHeal();
}
else if (s.isHpLow && !s.hasExit) {
Hide();
}
else if (!s.isHpLow && s.hasParty) {
Assist();
}
else if (!s.isHpLow && s.isEnemyAway) {
CastSpell();
}
...
else if (!s.hasReligion && s.isGodNear) {
Pray();
}
else {
Idle();
}
}
遇到這種 code 是否是設計上可以改進?
感覺還是要有 tropical72 說的使用 FSM 來維持狀態檢查(避免重複)
※ 編輯: BlazarArc 來自: 114.32.216.207 (03/12 19:30)
推
03/12 19:49, , 12F
03/12 19:49, 12F
→
03/12 19:49, , 13F
03/12 19:49, 13F
討論串 (同標題文章)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章