2009-11-22 55 views
3

我有一些事件發生在遊戲中。我想控制這些事件發生的時間和順序。F#:存儲和映射功能列表

例如:

事件1:在屏幕上顯示N個部分的文字框&播放聲音效果

事件2:清除屏幕上的文本

我的解決方案(也許有更好的一個),就是有一個包含事件的函數列表。事件執行他們的行爲,然後返回下一個事件發生在遊戲中。我想過使用List.map或List.collect,因爲我實際上是在執行某些行爲代碼時將事件列表映射到新的事件列表。

在上面的例子中,Event1可以由兩個功能組成:一個顯示文本和一個播放聲音(因此需要列表)。顯示文本的函數會爲N-1幀返回自身的副本,然後返回清除文本的Event2。播放聲音功能將返回相當於無操作。

如果這是一個很好的解決方案,我可以用C++或C#來做。我的目標是在F#中做一個等效或更好的解決方案。

+0

你想用你的函數列表解決什麼問題? – 2009-11-22 21:47:10

+0

我已經改變了原來的問題,因爲它在解決方案空間中定義;沒有問題的空間。我希望這可以清除事情。 – rysama 2009-11-22 22:36:22

回答

5

你的意思是這樣嗎?

let myActions = 
    [fun() -> printfn "You've woken up a dragon." 
    fun() -> printfn "You hit the dragon for 0 points of damage." 
    fun() -> printfn "The dragon belches." 
    fun() -> printfn "You have died."] 

let actionBuilder actionList = 
    let actions = ref actionList 
    fun() -> 
     match !actions with 
     | [] ->() 
     | h::t -> h(); actions := t 

用法(F#交互):

> let doSomething = actionBuilder myActions;; 

val doSomething : (unit -> unit) 

> doSomething();; 
You've woken up a dragon. 
val it : unit =() 
> doSomething();; 
You hit the dragon for 0 points of damage. 
val it : unit =() 
> doSomething();; 
The dragon belches. 
val it : unit =() 
> doSomething();; 
You have died. 
val it : unit =() 
> doSomething();; 
val it : unit =() 
> 

**編輯:**如果你希望能夠加入行動,也許是更好地使一個使用隊列內部動作飲水機,因爲追加是O(N)與列表和O(1)與隊列:

type actionGenerator(myActions: (unit->unit) list) = 
    let Q = new System.Collections.Generic.Queue<_>(Seq.ofList myActions) 

    member g.NextAction = 
     fun() -> 
      if Q.Count = 0 then() 
      else Q.Dequeue()() 

    member g.AddAction(action) = Q.Enqueue(action) 
+0

很好的答案,+1加入一個模棱兩可的問題努力! – Benjol 2009-11-23 12:10:38

2

不太清楚你想在這裏實現什麼......它可以幫助你思考你正在尋找的確切類型。這聽起來像也許你想通過在第一個應用每個函數將(unit->(unit->unit)) list映射到(unit->unit) list。如果是這樣的話,你可以像這樣:

let l = [(fun() -> (fun() -> printfn "first nested fn")); (fun() -> (fun() -> printfn "second nested fn"))] 
let l' = List.map (fun f -> f()) l 
+0

我的目標是將函數調用鏈接在一起。例如,函數「foo」會返回下一個要調用的函數「bar」。 – rysama 2009-11-22 21:21:01

2

如果你正在尋找一個語法來聲明您的列表類型,然後在這裏是爲了做到這一點的一種方法:

List<`a->`b> 

這假定該函數採用單個參數。

但是你試圖弄清楚這個類型的語法的一個事實是暗示你仍然在看着這個,就好像你在編程過程語言一樣。

做的「功能性」的方式是集中生成列表的邏輯,讓編譯器來推斷根據您的代碼的類型

0

好像你正在嘗試做的事情非常複雜的方式。這有時是必要的,但通常不是。

既然你問這個問題,我假設你有更多的命令式語言經驗。看來您的問題的解決方案與功能列表完全不同。

+0

這不是一個答案它是一個評論 – 2011-04-09 03:08:13

1

我已經讀過兩遍你的問題,但我仍然不確定自己明白你想要什麼。但根據我的理解,您的「事件」不一定按照它們出現在「列表」中的順序調用。如果是這樣的話,你並不是真的想要一個F#列表,你需要某種查找。

現在的另一個問題是,確定一個事件應該遵循的是一個好主意嗎?這種相當於一勞永逸的硬編碼功能,不是嗎?

編輯

我,你說你要「鏈函數調用一起」評論見。

如何一個接一個地寫它們?畢竟,我們不在Haskell中,F#會按照你寫的順序來解僱他們。

如果您希望更具功能性,您可以使用延續 - 每個函數都需要一個額外的參數,這是下一個要執行的函數。幾乎一元(我相信),除了你的情況,他們似乎是行動,所以沒有值從一個函數串到下一個。

不知道這是否有幫助:我認爲你必須嘗試改寫你的問題,從這裏的答案的多樣性來判斷。