2017-01-12 4 views
1

予期しない「]」式で私が正常に動作するコードの最初の部分を取得するために管理し、現在保存されたインデックスを使用してプレイヤー本当のスコアを見つけたいき三項演算子は、Arrayインデックスを選択する

メンバーの中に。私は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

クイックルック。 1つは配列 '[| |] '、リストは' [] 'です。 –

+0

このコメントにJustin Niessnerの答えを組み合わせると、 'this.scoring [| index |] '? @GuyCoder – KDOT

+0

ええ、私はそれを仮定しました。私はF#の男ではなく、ただハハを学ぼうとしています。それは有り難いです。 @GuyCoder – KDOT

答えて

4

コードを機能させるには、もう少し変更する必要があります。最も重要なのは、クラスをメンバーとともに使用していることですが、これらはF#の読み取り専用のゲッタープロパティです。それらを変更可能にすることができますが、それは慣用的ではありません。より良いオプションは、新しいゲーム状態を返すように関数を変更することです。

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))は、ターン数と2つのスコアを持つネストされたタプルとタプルを定義する(2つのスコアは、論理的に関連しているので、私はこれを選択したので、それらを一緒に保管してうれしいです):今

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

スコアを正しくインクリメントしていますか?テニスのように 'Love、15、30、40'ではなく' + 1'のように見えます。 –

4

F#の3進演算子にC#構文を使用しています。あなたは本当に必要があります:

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

これに感謝しますが、同じエラーですが – KDOT

+0

'スコアリングの後にドットがありません。 F#ではインデクサーのアクセスが異なります。また、三項演算子の最初の使い方も修正してください。 –