2017-01-12 29 views
1

意外「]」在表達三元操作者選擇數組索引

我已經成功地設法獲得工作的代碼的第一部分,現在要找到使用存儲在索引中的球員實得分在成員內部。我正在使用playersTurn並檢查其奇數或偶數是否代表玩家轉身。

我現在有使用三元運算符來獲得在下面的代碼行的得分問題:

let score = this.scoring[this.playersTurn % 2 = 0 ? this.playerOneScore : this.playerTwoScore] 

任何幫助將是輝煌的,這裏是全碼:

open System 

type Game(playerOne, playerTwo) = 
member this.playersTurn = 0 
member this.playerOneName = playerOne 
member this.playerOneScore = 0 
member this.playerTwoName = playerTwo 
member this.playerTwoScore = 0 
member this.scoring = [|0; 15; 30; 40|] 

member this.takeTurn() = 
    let name = this.playersTurn % 2 = 0 ? this.playerOneName : this.playerTwoName 
    let score = this.scoring[this.playersTurn % 2 = 0 ? this.playerOneScore : this.playerTwoScore] 
    printfn name |> "%d is now taking their turn." 
    if((new System.Random()).Next(0, 15) > 8) then 
    if (this.playersTurn % 2 = 0) then incr this.playerOneScore 
    else incr this.playerTwoScore 
    printfn name |> "%d scored a point!" 
    else 
    printfn name |> "%d did not score a point!" 
    incr this.playersTurn 

let tennis = new Game("Player1", "Player2") 
tennis.takeTurn() 
tennis.takeTurn() 
+0

快速查看。一個是數組'[| |]',一個是列表'[]'。 –

+0

因此,賈斯汀尼斯納的回答與這個評論相結合,應該是'this.scoring [|索引|]'? @GuyCoder – KDOT

+0

是的,我認爲會。我不是F#的人,只是想學習哈哈。我很感激。我更新,在此基礎上和你的前一個問題@GuyCoder – KDOT

回答

4

爲了使代碼正常工作,你需要做一些更改。最重要的是,您正在使用帶有成員的類,但這些是F#中的只讀getter屬性。你可以讓它們變化,但這不是慣用的;更好的選擇是改變函數,使其返回新的遊戲狀態。

如果你正在學習F#的話,我認爲這是更好地使更多的變化,並避免使用類(他們不習慣經常在F#),也去不需要突變的解決方案。以下幾乎與你所擁有的一樣。

我提取的共同定義爲普通let價值觀 - 你可以在以後定義的記錄(簡單數據類型),使他們,但現在,這是最簡單的選擇:

open System 

let scoring = [|0; 15; 30; 40|] 
let playerOne = "Player1" 
let playerTwo = "Player2" 
let rnd = new System.Random() 

我把你方法成爲一個函數,它將輪數和初始分數作爲元組並返回新狀態。語法(playersTurn, (playerOneScore, playerTwoScore))定義了一個元組的圈數,並用兩個分數的嵌套元組(我選擇這個,因爲這兩個分數有邏輯關係,所以很高興將它們儲存起來):

let takeTurn (playersTurn, (playerOneScore, playerTwoScore)) = 
    let name = if playersTurn % 2 = 0 then playerOne else playerTwo 
    let score = scoring.[if playersTurn % 2 = 0 then playerOneScore else playerTwoScore] 
    printfn "%s is now taking their turn." name 
    let newOneScore, newTwoScore = 
    if (rnd.Next(0, 15) > 8) then 
     printfn "%s scored a point!" name 
     if (playersTurn % 2 = 0) then playerOneScore + 1, playerTwoScore 
     else playerOneScore, playerTwoScore + 1 
    else 
     printfn "%s did not score a point!" name 
     playerOneScore, playerTwoScore 
    playersTurn+1, (newOneScore, newTwoScore) 

現在,您可以定義初始狀態,並呼籲takeTurn多次獲得下一個狀態(以及下一個狀態等):

let start = 0, (0, 0) 
let step1 = takeTurn start 
let step2 = takeTurn step1 

你當然希望在一個循環中運行這一點 - 你可以在功能使用方式做遞歸或使用諸如Seq.unfold之類的函數。

+1

感謝您發佈代碼,重申我對迴歸基本面的評論。 –

+0

耶穌,這裏有很多我需要看看!這次真是萬分感謝! – KDOT

+0

你是否正確地增加了分數。它看起來像「+ 1」,而不是像「Love,15,30,40」這樣的網球。 –

4

您在F#中使用C#語法作爲三元運算符。你真的需要:

this.scoring.[if this.playersTurn % 2 = 0 then this.playerOneScore else this.playerTwoScore] 
+0

感謝這個,還是同樣的錯誤但是 – KDOT

+0

缺少scoring'後'點。 F#中的索引器訪問是不同的。此外,修正第一次使用三元操作爲好。 –