Paintfuck

open System
open System.Windows
open System.Windows.Media.Imaging

let rec skipPrevious p c i =
    match p,i with
    | ']'::t, i -> skipPrevious t (']'::c) (i + 1) 
    | '['::t, 0 -> t, '['::c
    | '['::t, i -> skipPrevious t ('['::c) (i - 1)
    | h::t, i -> skipPrevious t (h::c) i

let rec skipNext p c i =
    match c,i with
    | '['::t, i -> skipNext ('['::p) t (i + 1)
    | ']'::t, 0 -> ']'::p, t
    | ']'::t, i -> skipNext (']'::p) t (i - 1)
    | h::t, i -> skipNext (h::p) t i

[<STAThread>]
[<EntryPoint>]
let main argv =
    let code = "*
    [[s*en]
    sw[w]enn
    [[e]w*ssss*nnnnw[w]ess[e]*[w]enn]
    ssss[*nnnn*essss]
    nnnnw[w]e
    ss]"

    let width = 1000
    let height = 500

    let image = Controls.Image(Stretch=Media.Stretch.Uniform)
    let format = Media.PixelFormats.Gray2
    let pixel = Array.create (width*height) 0uy
    let data:bool[,] = Array2D.zeroCreate height width

    let mutable x_ = 0
    let mutable y_ = 0
    let mutable pn_ = [], code.ToCharArray() |> Array.toList

    let rec fxx x y = function
        | (_, [])                -> ()
        | (p, h::t) when h = 'n' -> fxx ((x + height - 1) % height) y                         (h::p, t)
        | (p, h::t) when h = 'e' -> fxx x                           ((y + 1) % width)         (h::p, t)
        | (p, h::t) when h = 's' -> fxx ((x + 1) % height)          y                         (h::p, t)
        | (p, h::t) when h = 'w' -> fxx x                           ((y + width - 1) % width) (h::p, t)
        | (p, h::t) when h = '*' ->
            data.[x,y] <- not data.[x,y]

            data |> Seq.cast<bool> |> Seq.iteri (fun i x -> pixel.[i] <- if x then 255uy else 0uy)
            image.Source <- BitmapSource.Create(width, height, 1.0, 1.0, format, null, pixel, width)

            x_ <- x
            y_ <- y
            pn_ <- h::p, t
        | (p, h::t) when h = '[' && data.[x,y] -> fxx x y (h::p, t)
        | (p, h::t) when h = '[' -> fxx x y (skipNext (h::p) t 0)
        | (p, h::t) when h = ']' -> fxx x y (skipPrevious p (h::t) 0)
        | (p, h::t) -> fxx x y (h::p, t)

    Media.CompositionTarget.Rendering.Add (fun _ -> fxx x_ y_ pn_)

    Window(Content=image, Title="Paintfuck") |> (Application()).Run |> ignore
    0

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注