uhlenheuerdotnet
programming, .NET, linux and others

F# - Playing Hangman

by Gregor Uhlenheuer on October 18, 2011

Today I made some effort to implement a very simple version of the game “Hangman” in F#. Even though I am already familiar with the general syntax of F# and do understand some basic functional programming styles I have to admit that it’s not that easy to get rid of usual iterative programming behaviors I am so used to.

Without further ado, this is what I came up with so far:

open System
open System.Text
open System.Text.RegularExpressions

/// Replace the non-guessed letters with an underscore
let replace (word : string) (letters : char list) =
    let sb = StringBuilder(word.Length)
    let contains c list = list |> List.exists (fun x -> x = c)
    word.ToCharArray()
    |> Array.iter (fun l -> sb.Append(if contains l letters then l else '_') |> ignore)
    sb.ToString()

/// Determine whether the word was guessed
let solved (word : string) =
    let rgx = Regex(@"^[^_]+$")
    rgx.IsMatch(word)

/// Start the Hangman game with a maximum number of attempts
/// and a given word to guess
let hangman max (word : string) =
    printfn "Hangman: %s" (replace word [])
    let rec hangman' attempts (word : string) (letters : char list) =
        if attempts = 0 then printfn "You lost the game"
        else
            printf "Attempts left %d: " attempts
            let input = Console.ReadKey(true).KeyChar
            let ls = input :: letters
            let rep = replace word ls
            if solved rep then
                printfn "%s" word
            else
                printfn "%s" rep
                hangman' (attempts-1) word ls
    hangman' max word []

I am pretty sure that there are much more elegant ways to implement this in F#. So if you have got any remarks or suggestions on how to improve this, I am very much interested in your opinion. So feel free to me.

By the way, I did program on my linux machine at home using MonoDevelop with the great F# bindings 1 mainly written by Tomas Petricek. Go check that out if you are running linux or MacOS - it does work very well especially regarding that it’s completely open-source.

This post is tagged with f#, .net and programming