import uint from std::integer import uinteger from js::core import random from js::math import Document, Window, CanvasRenderingContext2D from w3c::dom import Element,HTMLCanvasElement, HTMLImageElement, MouseEvent from w3c::dom import model import view /** * Add a given number of bombs to the board. */ method add_random_bombs(model::Board board, uint n) -> model::Board: uinteger remaining = |board.squares| // Use Knuth's algorithm S for x in 0..board.width: for y in 0..board.height: // Flip a coin (so-to-speak) if random(remaining) < n: // create bomb square model::Square s = model::HiddenSquare(true,false) // Update board board = model::set_square(board,(uint) x, (uint) y,s) // Reduce number of bombs to place n = n - 1 // Reduce remaining options remaining = remaining - 1 // return updated board return board /** * Handle a mouse event on the canvas */ method onclick_handler(MouseEvent e, &view::State state, Window window): // Convert from view to world coordinates uint x = e->offsetX / state->gridsize uint y = e->offsetY / state->gridsize // Update board if e->shiftKey: state->board = model::flag_square(state->board,x,y) else: state->board = model::expose_square(state->board,x,y) // Render initial board view::draw_board(*state) // Finally determine game status (bool gameOver, bool winner) = model::is_gameover(state->board) // Check whether game over if gameOver: // Yes, but win or lose? if winner: window->alert("Well done --- You Found all the Mines!") else: window->alert("Game Over --- You Lost!") // Done /** * Create a new game of Minesweeper */ public export method main(uint width, uint height, uint bombs, Window window, HTMLCanvasElement canvas, HTMLImageElement[] images) // Requires at least 9 images requires |images| == 13: Document document = window->document // NOTE: following should not be required! Element c = document->getElementById("myCanvas") // Create a standard sized board model::Board board = model::Board(width,height) // Add bombs board = add_random_bombs(board,bombs) // Initialise the view state &view::State state = new view::init(document,canvas,board,images) // Render initial board view::draw_board(*state) // Configure mouse click listener c->addEventListener("click",&(MouseEvent e -> onclick_handler(e,state,window)))