Advertisement
ptrelford

Pacman Eats Ghosts

Sep 11th, 2013
419
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 22.34 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 = 0x00000000, 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 = 0x00000000, 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 = 0x00000000, 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 = 0x00000000, 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. let pr1 =
  87.     13, 13,
  88.     let A, B = 0x00000000, 0xFFFFFF00
  89.     [|
  90.     A; A; A; A; B; B; B; B; B; A; A; A; A
  91.     A; A; B; B; B; B; B; B; B; B; B; A; A
  92.     A; B; B; B; B; B; B; B; B; B; B; B; A
  93.     A; B; B; B; B; B; B; B; B; B; B; A; A
  94.     B; B; B; B; B; B; B; B; B; A; A; A; A
  95.     B; B; B; B; B; B; B; A; A; A; A; A; A
  96.     B; B; B; B; B; B; A; A; A; A; A; A; A
  97.     B; B; B; B; B; B; B; A; A; A; A; A; A
  98.     B; B; B; B; B; B; B; B; B; A; A; A; A
  99.     A; B; B; B; B; B; B; B; B; B; B; A; A
  100.     A; B; B; B; B; B; B; B; B; B; B; B; A
  101.     A; A; B; B; B; B; B; B; B; B; B; A; A
  102.     A; A; A; A; B; B; B; B; B; A; A; A; A
  103.     |]
  104. let pr2 =
  105.     13, 13,
  106.     let A, B = 0x0, 0xFFFFFF00
  107.     [|
  108.     A; A; A; A; B; B; B; B; B; A; A; A; A
  109.     A; A; B; B; B; B; B; B; B; B; B; A; A
  110.     A; B; B; B; B; B; B; B; B; B; B; B; A
  111.     A; B; B; B; B; B; B; B; B; B; B; B; A
  112.     B; B; B; B; B; B; B; B; B; B; B; B; B
  113.     B; B; B; B; B; B; B; B; B; A; A; A; A
  114.     B; B; B; B; B; B; A; A; A; A; A; A; A
  115.     B; B; B; B; B; B; B; B; B; A; A; A; A
  116.     B; B; B; B; B; B; B; B; B; B; B; B; B
  117.     A; B; B; B; B; B; B; B; B; B; B; B; A
  118.     A; B; B; B; B; B; B; B; B; B; B; B; A
  119.     A; A; B; B; B; B; B; B; B; B; B; A; A
  120.     A; A; A; A; B; B; B; B; B; A; A; A; A
  121.     |]
  122. let pl1 =
  123.     13, 13,
  124.     let A, B = 0x0, 0xFFFFFF00
  125.     [|
  126.     A; A; A; A; B; B; B; B; B; A; A; A; A
  127.     A; A; B; B; B; B; B; B; B; B; B; A; A
  128.     A; B; B; B; B; B; B; B; B; B; B; B; A
  129.     A; A; B; B; B; B; B; B; B; B; B; B; A
  130.     A; A; A; A; B; B; B; B; B; B; B; B; B
  131.     A; A; A; A; A; A; B; B; B; B; B; B; B
  132.     A; A; A; A; A; A; A; B; B; B; B; B; B
  133.     A; A; A; A; A; A; B; B; B; B; B; B; B
  134.     A; A; A; A; B; B; B; B; B; B; B; B; B
  135.     A; A; B; B; B; B; B; B; B; B; B; B; A
  136.     A; B; B; B; B; B; B; B; B; B; B; B; A
  137.     A; A; B; B; B; B; B; B; B; B; B; A; A
  138.     A; A; A; A; B; B; B; B; B; A; A; A; A
  139.     |]
  140. let pl2 =
  141.     13, 13,
  142.     let A, B = 0x0, 0xFFFFFF00
  143.     [|
  144.     A; A; A; A; B; B; B; B; B; A; A; A; A
  145.     A; A; B; B; B; B; B; B; B; B; B; A; A
  146.     A; B; B; B; B; B; B; B; B; B; B; B; A
  147.     A; B; B; B; B; B; B; B; B; B; B; B; A
  148.     B; B; B; B; B; B; B; B; B; B; B; B; B
  149.     A; A; A; A; B; B; B; B; B; B; B; B; B
  150.     A; A; A; A; A; A; A; B; B; B; B; B; B
  151.     A; A; A; A; B; B; B; B; B; B; B; B; B
  152.     B; B; B; B; B; B; B; B; B; B; B; B; B
  153.     A; B; B; B; B; B; B; B; B; B; B; B; A
  154.     A; B; B; B; B; B; B; B; B; B; B; B; A
  155.     A; A; B; B; B; B; B; B; B; B; B; A; A
  156.     A; A; A; A; B; B; B; B; B; A; A; A; A
  157.     |]
  158. let pu1 =
  159.     13, 13,
  160.     let A, B = 0x0, 0xFFFFFF00
  161.     [|
  162.     A; A; A; A; A; A; A; A; A; A; A; A; A
  163.     A; A; B; A; A; A; A; A; A; A; B; A; A
  164.     A; B; B; B; A; A; A; A; A; B; B; B; A
  165.     A; B; B; B; A; A; A; A; A; B; B; B; A
  166.     B; B; B; B; B; A; A; A; B; B; B; B; B
  167.     B; B; B; B; B; A; A; A; B; B; B; B; B
  168.     B; B; B; B; B; B; A; B; B; B; B; B; B
  169.     B; B; B; B; B; B; B; B; B; B; B; B; B
  170.     B; B; B; B; B; B; B; B; B; B; B; B; B
  171.     A; B; B; B; B; B; B; B; B; B; B; B; A
  172.     A; B; B; B; B; B; B; B; B; B; B; B; A
  173.     A; A; B; B; B; B; B; B; B; B; B; A; A
  174.     A; A; A; A; B; B; B; B; B; A; A; A; A
  175.     |]
  176. let pu2 =
  177.     13, 13,
  178.     let A, B = 0x0, 0xFFFFFF00
  179.     [|
  180.     A; A; A; A; B; A; A; A; B; A; A; A; A
  181.     A; A; B; B; B; A; A; A; B; B; B; A; A
  182.     A; B; B; B; B; A; A; A; B; B; B; B; A
  183.     A; B; B; B; B; A; A; A; B; B; B; B; A
  184.     B; B; B; B; B; B; A; B; B; B; B; B; B
  185.     B; B; B; B; B; B; A; B; B; B; B; B; B
  186.     B; B; B; B; B; B; A; B; B; B; B; B; B
  187.     B; B; B; B; B; B; B; B; B; B; B; B; B
  188.     B; B; B; B; B; B; B; B; B; B; B; B; B
  189.     A; B; B; B; B; B; B; B; B; B; B; B; A
  190.     A; B; B; B; B; B; B; B; B; B; B; B; A
  191.     A; A; B; B; B; B; B; B; B; B; B; A; A
  192.     A; A; A; A; B; B; B; B; B; A; A; A; A
  193.     |]
  194. let pd1 =
  195.     13, 13,
  196.     let A, B = 0x0, 0xFFFFFF00
  197.     [|
  198.     A; A; A; A; B; B; B; B; B; A; A; A; A
  199.     A; A; B; B; B; B; B; B; B; B; B; A; A
  200.     A; B; B; B; B; B; B; B; B; B; B; B; A
  201.     A; B; B; B; B; B; B; B; B; B; B; B; A
  202.     B; B; B; B; B; B; B; B; B; B; B; B; B
  203.     B; B; B; B; B; B; B; B; B; B; B; B; B
  204.     B; B; B; B; B; B; A; B; B; B; B; B; B
  205.     B; B; B; B; B; A; A; A; B; B; B; B; B
  206.     B; B; B; B; B; A; A; A; B; B; B; B; B
  207.     A; B; B; B; A; A; A; A; A; B; B; B; A
  208.     A; B; B; B; A; A; A; A; A; B; B; B; A
  209.     A; A; B; A; A; A; A; A; A; A; B; A; A
  210.     A; A; A; A; A; A; A; A; A; A; A; A; A
  211.     |]
  212. let pd2 =
  213.     13, 13,
  214.     let A, B = 0x0, 0xFFFFFF00
  215.     [|
  216.     A; A; A; A; B; B; B; B; B; A; A; A; A
  217.     A; A; B; B; B; B; B; B; B; B; B; A; A
  218.     A; B; B; B; B; B; B; B; B; B; B; B; A
  219.     A; B; B; B; B; B; B; B; B; B; B; B; A
  220.     B; B; B; B; B; B; B; B; B; B; B; B; B
  221.     B; B; B; B; B; B; B; B; B; B; B; B; B
  222.     B; B; B; B; B; B; A; B; B; B; B; B; B
  223.     B; B; B; B; B; B; A; B; B; B; B; B; B
  224.     B; B; B; B; B; B; A; B; B; B; B; B; B
  225.     A; B; B; B; B; A; A; A; B; B; B; B; A
  226.     A; B; B; B; B; A; A; A; B; B; B; B; A
  227.     A; A; B; B; B; A; A; A; B; B; B; A; A
  228.     A; A; A; A; B; A; A; A; B; A; A; A; A
  229.     |]
  230.  
  231. let blue =
  232.     14, 14,
  233.     let A, B, C = 0x0, 0xFF2121FF, 0xFFFFB8AE
  234.     [|
  235.     A; A; A; A; A; B; B; B; B; A; A; A; A; A
  236.     A; A; A; B; B; B; B; B; B; B; B; A; A; A
  237.     A; A; B; B; B; B; B; B; B; B; B; B; A; A
  238.     A; B; B; B; B; B; B; B; B; B; B; B; B; A
  239.     A; B; B; B; B; B; B; B; B; B; B; B; B; A
  240.     A; B; B; B; C; C; B; B; C; C; B; B; B; A
  241.     B; B; B; B; C; C; B; B; C; C; B; B; B; B
  242.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  243.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  244.     B; B; C; C; B; B; C; C; B; B; C; C; B; B
  245.     B; C; B; B; C; C; B; B; C; C; B; B; C; B
  246.     B; B; B; B; B; B; B; B; B; B; B; B; B; B
  247.     B; B; A; B; B; B; A; A; B; B; B; A; B; B
  248.     B; A; A; A; B; B; A; A; B; B; A; A; A; B
  249.     |]
  250.  
  251. let maze = "\
  252. ##/------------7/------------7##,\
  253. ##|............|!............|##,\
  254. ##|./__7./___7.|!./___7./__7.|##,\
  255. ##|o|  !.|   !.|!.|   !.|  !o|##,\
  256. ##|.L--J.L---J.LJ.L---J.L--J.|##,\
  257. ##|..........................|##,\
  258. ##|./__7./7./______7./7./__7.|##,\
  259. ##|.L--J.|!.L--7/--J.|!.L--J.|##,\
  260. ##|......|!....|!....|!......|##,\
  261. ##L____7.|L__7 |! /__J!./____J##,\
  262. #######!.|/--J LJ L--7!.|#######,\
  263. #######!.|!          |!.|#######,\
  264. #######!.|! /__==__7 |!.|#######,\
  265. -------J.LJ |      ! LJ.L-------,\
  266. ########.   | **** !   .########,\
  267. _______7./7 |      ! /7./_______,\
  268. #######!.|! L______J |!.|#######,\
  269. #######!.|!          |!.|#######,\
  270. #######!.|! /______7 |!.|#######,\
  271. ##/----J.LJ L--7/--J LJ.L----7##,\
  272. ##|............|!............|##,\
  273. ##|./__7./___7.|!./___7./__7.|##,\
  274. ##|.L-7!.L---J.LJ.L---J.|/-J.|##,\
  275. ##|o..|!.......<>.......|!..o|##,\
  276. ##L_7.|!./7./______7./7.|!./_J##,\
  277. ##/-J.LJ.|!.L--7/--J.|!.LJ.L-7##,\
  278. ##|......|!....|!....|!......|##,\
  279. ##|./____JL__7.|!./__JL____7.|##,\
  280. ##|.L--------J.LJ.L--------J.|##,\
  281. ##|..........................|##,\
  282. ##L--------------------------J##".Split(',')
  283.  
  284. let pills =
  285.     maze |> Array.map (fun line ->
  286.         line.ToCharArray() |> Array.map (fun c -> c)
  287.     )
  288.  
  289. let tl = [|
  290.     0b00000000
  291.     0b00000000
  292.     0b00000000
  293.     0b00000000
  294.     0b00000011
  295.     0b00000100
  296.     0b00001000
  297.     0b00001000|]
  298. let top = [|
  299.     0b00000000
  300.     0b00000000
  301.     0b00000000
  302.     0b00000000
  303.     0b11111111
  304.     0b00000000
  305.     0b00000000
  306.     0b00000000|]
  307. let tr = [|
  308.     0b00000000
  309.     0b00000000
  310.     0b00000000
  311.     0b00000000
  312.     0b11000000
  313.     0b00100000
  314.     0b00010000
  315.     0b00010000|]
  316. let left = [|
  317.     0b00001000
  318.     0b00001000
  319.     0b00001000
  320.     0b00001000
  321.     0b00001000
  322.     0b00001000
  323.     0b00001000
  324.     0b00001000|]
  325. let blank = [|
  326.     0b00000000
  327.     0b00000000
  328.     0b00000000
  329.     0b00000000
  330.     0b00000000
  331.     0b00000000
  332.     0b00000000
  333.     0b00000000|]
  334. let right = [|
  335.     0b00010000
  336.     0b00010000
  337.     0b00010000
  338.     0b00010000
  339.     0b00010000
  340.     0b00010000
  341.     0b00010000
  342.     0b00010000|]
  343. let bl = [|
  344.     0b00001000
  345.     0b00001000
  346.     0b00000100
  347.     0b00000011
  348.     0b00000000
  349.     0b00000000
  350.     0b00000000
  351.     0b00000000|]
  352. let bottom = [|
  353.     0b00000000
  354.     0b00000000
  355.     0b00000000
  356.     0b11111111
  357.     0b00000000
  358.     0b00000000
  359.     0b00000000
  360.     0b00000000|]
  361. let br = [|
  362.     0b00010000
  363.     0b00010000
  364.     0b00100000
  365.     0b11000000
  366.     0b00000000
  367.     0b00000000
  368.     0b00000000
  369.     0b00000000|]
  370. let door = [|
  371.     0b00000000
  372.     0b00000000
  373.     0b00000000
  374.     0b00000000
  375.     0b11111111
  376.     0b00000000
  377.     0b00000000
  378.     0b00000000|]
  379. let pill = [|
  380.     0b00000000
  381.     0b00000000
  382.     0b00000000
  383.     0b00011000
  384.     0b00011000
  385.     0b00000000
  386.     0b00000000
  387.     0b00000000|]
  388. let power = [|
  389.     0b00000000
  390.     0b00011000
  391.     0b00111100
  392.     0b01111110
  393.     0b01111110
  394.     0b00111100
  395.     0b00011000
  396.     0b00000000|]
  397.  
  398. type Brush = Blue | Yellow
  399.  
  400. let toTile c =
  401.     match c with  
  402.     | '=' -> door, Blue
  403.     | '_' -> top, Blue
  404.     | '|' -> left, Blue
  405.     | '!' -> right, Blue
  406.     | '/' -> tl, Blue
  407.     | '7' -> tr, Blue
  408.     | 'L' -> bl, Blue
  409.     | 'J' -> br, Blue
  410.     | '-' -> bottom, Blue
  411.     | '.' -> pill, Yellow
  412.     | 'o' -> power, Yellow
  413.     | _ -> blank, Blue
  414.  
  415. let isWall x=
  416.     match x with
  417.     | '_' | '|' | '!' | '/' | '7' | 'L' | 'J' | '-' | '*' -> true
  418.     | _ -> false
  419.  
  420. let tileAt (x,y) =
  421.     if x < 0 then ' '
  422.     elif x > 30 then ' '
  423.     else maze.[y].[x]
  424.        
  425. let isWallAt (x,y) = tileAt(x,y) |> isWall
  426.  
  427. [<JSEmit("return {0} << {1};")>]
  428. let ShiftLeft(x:int,n:int) : int = failwith "never"
  429.  
  430. [<JSEmit("return {0} >> {1};")>]
  431. let ShiftRight(x:int,n:int) : int = failwith "never"
  432.  
  433. [<JSEmit("return {0} & {1};")>]
  434. let And(a:int,b:int) : int = failwith "never"
  435.  
  436. let draw f (lines:int[]) =
  437.     let width = 8
  438.     lines |> Array.iteri (fun y line ->
  439.         for x = 0 to width-1 do
  440.             let bit = ShiftLeft(1, width - 1 - x)
  441.             let pattern = And(line,bit)
  442.             if pattern <> 0 then f (x,y)
  443.     )
  444.  
  445. let part x n =
  446.     let bits = ShiftRight(x,n)      
  447.     let byte = And(bits, 255)
  448.     float byte
  449.  
  450. let createImage (width, height, pixels) =
  451.     let layer = unbox<ts.HTMLCanvasElement>(ts.document.createElement("canvas"))  
  452.     layer.width <- float width
  453.     layer.height <- float height
  454.     let context = layer.getContext("2d")    
  455.     let id = context.createImageData(float width,float height)
  456.     let d = id.data
  457.     pixels |> Array.iteri (fun i pixel ->
  458.             let x = i * 4
  459.             d.[x+0] <- part pixel 16
  460.             d.[x+1] <- part pixel 8
  461.             d.[x+2] <- part pixel 0
  462.             d.[x+3] <- part pixel 24
  463.         )
  464.     context.putImageData(id,0.,0.)
  465.     let image = unbox<ts.HTMLImageElement>(ts.document.createElement("image"))  
  466.     image.src <- layer.toDataURL()
  467.     unbox<ts.HTMLElement>(image)
  468.  
  469. type Plotter(context:ts.CanvasRenderingContext2D) =
  470.     member __.createBrush(r,g,b,a) =
  471.         let id = context.createImageData(float 1,float 1)
  472.         let d = id.data
  473.         d.[0] <- float r; d.[1] <- float g; d.[2] <- float b; d.[3] <- float a
  474.         id
  475.     member __.plot(brush,x,y) =
  476.         context.putImageData(brush, float x, float y)          
  477.  
  478. let createBackground () =
  479.     let background = unbox<ts.HTMLCanvasElement>(ts.document.createElement("canvas"))  
  480.     background.width <- 256.
  481.     background.height <- 256.    
  482.     let context = background.getContext("2d")
  483.     context.fillStyle <- "rgb(0,0,0)"
  484.     context.fillRect (0., 0. , 256., 256.);
  485.     let plotter = Plotter(context)
  486.     let blue = plotter.createBrush (63,63,255,255)
  487.     let yellow = plotter.createBrush (255,255,0,255)
  488.     let lines = maze      
  489.     for y = 0 to lines.Length-1 do
  490.         let line = lines.[y]
  491.         for x = 0 to line.Length-1 do
  492.             let c = line.[x]
  493.             let tile, color = toTile c                
  494.             let brush = match color with Blue -> blue | Yellow -> yellow        
  495.             let f (x',y') = plotter.plot(brush, x*8 + x', y*8 + y')
  496.             draw f tile
  497.     unbox<ts.HTMLElement>(background)
  498.  
  499. let clearCell background (x,y) =    
  500.     let background = unbox<ts.HTMLCanvasElement>(background)
  501.     let context = background.getContext("2d")
  502.     let plotter = Plotter(context)
  503.     let black = plotter.createBrush (0,0,0,255)
  504.     for y' = 0 to 7 do
  505.        for x' = 0 to 7 do                  
  506.             plotter.plot(black, x*8 + x', y*8 + y')        
  507.  
  508. let noWall (x,y) (ex,ey) =
  509.     let bx, by = ShiftRight(x+6+ex,3), ShiftRight(y+6+ey,3)
  510.     isWallAt (bx,by) |> not
  511.  
  512. let verticallyAligned (x,y) =  (x % 8) = 5
  513. let horizontallyAligned (x,y) = (y % 8) = 5
  514. let isAligned n = (n % 8) = 5
  515.  
  516. let canGoUp (x,y) = isAligned x && noWall (x,y) (0,-4)
  517. let canGoDown (x,y) = isAligned x && noWall (x,y) (0,5)
  518. let canGoLeft (x,y) = isAligned y && noWall (x,y) (-4,0)
  519. let canGoRight (x,y) = isAligned y && noWall (x,y) (5,0)
  520.  
  521. let wrap (x,y) (dx,dy) =
  522.     let x =
  523.         if dx = -1 && x = 0 then 30 * 8
  524.         elif dx = 1  && x = 30 *8 then 0
  525.         else x
  526.     x + dx, y + dy
  527.  
  528. type Ghost(image:ts.HTMLElement,x,y,v) =
  529.     let mutable x' = x
  530.    let mutable y' = y
  531.     let mutable v' = v    
  532.    member val Image = image
  533.    member __.X = x'
  534.     member __.Y = y'
  535.    member __.V = v'
  536.     member ghost.Reset() =
  537.         x' <- x
  538.        y' <- y
  539.     member ghost.Move(v) =
  540.         v' <- v        
  541.        let dx,dy = v
  542.        let x,y = wrap (x',y') (dx,dy)
  543.        x' <- x
  544.         y' <- y
  545.  
  546. let chooseDirection (ghost:Ghost) =
  547.    let x,y = ghost.X, ghost.Y
  548.    let dx,dy = ghost.V
  549.    let isBackwards (a,b) =
  550.        (a <> 0 && a = -dx) || (b <> 0 && b = -dy)
  551.    let directions =
  552.        [|canGoLeft(x,y),(-1,0)
  553.          canGoDown(x,y),(0,1)
  554.          canGoRight(x,y),(1,0)
  555.          canGoUp(x,y),(0,-1)|]
  556.        |> Array.filter fst
  557.        |> Array.map snd
  558.        |> Array.filter (not << isBackwards)        
  559.    let i = int (ts.Math.floor(ts.Math.random() * float directions.Length))
  560.    let dx,dy = directions.[i]
  561.    dx,dy
  562.  
  563. let createGhosts context =
  564.    [|
  565.         redd, (16, 11), (1,0)
  566.         cyand, (14, 15), (1,0)
  567.         pinkd, (16, 13), (0,-1)
  568.         oranged, (18, 15), (-1,0)
  569.    |]
  570.    |> Array.map (fun (data,(x,y),v) ->
  571.        let image = createImage data
  572.        Ghost(image, (x*8)-7, (y*8)-3, v)
  573.    )
  574.  
  575. type Keys() =
  576.    let leftCode, upCode, rightCode, downCode = 90(*z*), 81(*q*), 88(*x*), 65(*a*)
  577.    let mutable isLeft = false
  578.    let mutable isUp = false
  579.    let mutable isDown = false
  580.    let mutable isRight = false
  581.    member keys.Update (e:ts.KeyboardEventExtensions,pressed) =
  582.        let keyCode = int e.keyCode        
  583.        if keyCode = leftCode then isLeft <- pressed
  584.        if keyCode = rightCode then isRight <- pressed
  585.        if keyCode = upCode then isUp <- pressed
  586.        if keyCode = downCode then isDown <- pressed          
  587.    member keys.LeftPressed = isLeft
  588.    member keys.RightPressed = isRight
  589.    member keys.UpPressed = isUp
  590.    member keys.DownPressed = isDown
  591.  
  592. let bindKeys (keys:Keys) =
  593.    ts.addEventListener("keydown", unbox<ts.EventListener>(fun e ->
  594.        let e = (unbox<ts.KeyboardEventExtensions>(e))
  595.        keys.Update(e, true)
  596.        )
  597.    )
  598.    ts.addEventListener("keyup", unbox<ts.EventListener>(fun e ->
  599.            let e = (unbox<ts.KeyboardEventExtensions>(e))
  600.            keys.Update(e,false)
  601.        )
  602.    )  
  603.  
  604. let main() =  
  605.    let keys = Keys()
  606.    bindKeys keys
  607.  
  608.    let canvas = unbox<ts.HTMLCanvasElement>(ts.document.getElementById("canvas"))
  609.    canvas.width <- 256.
  610.    canvas.height <- 256.    
  611.    let context = canvas.getContext("2d")
  612.    context.fillStyle <- "rgb(0,0,0)"
  613.    context.fillRect (0., 0. , 256., 256.);
  614.  
  615.    let background = createBackground()
  616.    let ghosts = createGhosts(context)
  617.    let pu1, pu2 = createImage pu1, createImage pu2
  618.    let pd1, pd2 = createImage pd1, createImage pd2
  619.    let pl1, pl2 = createImage pl1, createImage pl2
  620.    let pr1, pr2 = createImage pr1, createImage pr2
  621.    let blue = createImage blue
  622.  
  623.    let score = ref 0
  624.    let flashCountdown = ref 0
  625.    let powerCountdown = ref 0
  626.    let x, y = ref (16 * 8 - 7), ref (23 * 8 - 3)
  627.    let v = ref (0,0)
  628.    let lastp = ref pr1
  629.  
  630.    let moveGhosts () =
  631.        ghosts |> Array.iter (fun ghost ->
  632.            let v = chooseDirection ghost
  633.            ghost.Move(v)
  634.        )
  635.  
  636.    let movePacman () =      
  637.        v :=
  638.            if keys.LeftPressed && canGoLeft(!x,!y) then (-1,0)
  639.            elif keys.RightPressed && canGoRight(!x,!y) then (1,0)
  640.            elif keys.UpPressed && canGoUp(!x,!y) then (0,-1)
  641.            elif keys.DownPressed && canGoDown(!x,!y) then (0,1)
  642.            else (0,0)        
  643.        let x',y' = wrap (!x,!y) !v
  644.        x := x'
  645.         y := y'
  646.  
  647.    let eatPills () =
  648.        let tx = int (ts.Math.floor(float ((!x+6)/8)))      
  649.        let ty = int (ts.Math.floor(float ((!y+6)/8)))      
  650.        let c = pills.[ty].[tx]
  651.        if c = '.' then
  652.            pills.[ty].[tx] <- ' '
  653.            clearCell background (tx,ty)
  654.            score := !score + 10
  655.        if c = 'o' then          
  656.            pills.[ty].[tx] <- ' '
  657.            clearCell background (tx,ty)
  658.            score := !score + 50
  659.            powerCountdown := 250
  660.  
  661.    let touchingGhosts () =
  662.        let px, py = !x, !y
  663.        ghosts |> Array.filter (fun ghost ->
  664.            let x,y = ghost.X, ghost.Y
  665.            ((px >= x && px < x + 13) ||
  666.             (x < px + 13 && x >= px)) &&
  667.            ((py >= y && py < y + 13) ||
  668.             (y < py + 13 && y >= py))
  669.        )
  670.  
  671.    let collisionDetection () =
  672.        let touched = touchingGhosts ()
  673.        if touched.Length > 0
  674.        then
  675.            if !powerCountdown > 0 then
  676.                touched |> Array.iter (fun ghost ->
  677.                    ghost.Reset()
  678.                    score := !score + 100
  679.                )
  680.            else
  681.                flashCountdown := 30
  682.        if !flashCountdown > 0
  683.        then flashCountdown := !flashCountdown - 1
  684.    
  685.    let logic () =
  686.        moveGhosts()
  687.        movePacman()
  688.        eatPills ()
  689.        if !powerCountdown > 0 then powerCountdown := !powerCountdown - 1
  690.        collisionDetection()
  691.  
  692.    let getPacmanImage () =
  693.        let p1, p2 =
  694.            match !v with
  695.            | -1,  0 -> pl1, pl2
  696.            |  1,  0 -> pr1, pr2
  697.            |  0, -1 -> pu1, pu2
  698.            |  0,  1 -> pd1, pd2
  699.            |  _,  _ -> !lastp, !lastp
  700.        let x' = int (ts.Math.floor(float (!x/6)))
  701.         let y' = int (ts.Math.floor(float (!y/6)))
  702.        if (x' + y') % 2 = 0 then p1 else p2
  703.  
  704.    let renderPacman () =
  705.        let p = getPacmanImage()
  706.        lastp := p
  707.        if !flashCountdown % 2 = 0
  708.        then context.drawImage(p, float !x, float !y)
  709.  
  710.    let renderGhosts () =
  711.        ghosts |> Array.iter (fun ghost ->
  712.            let image =
  713.                if !powerCountdown = 0
  714.                then ghost.Image
  715.                else blue
  716.            context.drawImage(image, float ghost.X, float ghost.Y)
  717.        )
  718.  
  719.    let renderScore () =
  720.        context.fillStyle <- "white"
  721.        context.font <- "bold 8px";
  722.        context.fillText("Score " + (!score).ToString(), 0., 255.)
  723.  
  724.    let render () =
  725.        context.drawImage(background, 0., 0.)
  726.        renderScore ()
  727.        renderPacman()
  728.        renderGhosts ()
  729.  
  730.    let rec update () =
  731.        render ()
  732.        logic ()
  733.        ts.setTimeout(update, 1000. / 60.) |> ignore
  734.  
  735.    update()
  736.  
  737. do Runtime.Run(directory="Web", components=Interop.Components.all)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement