2010-07-16 23 views
4

我正在使用JavaScript和畫布創建一個基本的RPG遊戲引擎原型。我仍然在紙上制定一些設計規範,並且我遇到了一些問題,我不太清楚如何處理。用JavaScript創建基本公式編輯器

我將有一個Character對象,它具有一個Attribute對象數組。屬性將如下所示:

function(name, value){ 
    this.name = name; 
    this.value = value; 
    ... 
} 

一個角色也將具有根據屬性計算的「技能」。技能值也可以由用戶輸入的公式確定。合法公式看起來像這樣:

((@attribute1Name + (@attribute2Name/2) * 5) 

其中@符號後面的任何文本都代表屬於該字符的屬性的名稱。公式將作爲字符串輸入到文本字段中。

我有一個問題是理解解析和評估這個公式的正確方法。最初,我的計劃是對屬性名稱進行簡單的替換,並對錶達式進行評估(如果無效,則評估失敗)。然而,這會帶來一個問題,因爲它會允許JavaScript注入該領域。我假設我需要某種類似於中介計算器的FSM來解決這個問題,但我對計算理論有些生疏(感謝企業界!)。我真的不是要求某人把我的代碼交給我,因爲我希望得到你對這個問題的最佳解決方案的意見嗎?

編輯:感謝您的答覆。不幸的是,生活讓我很忙,我還沒有嘗試過一種解決方案。當我得到一個結果(好或壞)時會更新。

回答

0

我認爲,不要讓他們把整個公式放進去,你可以讓select有操作和值的標籤,讓他們選擇。

即。一組具有屬性的操作數標籤:

<select>   <select> <input type="text"> 
@attribute1Name1 +  (check if input is number) 
@attribute1Name2 - 
@attribute1Name3 * 
@attribute1Name4/

+0

感謝這個想法。這是一個選項。如果我在創建自由形式配方領域掛上鉤,這可能是一個可行的選擇,直到我可以得到一個更強大的解決方案。同樣有爭議的是,這對用戶來說更容易,因爲他們不必擔心公式語法。我必須嘗試兩種方法,看看我得到了什麼樣的反饋。謝謝! – framauro13 2010-07-16 15:36:29

+0

試試這一分鐘,你會發現它太繁瑣和緩慢。 – 2010-07-19 07:04:44

0

有一個非常簡單的解決辦法:只要進入正常的JavaScript公式(即,如果你在寫你的對象的方法)並使用this來引用您正在處理的對象。

在評估方法使用apply()call()see this answer)時更改this

+0

這就是我計劃要做的。驗證後,將@替換爲'this'。和eval。我最大的擔憂是用戶在eval被調用之前將JavaScript注入字段。儘管如此,我一定會對此進行測試......正如他們所說,最簡單的答案往往是正確的。我希望總是適用於軟件。 – framauro13 2010-07-16 15:34:22

+0

如果你的遊戲引擎要變成類似Facebook的東西(任何人都可以編輯公式),任何編輯公式的方式都太危險了,因爲它會破壞遊戲的平衡。所以我的猜測是,你爲遊戲設計師提供這個,在這種情況下你可以並且應該相信他們。 – 2010-07-19 07:06:56

0

我最近寫了一個類似的應用程序。我可能投入了太多的工作,但是我走了整整9碼,寫了一個掃描儀和一個解析器。

掃描儀將文本轉換爲一系列的標記;令牌是由令牌類型和值組成的簡單對象。對於標點符號,value = character,對於數字,這些值將是與數字的數字值相對應的整數,對於變量,它將是(對變量對象的引用),其中該變量將坐在具有名稱的對象。相同的變量對象=相同的變量,natch。

解析器是一個簡單的蠻力遞歸下降解析器。 Here's the code

我的語法分析器使用AND/OR來代替+/-,但我認爲您可以看到這個想法。有幾個級別的表達式,並且每個表達式嘗試儘可能地組裝它自己,並調用較低級別來解析嵌套構造。完成後,我的解析器生成了一個包含表示表達式的樹結構的Node。

在你的程序中,我想你可以存儲那個節點,因爲它的結構本質上代表了它的評估公式。

但是,考慮到所有這些工作,我會明白,只是陷入和使用eval是多麼誘人!

+0

FSM似乎是「適當的」解決方案,但對於我想要實現的目標,我仍然不確定它是否過分矯枉過正。一位同事告訴我,FSM將是「最簡單」和「最安全」的方法。最安全,當然。我並不完全相信這是「最簡單的」。 感謝解析器代碼,稍後我會深入研究它。 – framauro13 2010-07-16 15:39:11

+0

我已經考慮過爲我的任務手寫一個FSM,但是當我讓Bison去城裏時,事實證明有12或18個國家需要這個簡單的表達!一個FSM是快速且相對簡單的,但我覺得它會寫一個用於評估表達式。儘管如此,我的掃描儀確實使用了FSM,這非常簡單。 – 2010-07-16 15:44:22

2

不同的想法,因此,一個單獨的建議:

eval()正常工作,而且也沒有必要重新發明輪子。

假設您的公式語言中只有一小部分固定數量的變量,那麼在表達式中掃描您的方式就足夠了,並驗證您遇到的所有內容都是括號,操作符或您的某個變量名稱。我認爲沒有辦法將這些代碼組裝成一段可能對eval產生惡意副作用的代碼。

所以:

  • 掃描的表達,以驗證它只是一個非常有限的詞彙吸引。
  • 讓eval()解決。

在將風險降低到(接近?)0時,可能會導致工作量和代碼量最少。最糟糕的是,濫用者可能會在變量名上加上圓括號以嘗試執行該變量。

+0

這是我原來的想法。使用正則表達式來限制輸入,計算括號,確定變量名稱,然後評估。一位同事告訴我,FSM將是最簡單和最安全的方法。我同意「安全」,但「容易」是有爭議的:) – framauro13 2010-07-16 15:29:14

0

我對通過儘可能最簡單的方式完成這項任務感到着迷。

這裏的另一種方法:

  1. Convert infix to postfix;
  2. 使用一個非常簡單的基於堆棧的計算器來評估結果表達式。

這裏的基本原理是,一旦擺脫了「*之前的+」和括號的複雜性,剩餘的計算就非常簡單。

+0

而不是添加另一個答案,我建議編輯你的第一個。 – 2010-07-19 07:07:49

+1

我曾考慮過,但這是更改答案的語義,而不是呈現完全不同的答案。儘管如此,我會編輯道歉。它什麼都不貢獻。 – 2010-07-19 08:14:31