haha. it's cute. i never made a console game before. so that's how you make them

i'm learning F# myself so i took this as an exercise. the spec helped out a lot: [link:research.microsoft.com]

one thing i'm not sure of is whether or not it's necessary to closure a function within another function, or if the compiler automatically abstracts functions that don't change. eg:

1
2
3
4
5
let add1 =
    let add x y = x + y


    fun v -> add v 1

vs

1
2
3
4
5
6
let add1 v =


    let add x y = x + y

    add v 1

does the compiler notice that "add" is fully free and can be abstracted? i'm guessing it does. if so the former form isn't necessary, but it's a good idiom anyway in cases where you're using something expensive for the function but don't want to pollute the enclosing scope with it:

1
2
3
4
5
let fn =
    let expensive_val = expensive_calculation blah blah


    fun arg -> cheap_calculation expensive_val

anyway here's the code. you'll notice i'm not a fan of OO, but it should give you some ideas about the sorts of things you can do:

------------------------------------------------------------------------------------

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
#light


open System


let mapX = 40
let mapY = 20
let monsterCount = 35


Console.CursorVisible <- false
Console.SetWindowSize( mapX + 2, mapY + 2 )
Console.SetBufferSize( mapX + 2, mapY + 2 )


let move =
    let clamp max v =
        match v with // pat match with comparisons
        | _ when v < 1 -> 1
        | _ when v > max - 1 -> max - 1
        | _ -> v


    fun (x, y) (dx, dy) ->
        (clamp mapX (x + dx), clamp mapY (y + dy))


let rand: int * int -> int = Random().Next // function as value


let processPlayer player =
    let key = Console.ReadKey(true).Key;


    move player (match key with
    | ConsoleKey.UpArrow -> (0,-1)
    | ConsoleKey.DownArrow -> (0,1)
    | ConsoleKey.RightArrow -> (1,0)
    | ConsoleKey.LeftArrow -> (-1,0)
    | _ -> (0,0)) // match as expression


let processMonsters = Array.map (fun m -> move m (rand(-1,2), rand(-1,2))) // currying

   
let updateWorld player monsters =
    let player = processPlayer player
    let monsters = processMonsters monsters


    (player, monsters, monsters |> Array.exists ((=) player)) // currying


let drawChar col (c: char) (x, y) =
    Console.SetCursorPosition (x, y)
    Console.ForegroundColor <- col
    Console.Write(c)

       
let presentWorld =
    let draw = drawChar ConsoleColor.DarkGray '#' // currying


    fun player monsters ->
        Console.Clear()


        for i = 0 to mapX do
            draw (i, 0)
            draw (i, mapY)


        for i = 0 to mapY do
            draw (0, i)
            draw (mapX, i)


        drawChar ConsoleColor.White '@' player
        monsters |> Array.iter (drawChar ConsoleColor.Red 'm') // currying


let rec gameLoop player monsters turnCount =
    presentWorld player monsters
   

    match updateWorld player monsters with // pat match on return values
    | (player, monsters, false) -> gameLoop player monsters (turnCount + 1)
    | (player, monsters, true) -> Console.Clear()
                                  printfn "You survived for %d turns." turnCount


let player = (mapX / 2, mapY / 2)


let monsters = Array.init monsterCount (fun _ -> (rand(1, mapX), rand(1, mapY)))


gameLoop player monsters 1
By on 9/4/2008 5:59 AM ()

Dear amr,

thanks a lot for taking the time working with my mess and commenting your changes, I appreciate it very much.
I willl take a harder look at partial function application, as this seems to be a powerful abstraction mechanism.

Thanks again,
Bernhard

By on 9/4/2008 8:17 AM ()

Check out those blogs, there are some little F# games on it :
[link:monkeycoder.spaces.live.com]
[link:blogs.technet.com]

Russell

By on 9/10/2008 3:28 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper