Advertisement
ptrelford

Pacman Ghosts in FunScript

Sep 3rd, 2013
536
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 11.48 KB | None | 0 0
  1. [<ReflectedDefinition>]
  2. module Program
  3.  
  4. open FunScript
  5. open FunScript.TypeScript
  6.  
  7. type ts = Api<"../Typings/lib.d.ts">
  8.  
  9. let cyand =
  10.     14, 14,
  11.     let A, B, C, D = 0xFF000000, 0xFF00FFDE, 0xFFDEDEDE, 0xFF2121DE
  12.     [|
  13.     A; A; A; A; A; B; B; B; B; A; A; A; A; A
  14.     A; A; A; B; B; B; B; B; B; B; B; A; A; A
  15.     A; A; B; B; B; B; B; B; B; B; B; B; A; A
  16.     A; B; B; B; B; B; B; B; B; B; B; B; B; A
  17.     A; B; B; C; C; B; B; B; B; C; C; B; B; A
  18.     A; B; C; C; C; C; B; B; C; C; C; C; B; A
  19.     B; B; C; C; C; C; B; B; C; C; C; C; B; B
  20.     B; B; C; D; D; C; B; B; C; D; D; C; B; B
  21.     B; B; B; D; D; B; B; B; B; D; D; B; B; B
  22.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  23.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  24.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  25.     B; B; A; B; B; B; A; A; B; B; B; A; B; B
  26.     B; A; A; A; B; B; A; A; B; B; A; A; A; B
  27.     |]
  28. let oranged =
  29.     14, 14,
  30.     let A, B, C, D = 0xFF000000, 0xFFFFB847, 0xFFDEDEDE, 0xFF2121DE
  31.     [|
  32.     A; A; A; A; A; B; B; B; B; A; A; A; A; A
  33.     A; A; A; B; B; B; B; B; B; B; B; A; A; A
  34.     A; A; B; B; B; B; B; B; B; B; B; B; A; A
  35.     A; B; B; B; B; B; B; B; B; B; B; B; B; A
  36.     A; B; B; C; C; B; B; B; B; C; C; B; B; A
  37.     A; B; C; C; C; C; B; B; C; C; C; C; B; A
  38.     B; B; C; C; C; C; B; B; C; C; C; C; B; B
  39.     B; B; C; D; D; C; B; B; C; D; D; C; B; B
  40.     B; B; B; D; D; B; B; B; B; D; D; B; B; B
  41.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  42.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  43.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  44.     B; B; A; B; B; B; A; A; B; B; B; A; B; B
  45.     B; A; A; A; B; B; A; A; B; B; A; A; A; B
  46.     |]
  47. let pinkd =
  48.     14, 14,
  49.     let A, B, C, D = 0xFF000000, 0xFFFFB8DE, 0xFFDEDEDE, 0xFF2121DE
  50.     [|
  51.     A; A; A; A; A; B; B; B; B; A; A; A; A; A
  52.     A; A; A; B; B; B; B; B; B; B; B; A; A; A
  53.     A; A; B; B; B; B; B; B; B; B; B; B; A; A
  54.     A; B; B; B; B; B; B; B; B; B; B; B; B; A
  55.     A; B; B; C; C; B; B; B; B; C; C; B; B; A
  56.     A; B; C; C; C; C; B; B; C; C; C; C; B; A
  57.     B; B; C; C; C; C; B; B; C; C; C; C; B; B
  58.     B; B; C; D; D; C; B; B; C; D; D; C; B; B
  59.     B; B; B; D; D; B; B; B; B; D; D; B; B; B
  60.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  61.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  62.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  63.     B; B; A; B; B; B; A; A; B; B; B; A; B; B
  64.     B; A; A; A; B; B; A; A; B; B; A; A; A; B
  65.     |]
  66. let redd =
  67.     14, 14,
  68.     let A, B, C, D = 0xFF000000, 0xFFFF0000, 0xFFDEDEDE, 0xFF2121DE
  69.     [|
  70.     A; A; A; A; A; B; B; B; B; A; A; A; A; A
  71.     A; A; A; B; B; B; B; B; B; B; B; A; A; A
  72.     A; A; B; B; B; B; B; B; B; B; B; B; A; A
  73.     A; B; B; B; B; B; B; B; B; B; B; B; B; A
  74.     A; B; B; C; C; B; B; B; B; C; C; B; B; A
  75.     A; B; C; C; C; C; B; B; C; C; C; C; B; A
  76.     B; B; C; C; C; C; B; B; C; C; C; C; B; B
  77.     B; B; C; D; D; C; B; B; C; D; D; C; B; B
  78.     B; B; B; D; D; B; B; B; B; D; D; B; B; B
  79.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  80.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  81.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  82.     B; B; A; B; B; B; A; A; B; B; B; A; B; B
  83.     B; A; A; A; B; B; A; A; B; B; A; A; A; B
  84.     |]
  85.  
  86.  
  87. let maze = "\
  88. ##/------------7/------------7##,\
  89. ##|............|!............|##,\
  90. ##|./__7./___7.|!./___7./__7.|##,\
  91. ##|o|  !.|   !.|!.|   !.|  !o|##,\
  92. ##|.L--J.L---J.LJ.L---J.L--J.|##,\
  93. ##|..........................|##,\
  94. ##|./__7./7./______7./7./__7.|##,\
  95. ##|.L--J.|!.L--7/--J.|!.L--J.|##,\
  96. ##|......|!....|!....|!......|##,\
  97. ##L____7.|L__7 |! /__J!./____J##,\
  98. #######!.|/--J LJ L--7!.|#######,\
  99. #######!.|!          |!.|#######,\
  100. #######!.|! /__==__7 |!.|#######,\
  101. -------J.LJ |      ! LJ.L-------,\
  102. ########.   | **** !   .########,\
  103. _______7./7 |      ! /7./_______,\
  104. #######!.|! L______J |!.|#######,\
  105. #######!.|!          |!.|#######,\
  106. #######!.|! /______7 |!.|#######,\
  107. ##/----J.LJ L--7/--J LJ.L----7##,\
  108. ##|............|!............|##,\
  109. ##|./__7./___7.|!./___7./__7.|##,\
  110. ##|.L-7!.L---J.LJ.L---J.|/-J.|##,\
  111. ##|o..|!.......<>.......|!..o|##,\
  112. ##L_7.|!./7./______7./7.|!./_J##,\
  113. ##/-J.LJ.|!.L--7/--J.|!.LJ.L-7##,\
  114. ##|......|!....|!....|!......|##,\
  115. ##|./____JL__7.|!./__JL____7.|##,\
  116. ##|.L--------J.LJ.L--------J.|##,\
  117. ##|..........................|##,\
  118. ##L--------------------------J##".Split(',')
  119.  
  120. let tl = [|
  121.     0b00000000
  122.     0b00000000
  123.     0b00000000
  124.     0b00000000
  125.     0b00000011
  126.     0b00000100
  127.     0b00001000
  128.     0b00001000|]
  129. let top = [|
  130.     0b00000000
  131.     0b00000000
  132.     0b00000000
  133.     0b00000000
  134.     0b11111111
  135.     0b00000000
  136.     0b00000000
  137.     0b00000000|]
  138. let tr = [|
  139.     0b00000000
  140.     0b00000000
  141.     0b00000000
  142.     0b00000000
  143.     0b11000000
  144.     0b00100000
  145.     0b00010000
  146.     0b00010000|]
  147. let left = [|
  148.     0b00001000
  149.     0b00001000
  150.     0b00001000
  151.     0b00001000
  152.     0b00001000
  153.     0b00001000
  154.     0b00001000
  155.     0b00001000|]
  156. let blank = [|
  157.     0b00000000
  158.     0b00000000
  159.     0b00000000
  160.     0b00000000
  161.     0b00000000
  162.     0b00000000
  163.     0b00000000
  164.     0b00000000|]
  165. let right = [|
  166.     0b00010000
  167.     0b00010000
  168.     0b00010000
  169.     0b00010000
  170.     0b00010000
  171.     0b00010000
  172.     0b00010000
  173.     0b00010000|]
  174. let bl = [|
  175.     0b00001000
  176.     0b00001000
  177.     0b00000100
  178.     0b00000011
  179.     0b00000000
  180.     0b00000000
  181.     0b00000000
  182.     0b00000000|]
  183. let bottom = [|
  184.     0b00000000
  185.     0b00000000
  186.     0b00000000
  187.     0b11111111
  188.     0b00000000
  189.     0b00000000
  190.     0b00000000
  191.     0b00000000|]
  192. let br = [|
  193.     0b00010000
  194.     0b00010000
  195.     0b00100000
  196.     0b11000000
  197.     0b00000000
  198.     0b00000000
  199.     0b00000000
  200.     0b00000000|]
  201. let door = [|
  202.     0b00000000
  203.     0b00000000
  204.     0b00000000
  205.     0b00000000
  206.     0b11111111
  207.     0b00000000
  208.     0b00000000
  209.     0b00000000|]
  210. let pill = [|
  211.     0b00000000
  212.     0b00000000
  213.     0b00000000
  214.     0b00011000
  215.     0b00011000
  216.     0b00000000
  217.     0b00000000
  218.     0b00000000|]
  219. let power = [|
  220.     0b00000000
  221.     0b00011000
  222.     0b00111100
  223.     0b01111110
  224.     0b01111110
  225.     0b00111100
  226.     0b00011000
  227.     0b00000000|]
  228.  
  229. type Brush = Blue | Yellow
  230.  
  231. let toTile c =
  232.     match c with  
  233.     | '=' -> door, Blue
  234.     | '_' -> top, Blue
  235.     | '|' -> left, Blue
  236.     | '!' -> right, Blue
  237.     | '/' -> tl, Blue
  238.     | '7' -> tr, Blue
  239.     | 'L' -> bl, Blue
  240.     | 'J' -> br, Blue
  241.     | '-' -> bottom, Blue
  242.     | '.' -> pill, Yellow
  243.     | 'o' -> power, Yellow
  244.     | _ -> blank, Blue
  245.  
  246. let isWall x=
  247.     match x with
  248.     | '_' | '|' | '!' | '/' | '7' | 'L' | 'J' | '-' | '*' -> true
  249.     | _ -> false
  250.  
  251. let tileAt (x,y) =
  252.     if x < 0 then ' '
  253.     elif x > 30 then ' '
  254.     else maze.[y].[x]
  255.        
  256. let isWallAt (x,y) = tileAt(x,y) |> isWall
  257.  
  258. [<JSEmit("return {0} << {1};")>]
  259. let ShiftLeft(x:int,n:int) : int = failwith "never"
  260.  
  261. [<JSEmit("return {0} >> {1};")>]
  262. let ShiftRight(x:int,n:int) : int = failwith "never"
  263.  
  264. [<JSEmit("return {0} & {1};")>]
  265. let And(a:int,b:int) : int = failwith "never"
  266.  
  267. let draw f (lines:int[]) =
  268.     let width = 8
  269.     lines |> Array.iteri (fun y line ->
  270.         let line = line
  271.         for x = 0 to width-1 do
  272.             let bit = ShiftLeft(1, width - 1 - x)
  273.             let pattern = And(line,bit)
  274.             if pattern <> 0 then f (x,y)
  275.     )
  276.  
  277. let part x n =
  278.     let bits = ShiftRight(x,n)      
  279.     let byte = And(bits, 255)
  280.     float byte
  281.  
  282. type Sprite(context:ts.CanvasRenderingContext2D, data) =
  283.     let width, height, pixels = data
  284.     let id = context.createImageData(float width,float height)
  285.     let d = id.data
  286.     do  pixels |> Array.iteri (fun i pixel ->
  287.             let x = i * 4
  288.             d.[x+0] <- part pixel 16
  289.             d.[x+1] <- part pixel 8
  290.             d.[x+2] <- part pixel 0
  291.             d.[x+3] <- part pixel 24
  292.         )
  293.     member sprite.Image = id
  294.     member sprite.Draw (x,y) =
  295.         context.putImageData(id, float x, float y)
  296.  
  297. type Plotter(context:ts.CanvasRenderingContext2D) =
  298.     member __.createBrush(r,g,b,a) =
  299.         let id = context.createImageData(float 1,float 1)
  300.         let d = id.data
  301.         d.[0] <- float r; d.[1] <- float g; d.[2] <- float b; d.[3] <- float a
  302.         id
  303.     member __.plot(brush,x,y) =
  304.         context.putImageData(brush, float x, float y)
  305.  
  306. let createBackground () =
  307.     let background = unbox<ts.HTMLCanvasElement>(ts.document.createElement("canvas"))
  308.     background.width <- 256.
  309.     background.height <- 256.
  310.     let context = background.getContext("2d")
  311.     context.fillStyle <- "rgb(0,0,0)"
  312.     context.fillRect (0., 0. , 256., 256.);
  313.     let plotter = Plotter(context)
  314.     let blue = plotter.createBrush (63,63,255,255)
  315.     let yellow = plotter.createBrush (255,255,0,255)
  316.     let lines = maze      
  317.     for y = 0 to lines.Length-1 do
  318.         let line = lines.[y]
  319.         for x = 0 to line.Length-1 do
  320.             let c = line.[x]
  321.             let tile, color = toTile c                
  322.             let brush = match color with Blue -> blue | Yellow -> yellow        
  323.             let f (x',y') = plotter.plot(brush, x*8 + x', y*8 + y')
  324.             draw f tile
  325.     background
  326.  
  327. let noWall (x,y) (ex,ey) =
  328.     let bx, by = ShiftRight(x+6+ex,3), ShiftRight(y+6+ey,3)
  329.     isWallAt (bx,by) |> not
  330.  
  331. let verticallyAligned (x,y) =  (x % 8) = 5
  332. let horizontallyAligned (x,y) = (y % 8) = 5
  333. let isAligned n = (n % 8) = 5
  334.  
  335. let canGoUp (x,y) = isAligned x && noWall (x,y) (0,-4)
  336. let canGoDown (x,y) = isAligned x && noWall (x,y) (0,5)
  337. let canGoLeft (x,y) = isAligned y && noWall (x,y) (-4,0)
  338. let canGoRight (x,y) = isAligned y && noWall (x,y) (5,0)
  339.  
  340. type Ghost(sprite:Sprite,x,y,v) =
  341.     let mutable x' = x
  342.    let mutable y' = y
  343.     let mutable v' = v
  344.    member val Sprite = sprite
  345.    member __.X = x'
  346.     member __.Y = y'
  347.    member __.V = v'
  348.     member __.Move(v) =
  349.         v' <- v
  350.        let dx,dy = v
  351.        let go (x,y) (dx,dy) =
  352.            let x =
  353.                if   dx = -1 && x = 0 then 30 * 8
  354.                elif dx = 1  && x = 30 *8 then 0
  355.                else x
  356.            x + dx, y + dy
  357.        let x,y = go (x',y') (dx,dy)
  358.        x' <- x
  359.         y' <- y
  360.  
  361. let createGhosts context =
  362.    [|
  363.         redd, (16, 11), (1,0)
  364.         cyand, (14, 15), (1,0)
  365.         pinkd, (16, 13), (0,-1)
  366.         oranged, (18, 15), (-1,0)
  367.    |]
  368.    |> Array.map (fun (data,(x,y),v) ->
  369.        let sprite = Sprite(context, data)
  370.        Ghost(sprite, (x*8)-7, (y*8)-3, v)
  371.    )
  372.  
  373. let main() =
  374.    let canvas = unbox<ts.HTMLCanvasElement>(ts.document.getElementById("canvas"))
  375.    canvas.width <- 512.
  376.    canvas.height <- 512.
  377.  
  378.    let context = canvas.getContext("2d")    
  379.    let background = createBackground()
  380.    let ghosts = createGhosts(context)
  381.  
  382.    let move (ghost:Ghost) =
  383.        let x,y = ghost.X, ghost.Y
  384.        let dx,dy = ghost.V
  385.        let isBackwards (a,b) =
  386.            (a <> 0 && a = -dx) || (b <> 0 && b = -dy)
  387.        let directions =
  388.            [|canGoLeft(x,y),(-1,0)
  389.              canGoDown(x,y),(0,1)
  390.              canGoRight(x,y),(1,0)
  391.              canGoUp(x,y),(0,-1)|]
  392.            |> Array.filter fst
  393.            |> Array.map snd
  394.            |> Array.filter (not << isBackwards)        
  395.        let i = int (ts.Math.floor(ts.Math.random() * float directions.Length))
  396.        let dx,dy = directions.[i]
  397.        ghost.Move(dx,dy)
  398.  
  399.    let rec update () =
  400.        let element = unbox<ts.HTMLElement>(background)
  401.        context.drawImage(element, 0., 0.)
  402.        ghosts |> Array.iter (fun ghost ->
  403.            move ghost
  404.            let sprite = ghost.Sprite
  405.            sprite.Draw(ghost.X, ghost.Y)
  406.        )
  407.        ts.setTimeout(update, 1000. / 60.) |> ignore
  408.  
  409.    update()
  410.  
  411. do Runtime.Run(directory="Web", components=Interop.Components.all)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement