三元运算符选择一个Array索引

时间:2017-01-12 21:35:08

标签: f#

  

表达式中的意外']'

我已成功设法让代码的第一部分工作,现在想要使用存储在成员中的索引找到玩家的真实分数。我正在使用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()

2 个答案:

答案 0 :(得分:4)

您在F#中使用C#语法作为三元运算符。你真的需要:

 .run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
  // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
  // for form inputs)
  if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
    cordova.plugins.Keyboard.hideKeyboardAccessoryBar(false);
    cordova.plugins.keyboard.disablescroll(true)
  }
  if (window.StatusBar) {
    // org.apache.cordova.statusbar required
    StatusBar.styleDefault();
  }
});

答案 1 :(得分: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等函数以函数方式执行此操作。