...
1
2import uint from std::integer
3import uinteger from js::core
4import random from js::math
5import Document, Window, CanvasRenderingContext2D from w3c::dom
6import Element,HTMLCanvasElement, HTMLImageElement, MouseEvent from w3c::dom
7
8import model
9import view
10
11/**
12 * Add a given number of bombs to the board.
13 */
14method add_random_bombs(model::Board board, uint n) -> model::Board:
15 uinteger remaining = |board.squares|
16 // Use Knuth's algorithm S
17 for x in 0..board.width:
18 for y in 0..board.height:
19 // Flip a coin (so-to-speak)
20 if random(remaining) < n:
21 // create bomb square
22 model::Square s = model::HiddenSquare(true,false)
23 // Update board
24 board = model::set_square(board,(uint) x, (uint) y,s)
25 // Reduce number of bombs to place
26 n = n - 1
27 // Reduce remaining options
28 remaining = remaining - 1
29 // return updated board
30 return board
31
32/**
33 * Handle a mouse event on the canvas
34 */
35method onclick_handler(MouseEvent e, &view::State state, Window window):
36 // Convert from view to world coordinates
37 uint x = e->offsetX / state->gridsize
38 uint y = e->offsetY / state->gridsize
39 // Update board
40 if e->shiftKey:
41 state->board = model::flag_square(state->board,x,y)
42 else:
43 state->board = model::expose_square(state->board,x,y)
44 // Render initial board
45 view::draw_board(*state)
46 // Finally determine game status
47 (bool gameOver, bool winner) = model::is_gameover(state->board)
48 // Check whether game over
49 if gameOver:
50 // Yes, but win or lose?
51 if winner:
52 window->alert("Well done --- You Found all the Mines!")
53 else:
54 window->alert("Game Over --- You Lost!")
55 // Done
56
57/**
58 * Create a new game of Minesweeper
59 */
60public export method main(uint width, uint height, uint bombs, Window window, HTMLCanvasElement canvas, HTMLImageElement[] images)
61// Requires at least 9 images
62requires |images| == 13:
63 Document document = window->document
64 // NOTE: following should not be required!
65 Element c = document->getElementById("myCanvas")
66 // Create a standard sized board
67 model::Board board = model::Board(width,height)
68 // Add bombs
69 board = add_random_bombs(board,bombs)
70 // Initialise the view state
71 &view::State state = new view::init(document,canvas,board,images)
72 // Render initial board
73 view::draw_board(*state)
74 // Configure mouse click listener
75 c->addEventListener("click",&(MouseEvent e -> onclick_handler(e,state,window)))
76
View as plain text