Created
March 30, 2016 03:42
-
-
Save hakelimopu/cbfa485293b2e157628ace239a00dd71 to your computer and use it in GitHub Desktop.
Quick Shot #1: Guess My Number
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open Microsoft.SmallBasic.Library | |
//Guess My Number | |
//1. Computer picks a number between 1 and 100 | |
//2. Player makes a guess | |
//3. Computer tells player if guess was too high or too low | |
//4. If the guess is not correct, go back to 2 | |
//5. When the guess is correct, report how many guesses it took. | |
type GameState = { | |
Target:int; | |
GuessCount:int; | |
LastGuess:int option} | |
let generateInitialState () :GameState = | |
let random = new System.Random(); | |
{Target = random.Next(100) + 1; | |
GuessCount = 0; | |
LastGuess = None} | |
let gameState = ref (generateInitialState()) | |
let reportGuessStatus (target:int) (guess:int) : bool = | |
if target > guess then | |
TextWindow.WriteLine (Primitive("Too Low!")) | |
false | |
elif target < guess then | |
TextWindow.WriteLine (Primitive("Too High!")) | |
false | |
else | |
TextWindow.WriteLine (Primitive("Correct!")) | |
true | |
let readNextGuess () :int = | |
TextWindow.WriteLine(Primitive("Guess My Number (1-100)")) | |
let input = TextWindow.ReadNumber() | |
input |> int | |
let rec playGame (gameState:GameState) : unit = | |
match gameState.LastGuess with | |
| Some guess -> | |
if (gameState.Target, guess) ||> reportGuessStatus then | |
TextWindow.WriteLine(Primitive("You Win!")) | |
TextWindow.WriteLine(Primitive(gameState.GuessCount |> sprintf "You took %d guesses!")) | |
TextWindow.Read() | |
|> ignore | |
else | |
let nextGuess = readNextGuess () | |
{gameState with GuessCount = gameState.GuessCount + 1; LastGuess = nextGuess |> Some} | |
|> playGame | |
| None -> | |
let nextGuess = readNextGuess () | |
{gameState with GuessCount = gameState.GuessCount + 1; LastGuess = nextGuess |> Some} | |
|> playGame | |
let buttons = ref (Seq.empty<int * string>) | |
let onButtonClicked: SmallBasicCallback = | |
SmallBasicCallback(fun ()-> | |
let clickedButton = Controls.LastClickedButton |> string | |
let guess = | |
!buttons | |
|> Seq.find (fun (guess,name) -> name = clickedButton) | |
|> fst | |
if guess = (!gameState).Target then | |
GraphicsWindow.ShowMessage(Primitive(((!gameState).GuessCount + 1) |> sprintf "You took %d guesses!"), Primitive("You Win!")) | |
Program.End() | |
else | |
if guess < (!gameState).Target then | |
!buttons | |
|> Seq.filter(fun (number, name)-> number <= guess) | |
|> Seq.map snd | |
|> Seq.iter (fun name -> Controls.HideControl(Primitive(name))) | |
else | |
!buttons | |
|> Seq.filter(fun (number, name)-> number >= guess) | |
|> Seq.map snd | |
|> Seq.iter (fun name -> Controls.HideControl(Primitive(name))) | |
gameState := {!gameState with GuessCount = (!gameState).GuessCount + 1; LastGuess = guess |> Some} | |
()) | |
[<EntryPoint>] | |
let main argv = | |
let graphical = | |
if argv |> Array.length = 0 then | |
true | |
else | |
argv.[0].ToLower() <> "text" | |
if graphical then | |
GraphicsWindow.Title <- Primitive("Guess My Number (1 - 100)") | |
GraphicsWindow.CanResize <- Primitive(false) | |
GraphicsWindow.Width <- Primitive(640) | |
GraphicsWindow.Height <- Primitive(640) | |
buttons := | |
[for n in [0..99] do | |
let button = Controls.AddButton(Primitive((n+1) |> sprintf "%d"),Primitive(64 * (n % 10)),Primitive(64 * (n / 10))) | |
Controls.SetSize (button, Primitive(64), Primitive(64)) | |
yield (n + 1, button |> string)] | |
|> List.toSeq | |
Controls.add_ButtonClicked onButtonClicked | |
GraphicsWindow.Show() | |
else | |
TextWindow.Title <- Primitive("Guess My Number (1 - 100)") | |
TextWindow.Show() | |
generateInitialState() | |
|> playGame | |
0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment