Advertisement
Guest User

Untitled

a guest
Dec 12th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 6.44 KB | None | 0 0
  1. open System
  2. open System.Collections.Generic
  3.  
  4. // Pokemon Catch Simulator. Version 1.1
  5. // This program simulates how many Pokeballs it will take to catch a Pokemon.
  6. // In Pokemon, you are able to catch Pokemon you find in the wild and tame them.
  7.  
  8. // In the game, you simply throw a Pokeball and hope for the best. The Pokemon will enter the ball, shake three times,
  9. // and will display a message saying the Pokemon was caught... if you're lucky.
  10. // The odds of catching a Pokemon increase if the Pokemon's health is low, if it is afflicted with a status condition
  11. // such as sleep, paralysis, burn, etc. The odds of catching a Pokemon also depend on that specific Pokemon's catch rate.
  12. // I am specifically using this calculation here:
  13. // https://bulbapedia.bulbagarden.net/wiki/Catch_rate#Capture_method_.28Generation_III-IV.29
  14.  
  15. // ----------------------------------------------------------------------------
  16.  
  17. // BEGIN CITATION: This following code was authored by Tomas Petricek. This code snippet implements the "break" and "continue" keywords in F#.
  18. // Retrieved from http://tomasp.net/blog/imperative-ii-break.aspx/
  19.  
  20. type ImperativeResult<'T> =
  21.  | ImpValue of 'T
  22.   | ImpJump of int * bool
  23.   | ImpNone
  24.  
  25. type Imperative<'T> = unit -> ImperativeResult<'T>
  26.  
  27. type ImperativeBuilder() =
  28.   member x.Combine(a, b) = (fun () ->
  29.     match a() with
  30.     | ImpNone -> b()
  31.     | res -> res)
  32.   member x.Delay(f:unit -> Imperative<_>) = (fun () -> f()())
  33.   member x.Return(v) : Imperative<_> = (fun () -> ImpValue(v))
  34.   member x.Zero() = (fun () -> ImpNone)
  35.   member x.Run<'T>(imp) =
  36.    match imp() with
  37.    | ImpValue(v) -> v
  38.    | ImpJump _ -> failwith "Invalid use of break/continue!"
  39.    | _ when typeof<'T> = typeof<unit> -> Unchecked.defaultof<'T>
  40.    | _ -> failwith "No value has been returend!"
  41.  
  42.  
  43. // Add special Combine for loops and implement loops
  44. // Add Bind to enable using of break and continue
  45.  
  46. type ImperativeBuilder with
  47.  member x.CombineLoop(a, b) = (fun () ->
  48.    match a() with
  49.    | ImpValue(v) -> ImpValue(v)
  50.    | ImpJump(0, false) -> ImpNone
  51.    | ImpJump(0, true)
  52.    | ImpNone -> b()
  53.    | ImpJump(depth, b) -> ImpJump(depth - 1, b))
  54.  member x.For(inp:seq<_>, f) =
  55.    let rec loop(en:IEnumerator<_>) =
  56.      if not(en.MoveNext()) then x.Zero() else
  57.        x.CombineLoop(f(en.Current), x.Delay(fun () -> loop(en)))
  58.    loop(inp.GetEnumerator())
  59.  member x.While(gd, body) =
  60.    let rec loop() =
  61.      if not(gd()) then x.Zero() else
  62.        x.CombineLoop(body, x.Delay(fun () -> loop()))
  63.    loop()        
  64.  member x.Bind(v:Imperative<unit>, f : unit -> Imperative<_>) = (fun () ->
  65.    match v() with
  66.    | ImpJump(depth, kind) -> ImpJump(depth, kind)
  67.    | _ -> f()() )
  68.    
  69. let imperative = new ImperativeBuilder()  
  70. let break = (fun () -> ImpJump(0, false))
  71. let continue = (fun () -> ImpJump(0, true))
  72. let breakn(n) = (fun () -> ImpJump(n, false))
  73. let continuen(n) = (fun () -> ImpJump(n, true))
  74.  
  75. // END CITATION.
  76.  
  77. // ----------------------------------------------------------------------------
  78.  
  79.  
  80. let HPcurrent = 20.0 // The current health of the Pokemon.
  81. let HPmax = 180.0 // The maximum health the Pokemon can have.
  82. let ball = 1.0 // The type of Pokeball to be used (1 = standard Pokeball, 1.5 = Great Ball, 2 = Ultra Ball)
  83. let status = 1.5 // Status affliction of the Pokemon (1 = no affliction, 1.5 = poisoned/burned/paralyzed, 2 = asleep/frozen)
  84. let rate = 3.0 // the catch rate of the Pokemon (a value between 1 and 255)
  85.  
  86. // Do NOT mess with these:
  87. let mutable counter = 0 // this will be used to keep track of how many balls were used.
  88. let mutable caught = false // Boolean to keep track of whether or not the Pokemon is captured.
  89. let mutable a = (((3.0*HPmax - 2.0*HPcurrent) * rate * ball )/(3.0*HPmax)) * status // The calcuation of the modified catch rate given all the properties above.
  90. let b = Math.Floor (1048560.0 / sqrt (sqrt (16711680.0/a))) // Ball shake probability. It's actually supposed to floor every division and square root, but this will do.
  91. let mutable x = 0.0 // number that will be randomly generated
  92.  
  93.  
  94. // Display User-inputted information the program will run with.
  95. printfn "HP of Pokemon: %.0f/%.0f" HPcurrent HPmax
  96. if ball = 1.0 then printfn "Using Poke Ball."
  97. elif ball = 1.5 then printfn "Using Great Ball."
  98. elif ball = 2.0 then printfn "Using Ultra Ball."
  99. if status = 1.0 then printfn "Pokemon has no status affliction."
  100. elif status = 1.5 then printfn "Pokemon is paralyzed/burned/poisoned."
  101. elif status = 2.0 then printfn "Pokemon is asleep/frozen."
  102. printfn "Catch rate of Pokemon: %.0f" rate
  103. printfn "a = %.0f" a
  104. printfn "b = %.0f" b
  105. printfn "Press any key to begin..."
  106.  
  107. Console.ReadKey() |> ignore
  108.  
  109. let catch_the_monster() = imperative {
  110.     if HPcurrent <> 0.0 || HPmax <> 0.0 || ball <> 0.0 || status <> 0.0 || rate <> 0.0 then
  111.         if a < 1.0 then // if modified catch rate is less than 1, it is set to 1.
  112.             a <- 1.0
  113.         while not caught do
  114.             let rand = Random() // initialize RNG
  115.             for i in 0 .. 3 do //perform four shake checks
  116.                 x <- double (rand.Next(0,65535)) // pick a number between 1-65535
  117.                 printfn "Ball number %d / shake number %d / random number %.0f" counter i x
  118.                 if i = 0 && x >= b then // first shake check
  119.                     printfn "Oh no! The Pokemon broke free!"
  120.                     counter <- counter + 1
  121.                     do! break
  122.                 elif i = 1 && x >= b then // second shake check
  123.                     printfn "Aww! It appeared to be caught!"
  124.                     counter <- counter + 1
  125.                     do! break
  126.                 elif i = 2 && x >= b then // third shake check
  127.                     printfn "Aargh! Almost had it!"
  128.                     counter <- counter + 1
  129.                     do! break
  130.                 elif i = 3 && x >= b then // fails third shake check
  131.                     printfn "Shoot! It was so close, too!"
  132.                     counter <- counter + 1
  133.                     do! break
  134.                 elif i = 3 && x < b then // passes third shake check
  135.                     caught <- true
  136.                     printfn "Gotcha! The Pokemon was caught!"
  137.                     counter <- counter + 1
  138.         printfn "It was caught after %d balls" counter
  139.     else
  140.         printfn "Something doesn't seem right. Check the properties of the Pokemon. Make sure nothing is set to zero." }
  141. catch_the_monster()
  142.  
  143.  
  144. Console.ReadKey() |> ignore
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement