[英]How do i write the classic high/low game in F#?
我正在閱讀功能語言,我想知道如何用純功能語言實現“嘗試”。 所以我決定嘗試用F#來做
但是我無法掌握一半的基礎知識。 我無法弄清楚如何使用隨機數,如何使用返回/繼續(起初我以為我在做多條語句,如果錯了,但似乎我做對了),我也無法弄清楚如何打印數字在F#中,所以我用C#方式做到了。
更難的問題是tryparse中的out參數,我仍然不確定如何在不使用可變變量的情況下實現tries
。 也許有些人可以告訴我如何正確實施
我上周必須做的C#代碼
using System;
namespace CS_Test
{
class Program
{
static void Main(string[] args)
{
var tries = 0;
var answer = new Random().Next(1, 100);
Console.WriteLine("Guess the number between 1 and 100");
while (true)
{
var v = Console.ReadLine();
if (v == "q")
{
Console.WriteLine("you have quit");
return;
}
int n;
var b = Int32.TryParse(v, out n);
if (b == false)
{
Console.WriteLine("This is not a number");
continue;
}
tries++;
if (n == answer)
{
Console.WriteLine("Correct! You win!");
break;
}
else if (n < answer)
Console.WriteLine("Guess higher");
else if (n > answer)
Console.WriteLine("Guess lower");
}
Console.WriteLine("You guess {0} times", tries);
Console.WriteLine("Press enter to exist");
Console.ReadLine();
}
}
}
非常破損和錯誤的F#代碼
open System;
let main() =
let tries = 0;
let answer = (new Random()).Next 1, 100
printfn "Guess the number between 1 and 100"
let dummyWhileTrue() =
let v = Console.ReadLine()
if v = "q" then
printfn ("you have quit")
//return
printfn "blah"
//let b = Int32.TryParse(v, out n)
let b = true;
let n = 3
if b = false then
printfn ("This is not a number")
//continue;
//tries++
(*
if n = answer then
printfn ("Correct! You win!")
//break;
elif n < answer then
printfn ("Guess higher")
elif n>answer then
printfn ("Guess lower")
*)
dummyWhileTrue()
(Console.WriteLine("You guess {0} times", tries))
printfn ("Press enter to exist")
Console.ReadLine()
main()
歡迎使用F#!
這是一個工作程序; 解釋如下。
open System
let main() =
let answer = (new Random()).Next(1, 100)
printfn "Guess the number between 1 and 100"
let rec dummyWhileTrue(tries) =
let v = Console.ReadLine()
if v = "q" then
printfn "you have quit"
0
else
printfn "blah"
let mutable n = 0
let b = Int32.TryParse(v, &n)
if b = false then
printfn "This is not a number"
dummyWhileTrue(tries)
elif n = answer then
printfn "Correct! You win!"
tries
elif n < answer then
printfn "Guess higher"
dummyWhileTrue(tries+1)
else // n>answer
printfn "Guess lower"
dummyWhileTrue(tries+1)
let tries = dummyWhileTrue(1)
printfn "You guess %d times" tries
printfn "Press enter to exit"
Console.ReadLine() |> ignore
main()
很多事情...
如果要調用帶有多個參數的方法(例如Random.Next
),請在args( .Next(1,100)
)周圍使用括號。
您似乎正在使用遞歸函數( dummyWhileTrue
),而不是while循環; 一會兒循環也可以,但是我一直照着你做。 請注意,F#中沒有break
或continue
符,因此您必須在其中包含if
東西,以使其更有條理。
我將您的Console.WriteLine
更改為printfn
以展示如何使用參數調用它。
我展示了最類似於C#的調用TryParse
的方法。 首先聲明變量(使其可變,因為TryParse
將寫入該位置),然后使用&n
作為參數(在這種情況下, &n
類似於C#中的ref n
或out n
)。 另外,在F#中,您可以這樣:
let b, n = Int32.TryParse(v)
在F#中,您可以省略尾隨參數,而在元組末尾返回它們的值; 這只是語法上的方便。
Console.ReadLine
返回一個字符串,該字符串在程序結束時不需要在意,因此請將其通過管道傳遞給ignore
函數以丟棄該值(並擺脫有關未使用的字符串值的警告)。
這是我的看法,只是為了好玩:
open System
let main() =
let answer = (new Random()).Next(1, 100)
printfn "Guess the number between 1 and 100"
let rec TryLoop(tries) =
let doneWith(t) = t
let notDoneWith(s, t) = printfn s; TryLoop(t)
match Console.ReadLine() with
| "q" -> doneWith 0
| s ->
match Int32.TryParse(s) with
| true, v when v = answer -> doneWith(tries)
| true, v when v < answer -> notDoneWith("Guess higher", tries + 1)
| true, v when v > answer -> notDoneWith("Guess lower", tries + 1)
| _ -> notDoneWith("This is not a number", tries)
match TryLoop(1) with
| 0 -> printfn "You quit, loser!"
| tries -> printfn "Correct! You win!\nYou guessed %d times" tries
printfn "Hit enter to exit"
Console.ReadLine() |> ignore
main()
注意事項:
TryParse
dummyWhileTrue
的TryLoop
,似乎更具描述性 doneWith
和notDoneWith
,(出於純粹的美學原因) 我在@Huusom解決方案中取消了Evaluate
的主要模式匹配,但選擇了遞歸循環和累加器,而不是@Hussom的(非常酷)區分Seq.unfold並應用了非常緊湊的解決方案。
open System
let guessLoop answer =
let rec loop tries =
let guess = Console.ReadLine()
match Int32.TryParse(guess) with
| true, v when v < answer -> printfn "Guess higher." ; loop (tries+1)
| true, v when v > answer -> printfn "Guess lower." ; loop (tries+1)
| true, v -> printfn "You won." ; tries+1
| false, _ when guess = "q" -> printfn "You quit." ; tries
| false, _ -> printfn "Not a number." ; loop tries
loop 0
let main() =
printfn "Guess a number between 1 and 100."
printfn "You guessed %i times" (guessLoop ((Random()).Next(1, 100)))
同樣是為了滿足以下條件:
open System
type Result =
| Match
| Higher
| Lower
| Quit
| NaN
let Evaluate answer guess =
match Int32.TryParse(guess) with
| true, v when v < answer -> Higher
| true, v when v > answer -> Lower
| true, v -> Match
| false, _ when guess = "q" -> Quit
| false, _ -> NaN
let Ask answer =
match Evaluate answer (Console.ReadLine()) with
| Match ->
printfn "You won."
None
| Higher ->
printfn "Guess higher."
Some (Higher, answer)
| Lower ->
printfn "Guess lower."
Some (Lower, answer)
| Quit ->
printfn "You quit."
None
| NaN ->
printfn "This is not a number."
Some (NaN, answer)
let main () =
printfn "Guess a number between 1 and 100."
let guesses = Seq.unfold Ask ((Random()).Next(1, 100))
printfn "You guessed %i times" (Seq.length guesses)
let _ = main()
我對狀態使用枚舉,對輸入使用Seq.unfold來查找結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.