Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [<ReflectedDefinition>]
- module Program
- open FunScript
- open FunScript.TypeScript
- type ts = Api<"../Typings/lib.d.ts">
- let cyand =
- 14, 14,
- let A, B, C, D = 0xFF000000, 0xFF00FFDE, 0xFFDEDEDE, 0xFF2121DE
- [|
- A; A; A; A; A; B; B; B; B; A; A; A; A; A
- A; A; A; B; B; B; B; B; B; B; B; A; A; A
- A; A; B; B; B; B; B; B; B; B; B; B; A; A
- A; B; B; B; B; B; B; B; B; B; B; B; B; A
- A; B; B; C; C; B; B; B; B; C; C; B; B; A
- A; B; C; C; C; C; B; B; C; C; C; C; B; A
- B; B; C; C; C; C; B; B; C; C; C; C; B; B
- B; B; C; D; D; C; B; B; C; D; D; C; B; B
- B; B; B; D; D; B; B; B; B; D; D; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; A; B; B; B; A; A; B; B; B; A; B; B
- B; A; A; A; B; B; A; A; B; B; A; A; A; B
- |]
- let oranged =
- 14, 14,
- let A, B, C, D = 0xFF000000, 0xFFFFB847, 0xFFDEDEDE, 0xFF2121DE
- [|
- A; A; A; A; A; B; B; B; B; A; A; A; A; A
- A; A; A; B; B; B; B; B; B; B; B; A; A; A
- A; A; B; B; B; B; B; B; B; B; B; B; A; A
- A; B; B; B; B; B; B; B; B; B; B; B; B; A
- A; B; B; C; C; B; B; B; B; C; C; B; B; A
- A; B; C; C; C; C; B; B; C; C; C; C; B; A
- B; B; C; C; C; C; B; B; C; C; C; C; B; B
- B; B; C; D; D; C; B; B; C; D; D; C; B; B
- B; B; B; D; D; B; B; B; B; D; D; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; A; B; B; B; A; A; B; B; B; A; B; B
- B; A; A; A; B; B; A; A; B; B; A; A; A; B
- |]
- let pinkd =
- 14, 14,
- let A, B, C, D = 0xFF000000, 0xFFFFB8DE, 0xFFDEDEDE, 0xFF2121DE
- [|
- A; A; A; A; A; B; B; B; B; A; A; A; A; A
- A; A; A; B; B; B; B; B; B; B; B; A; A; A
- A; A; B; B; B; B; B; B; B; B; B; B; A; A
- A; B; B; B; B; B; B; B; B; B; B; B; B; A
- A; B; B; C; C; B; B; B; B; C; C; B; B; A
- A; B; C; C; C; C; B; B; C; C; C; C; B; A
- B; B; C; C; C; C; B; B; C; C; C; C; B; B
- B; B; C; D; D; C; B; B; C; D; D; C; B; B
- B; B; B; D; D; B; B; B; B; D; D; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; A; B; B; B; A; A; B; B; B; A; B; B
- B; A; A; A; B; B; A; A; B; B; A; A; A; B
- |]
- let redd =
- 14, 14,
- let A, B, C, D = 0xFF000000, 0xFFFF0000, 0xFFDEDEDE, 0xFF2121DE
- [|
- A; A; A; A; A; B; B; B; B; A; A; A; A; A
- A; A; A; B; B; B; B; B; B; B; B; A; A; A
- A; A; B; B; B; B; B; B; B; B; B; B; A; A
- A; B; B; B; B; B; B; B; B; B; B; B; B; A
- A; B; B; C; C; B; B; B; B; C; C; B; B; A
- A; B; C; C; C; C; B; B; C; C; C; C; B; A
- B; B; C; C; C; C; B; B; C; C; C; C; B; B
- B; B; C; D; D; C; B; B; C; D; D; C; B; B
- B; B; B; D; D; B; B; B; B; D; D; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; B; B; B; B; B; B; B; B; B; B; B; B
- B; B; A; B; B; B; A; A; B; B; B; A; B; B
- B; A; A; A; B; B; A; A; B; B; A; A; A; B
- |]
- let maze = "\
- ##/------------7/------------7##,\
- ##|............|!............|##,\
- ##|./__7./___7.|!./___7./__7.|##,\
- ##|o| !.| !.|!.| !.| !o|##,\
- ##|.L--J.L---J.LJ.L---J.L--J.|##,\
- ##|..........................|##,\
- ##|./__7./7./______7./7./__7.|##,\
- ##|.L--J.|!.L--7/--J.|!.L--J.|##,\
- ##|......|!....|!....|!......|##,\
- ##L____7.|L__7 |! /__J!./____J##,\
- #######!.|/--J LJ L--7!.|#######,\
- #######!.|! |!.|#######,\
- #######!.|! /__==__7 |!.|#######,\
- -------J.LJ | ! LJ.L-------,\
- ########. | **** ! .########,\
- _______7./7 | ! /7./_______,\
- #######!.|! L______J |!.|#######,\
- #######!.|! |!.|#######,\
- #######!.|! /______7 |!.|#######,\
- ##/----J.LJ L--7/--J LJ.L----7##,\
- ##|............|!............|##,\
- ##|./__7./___7.|!./___7./__7.|##,\
- ##|.L-7!.L---J.LJ.L---J.|/-J.|##,\
- ##|o..|!.......<>.......|!..o|##,\
- ##L_7.|!./7./______7./7.|!./_J##,\
- ##/-J.LJ.|!.L--7/--J.|!.LJ.L-7##,\
- ##|......|!....|!....|!......|##,\
- ##|./____JL__7.|!./__JL____7.|##,\
- ##|.L--------J.LJ.L--------J.|##,\
- ##|..........................|##,\
- ##L--------------------------J##".Split(',')
- let tl = [|
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000011
- 0b00000100
- 0b00001000
- 0b00001000|]
- let top = [|
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000
- 0b11111111
- 0b00000000
- 0b00000000
- 0b00000000|]
- let tr = [|
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000
- 0b11000000
- 0b00100000
- 0b00010000
- 0b00010000|]
- let left = [|
- 0b00001000
- 0b00001000
- 0b00001000
- 0b00001000
- 0b00001000
- 0b00001000
- 0b00001000
- 0b00001000|]
- let blank = [|
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000|]
- let right = [|
- 0b00010000
- 0b00010000
- 0b00010000
- 0b00010000
- 0b00010000
- 0b00010000
- 0b00010000
- 0b00010000|]
- let bl = [|
- 0b00001000
- 0b00001000
- 0b00000100
- 0b00000011
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000|]
- let bottom = [|
- 0b00000000
- 0b00000000
- 0b00000000
- 0b11111111
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000|]
- let br = [|
- 0b00010000
- 0b00010000
- 0b00100000
- 0b11000000
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000|]
- let door = [|
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00000000
- 0b11111111
- 0b00000000
- 0b00000000
- 0b00000000|]
- let pill = [|
- 0b00000000
- 0b00000000
- 0b00000000
- 0b00011000
- 0b00011000
- 0b00000000
- 0b00000000
- 0b00000000|]
- let power = [|
- 0b00000000
- 0b00011000
- 0b00111100
- 0b01111110
- 0b01111110
- 0b00111100
- 0b00011000
- 0b00000000|]
- type Brush = Blue | Yellow
- let toTile c =
- match c with
- | '=' -> door, Blue
- | '_' -> top, Blue
- | '|' -> left, Blue
- | '!' -> right, Blue
- | '/' -> tl, Blue
- | '7' -> tr, Blue
- | 'L' -> bl, Blue
- | 'J' -> br, Blue
- | '-' -> bottom, Blue
- | '.' -> pill, Yellow
- | 'o' -> power, Yellow
- | _ -> blank, Blue
- let isWall x=
- match x with
- | '_' | '|' | '!' | '/' | '7' | 'L' | 'J' | '-' | '*' -> true
- | _ -> false
- let tileAt (x,y) =
- if x < 0 then ' '
- elif x > 30 then ' '
- else maze.[y].[x]
- let isWallAt (x,y) = tileAt(x,y) |> isWall
- [<JSEmit("return {0} << {1};")>]
- let ShiftLeft(x:int,n:int) : int = failwith "never"
- [<JSEmit("return {0} >> {1};")>]
- let ShiftRight(x:int,n:int) : int = failwith "never"
- [<JSEmit("return {0} & {1};")>]
- let And(a:int,b:int) : int = failwith "never"
- let draw f (lines:int[]) =
- let width = 8
- lines |> Array.iteri (fun y line ->
- let line = line
- for x = 0 to width-1 do
- let bit = ShiftLeft(1, width - 1 - x)
- let pattern = And(line,bit)
- if pattern <> 0 then f (x,y)
- )
- let part x n =
- let bits = ShiftRight(x,n)
- let byte = And(bits, 255)
- float byte
- type Sprite(context:ts.CanvasRenderingContext2D, data) =
- let width, height, pixels = data
- let id = context.createImageData(float width,float height)
- let d = id.data
- do pixels |> Array.iteri (fun i pixel ->
- let x = i * 4
- d.[x+0] <- part pixel 16
- d.[x+1] <- part pixel 8
- d.[x+2] <- part pixel 0
- d.[x+3] <- part pixel 24
- )
- member sprite.Image = id
- member sprite.Draw (x,y) =
- context.putImageData(id, float x, float y)
- type Plotter(context:ts.CanvasRenderingContext2D) =
- member __.createBrush(r,g,b,a) =
- let id = context.createImageData(float 1,float 1)
- let d = id.data
- d.[0] <- float r; d.[1] <- float g; d.[2] <- float b; d.[3] <- float a
- id
- member __.plot(brush,x,y) =
- context.putImageData(brush, float x, float y)
- let createBackground () =
- let background = unbox<ts.HTMLCanvasElement>(ts.document.createElement("canvas"))
- background.width <- 256.
- background.height <- 256.
- let context = background.getContext("2d")
- context.fillStyle <- "rgb(0,0,0)"
- context.fillRect (0., 0. , 256., 256.);
- let plotter = Plotter(context)
- let blue = plotter.createBrush (63,63,255,255)
- let yellow = plotter.createBrush (255,255,0,255)
- let lines = maze
- for y = 0 to lines.Length-1 do
- let line = lines.[y]
- for x = 0 to line.Length-1 do
- let c = line.[x]
- let tile, color = toTile c
- let brush = match color with Blue -> blue | Yellow -> yellow
- let f (x',y') = plotter.plot(brush, x*8 + x', y*8 + y')
- draw f tile
- background
- let noWall (x,y) (ex,ey) =
- let bx, by = ShiftRight(x+6+ex,3), ShiftRight(y+6+ey,3)
- isWallAt (bx,by) |> not
- let verticallyAligned (x,y) = (x % 8) = 5
- let horizontallyAligned (x,y) = (y % 8) = 5
- let isAligned n = (n % 8) = 5
- let canGoUp (x,y) = isAligned x && noWall (x,y) (0,-4)
- let canGoDown (x,y) = isAligned x && noWall (x,y) (0,5)
- let canGoLeft (x,y) = isAligned y && noWall (x,y) (-4,0)
- let canGoRight (x,y) = isAligned y && noWall (x,y) (5,0)
- type Ghost(sprite:Sprite,x,y,v) =
- let mutable x' = x
- let mutable y' = y
- let mutable v' = v
- member val Sprite = sprite
- member __.X = x'
- member __.Y = y'
- member __.V = v'
- member __.Move(v) =
- v' <- v
- let dx,dy = v
- let go (x,y) (dx,dy) =
- let x =
- if dx = -1 && x = 0 then 30 * 8
- elif dx = 1 && x = 30 *8 then 0
- else x
- x + dx, y + dy
- let x,y = go (x',y') (dx,dy)
- x' <- x
- y' <- y
- let createGhosts context =
- [|
- redd, (16, 11), (1,0)
- cyand, (14, 15), (1,0)
- pinkd, (16, 13), (0,-1)
- oranged, (18, 15), (-1,0)
- |]
- |> Array.map (fun (data,(x,y),v) ->
- let sprite = Sprite(context, data)
- Ghost(sprite, (x*8)-7, (y*8)-3, v)
- )
- let main() =
- let canvas = unbox<ts.HTMLCanvasElement>(ts.document.getElementById("canvas"))
- canvas.width <- 512.
- canvas.height <- 512.
- let context = canvas.getContext("2d")
- let background = createBackground()
- let ghosts = createGhosts(context)
- let move (ghost:Ghost) =
- let x,y = ghost.X, ghost.Y
- let dx,dy = ghost.V
- let isBackwards (a,b) =
- (a <> 0 && a = -dx) || (b <> 0 && b = -dy)
- let directions =
- [|canGoLeft(x,y),(-1,0)
- canGoDown(x,y),(0,1)
- canGoRight(x,y),(1,0)
- canGoUp(x,y),(0,-1)|]
- |> Array.filter fst
- |> Array.map snd
- |> Array.filter (not << isBackwards)
- let i = int (ts.Math.floor(ts.Math.random() * float directions.Length))
- let dx,dy = directions.[i]
- ghost.Move(dx,dy)
- let rec update () =
- let element = unbox<ts.HTMLElement>(background)
- context.drawImage(element, 0., 0.)
- ghosts |> Array.iter (fun ghost ->
- move ghost
- let sprite = ghost.Sprite
- sprite.Draw(ghost.X, ghost.Y)
- )
- ts.setTimeout(update, 1000. / 60.) |> ignore
- update()
- do Runtime.Run(directory="Web", components=Interop.Components.all)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement