2 people like it.

Times Table JS game

Simple times table browser based game., compiles to JavaScript via Pit (v0.1) (http://pitfw.posterous.com). Run: http://trelford.com/SevenSixes.htm

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
78: 
79: 
80: 
81: 
82: 
83: 
84: 
85: 
86: 
87: 
88: 
89: 
90: 
91: 
92: 
93: 
94: 
95: 
96: 
97: 
98: 
99: 
open Pit
open Pit.Dom
open Pit.Javascript

module App =
    (helper functions omitted)

    let rec [<Js>] start (root:DomElement) =
        let addButton (total:int) = 
            let button = 
                tag "input" 
                    ["type"@="submit";
                     "value"@="Play " + total.ToString();
                     "style"@="font-size:large;margin:4px"]
            button |> Event.click |> Event.add (fun _ -> countdown total root)
            root.AppendChild button
        addButton 5
        addButton 10
        addButton 20

    and [<Js>] countdown total (root:DomElement) =
        delay {
            root.InnerHTML <- "3"
            do! Delay 1000
            root.InnerHTML <- "2"
            do! Delay 1000
            root.InnerHTML <- "1"
            do! Delay 1000
            root.InnerHTML <- "Go"
            do! Delay 1000
            play total root
        }

    and [<Js>] play total (root:DomElement) =
        let started = Date().GetTime()
        let question = 
            tag "div" ["style"@="font-size:x-large;text-align:center"]
        let answer = 
            tag "input" 
                ["type"@="text";"size"@="3";
                 "style"@="width:100px;font-size:x-large;text-align:center"]
            |> DomInput.Of
        let showQuestion () =
            root.InnerHTML <- ""
            root.AppendChild question
            root.AppendChild answer
        showQuestion ()
        let expected, asked = ref 42, ref "7 x 6"
        let ask () = 
            let next () = Math.random() * 13.0 |> Math.floor |> int
            let a, b = next(), next()
            expected := a * b
            asked := a.ToString() + " x "  + b.ToString()
            question.InnerHTML <- !asked
            answer.Value <- ""
            answer.Focus()
        ask ()
        let count, score = ref 0, ref 0
        let toint (f:float) = int f
        answer
        |> Event.keydown 
        |> Event.filter (fun e -> e.KeyCode = 13 && JsString(answer.Value).Length > 0)
        |> Event.add (fun _ ->
            let value = answer.Value |> int
            let cont() =
                count := !count + 1
                if !count = total then
                    let finished = Date().GetTime()
                    let ms = float (finished - started)
                    let seconds = ms / 1000.0 |> toint
                    finish seconds !score !count root
                else ask()
            if value = !expected then
                score := !score + 1
                cont()
            else
                delay {
                    root.InnerHTML <- !asked + " = " + (!expected).ToString()
                    do! Delay 3000
                    showQuestion()
                    cont()
                }
        )

    and [<Js>] finish seconds score count (root:DomElement) =
        root.InnerHTML <- ""
        let div = tag "div" ["style"@="font-size:x-large;text-align:center"] 
        root.AppendChild div
        div.InnerHTML <- 
            score.ToString() + " / " + count.ToString() + 
            " in " + seconds.ToString() + "s"
        delay {
            do! Delay 10000
            root.InnerHTML <- ""
            start root
        }

    [<Js;DomEntryPoint>]
    let main () = document.GetElementById("maindiv") |> start
module App

from Script
type DomAttribute = { Name:string; Value:obj }
    let [<Js>] (@=) name (value:'a) =
        { Name=name; Value=box value }
    let [<Js>] tag name (attributes:DomAttribute list) =
        let el = document.CreateElement(name)
        for a in attributes do el.SetAttribute(a.Name,a.Value.ToString())
        el

    type Delay = Delay of int
    type DelayBuilder() =
        [<Js>] member x.Bind(Delay t, f:unit->unit) = window.SetTimeout(f, t) |> ignore
        [<Js>] member x.Return(t) = fun () -> t
        [<Js>] member x.Delay(f:unit->'a) = f()
        [<Js>] member x.Zero () = ()
    let [<Js>] delay = DelayBuilder()
val start : root:'a -> unit

Full name: Script.App.start
val root : 'a
val addButton : (int -> 'a)
val total : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val button : obj
val tag : name:'a -> attributes:DomAttribute list -> 'b

Full name: Script.App.tag
System.Int32.ToString() : string
System.Int32.ToString(provider: System.IFormatProvider) : string
System.Int32.ToString(format: string) : string
System.Int32.ToString(format: string, provider: System.IFormatProvider) : string
Multiple items
module Event

from Microsoft.FSharp.Control

--------------------
type Event<'T> =
  new : unit -> Event<'T>
  member Trigger : arg:'T -> unit
  member Publish : IEvent<'T>

Full name: Microsoft.FSharp.Control.Event<_>

--------------------
type Event<'Delegate,'Args (requires delegate and 'Delegate :> Delegate)> =
  new : unit -> Event<'Delegate,'Args>
  member Trigger : sender:obj * args:'Args -> unit
  member Publish : IEvent<'Delegate,'Args>

Full name: Microsoft.FSharp.Control.Event<_,_>

--------------------
new : unit -> Event<'T>

--------------------
new : unit -> Event<'Delegate,'Args>
val add : callback:('T -> unit) -> sourceEvent:IEvent<'Del,'T> -> unit (requires delegate and 'Del :> System.Delegate)

Full name: Microsoft.FSharp.Control.Event.add
val countdown : total:int -> root:'a -> unit

Full name: Script.App.countdown
val delay : DelayBuilder

Full name: Script.App.delay
Multiple items
union case Delay.Delay: int -> Delay

--------------------
type Delay = | Delay of int

Full name: Script.App.Delay
val play : total:int -> root:'a -> unit

Full name: Script.App.play
val started : int
val question : 'a
val answer : DomAttribute
val showQuestion : (unit -> 'a)
val expected : int ref
val asked : string ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val ask : (unit -> 'a)
val next : (unit -> int)
val floor : value:'T -> 'T (requires member Floor)

Full name: Microsoft.FSharp.Core.Operators.floor
val a : int
val b : int
DomAttribute.Value: obj
val count : int ref
val score : int ref
val toint : (float -> int)
val f : float
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
val filter : predicate:('T -> bool) -> sourceEvent:IEvent<'Del,'T> -> IEvent<'T> (requires delegate and 'Del :> System.Delegate)

Full name: Microsoft.FSharp.Control.Event.filter
val e : 'a
val value : int
val cont : (unit -> unit)
val finished : int
val ms : float
val seconds : int
val finish : seconds:int -> score:int -> count:int -> root:'a -> unit

Full name: Script.App.finish
val score : int
val count : int
val div : 'a
val main : unit -> unit

Full name: Script.App.main
Raw view New version

More information

Link:http://fssnip.net/9b
Posted:6 years ago
Author:Phillip Trelford
Tags: js , pit