Skip to content

This is a browser implementation of the classic game Minesweeper using Angular.

License

Notifications You must be signed in to change notification settings

charlesribeiro/minesweeper-angular

Repository files navigation

Minesweeper

This is a browser implementation of the classic game Minesweeper using Angular 16.

Minesweeper

TL;DR

Make sure you have NPM and Yarn installed on your machine, install dependencies with yarn. Then, just run yarn start to open the project. yarn test and yarn test-coverage will run the Jest unit tests.

Technologies used

  • Angular 16
  • TailwindCSS with SASS
  • Redux (NgRx + RxJs)
  • Jest (jest-preset-angular)
  • Github Actions

Cool Features

  • This project uses SASS for styling (plus TailwindCSS)
  • The application can be tested using yarn test
  • The project auto-lints the files, also, yarn lint:fix will try to fix linting problems with Prettier
  • A coverage report is available with jest yarn test-coverage
  • This projects includes load and save features. You can navigate to 'save-and-load' and upload the saves/savewith35mines.json file.

Algorithms employed

This project uses two notable algorithms:

Deep Search First

One of the most challenging parts of the game is to implement the following behavior:

If the clicked cell number of adjacent mines is 0, it behaves as if the user had clicked on every cell around it.

This is reached by the Deep Search First algorithm (https://en.wikipedia.org/wiki/Depth-first_search)

Fisher–Yates shuffle

Another really useful algorithm used in this project is the Fisher–Yates shuffle. It ensures the creation of truly randomized grids, so each game you generate in this game is unique! (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)

Code coverage

This project aims to have a high unit test coverage for statements.

-----------------------------------------------------|---------|----------|---------|---------|--------------------
File                                                 | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s  
-----------------------------------------------------|---------|----------|---------|---------|--------------------
All files                                            |   94.01 |       86 |   90.69 |   93.81 |                    
 app                                                 |     100 |      100 |     100 |     100 |                    
  app.component.html                                 |     100 |      100 |     100 |     100 |                    
  app.component.ts                                   |     100 |      100 |     100 |     100 |                    
 app/features/game/components/main-game              |   93.93 |      100 |   83.33 |   93.93 |                    
  main-game.component.html                           |     100 |      100 |     100 |     100 |                    
  main-game.component.ts                             |   93.75 |      100 |   83.33 |   93.75 | 59,71              
 app/features/game/containers/board                  |     100 |      100 |     100 |     100 |                    
  board.component.html                               |     100 |      100 |     100 |     100 |                    
  board.component.ts                                 |     100 |      100 |     100 |     100 |                    
 app/features/game/containers/cell                   |     100 |      100 |     100 |     100 |                    
  cell.component.html                                |     100 |      100 |     100 |     100 |                    
  cell.component.ts                                  |     100 |      100 |     100 |     100 |                    
 app/features/game/containers/reset-button           |     100 |      100 |     100 |     100 |                    
  reset-button.component.html                        |     100 |      100 |     100 |     100 |                    
  reset-button.component.ts                          |     100 |      100 |     100 |     100 |                    
 app/features/game/containers/seven-segment          |     100 |      100 |     100 |     100 |                    
  seven-segment-display.component.html               |     100 |      100 |     100 |     100 |                    
  seven-segment-display.component.ts                 |     100 |      100 |     100 |     100 |                    
 app/features/save-and-load/components/save-and-load |   48.14 |        0 |   57.14 |   48.14 |                    
  save-and-load.component.html                       |     100 |      100 |     100 |     100 |                    
  save-and-load.component.ts                         |   46.15 |        0 |   57.14 |   46.15 | 30-58              
 app/features/settings/components                    |     100 |      100 |     100 |     100 |                    
  settings.component.html                            |     100 |      100 |     100 |     100 |                    
  settings.component.ts                              |     100 |      100 |     100 |     100 |                    
 app/features/settings/store                         |     100 |      100 |     100 |     100 |                    
  settings.actions.ts                                |     100 |      100 |     100 |     100 |                    
  settings.reducer.ts                                |     100 |      100 |     100 |     100 |                    
  settings.selectors.ts                              |     100 |      100 |     100 |     100 |                    
 app/features/shared/containers/error                |     100 |      100 |     100 |     100 |                    
  error.component.html                               |     100 |      100 |     100 |     100 |                    
  error.component.ts                                 |     100 |      100 |     100 |     100 |                    
 app/features/shared/containers/header               |     100 |      100 |     100 |     100 |                    
  header.component.html                              |     100 |      100 |     100 |     100 |                    
  header.component.ts                                |     100 |      100 |     100 |     100 |                    
 app/features/shared/containers/loader               |     100 |      100 |     100 |     100 |                    
  loader.component.html                              |     100 |      100 |     100 |     100 |                    
  loader.component.ts                                |     100 |      100 |     100 |     100 |                    
 app/features/shared/containers/page-wrapper         |     100 |      100 |     100 |     100 |                    
  page-wrapper.component.html                        |     100 |      100 |     100 |     100 |                    
  page-wrapper.component.ts                          |     100 |      100 |     100 |     100 |                    
 app/models                                          |     100 |      100 |     100 |     100 |                    
  cell.model.ts                                      |     100 |      100 |     100 |     100 |                    
  gameStatus.model.ts                                |     100 |      100 |     100 |     100 |                    
  level.model.ts                                     |     100 |      100 |     100 |     100 |                    
  sessionTypes.ts                                    |     100 |      100 |     100 |     100 |                    
 app/services                                        |   89.38 |    84.21 |   78.78 |   88.99 |                    
  click-handler.service.ts                           |   84.31 |    92.85 |   72.72 |   84.31 | 32,37,42,59-64,123 
  create-level.service.ts                            |   89.18 |        0 |      60 |   88.23 | 24,28,32,36        
  storage.service.ts                                 |     100 |      100 |     100 |     100 |                    
  timer.service.ts                                   |     100 |       75 |     100 |     100 | 45                 
 app/state                                           |     100 |      100 |     100 |     100 |                    
  app.actions.ts                                     |     100 |      100 |     100 |     100 |                    
  app.effects.ts                                     |     100 |      100 |     100 |     100 |                    
  app.reducer.ts                                     |     100 |      100 |     100 |     100 |                    
  app.selectors.ts                                   |     100 |      100 |     100 |     100 |                    
 app/utils                                           |     100 |      100 |     100 |     100 |                    
  fisher-yates-shuffle.ts                            |     100 |      100 |     100 |     100 |                    
  mock-board.ts                                      |     100 |      100 |     100 |     100 |                    
  mock-cell.ts                                       |     100 |      100 |     100 |     100 |                    
  mock-settings.ts                                   |     100 |      100 |     100 |     100 |                    
  neighbor-offsets.ts                                |     100 |      100 |     100 |     100 |                    
  predefinedLevels.ts                                |     100 |      100 |     100 |     100 |                    
  store-utils.ts                                     |     100 |      100 |     100 |     100 |                    
-----------------------------------------------------|---------|----------|---------|---------|--------------------

Credits

Thanks to eugeneloza that provided the assets here https://opengameart.org/content/minesweeper-tile-set. Also, to the developers behind each of the imported GitHub Actions. This project uses the DSEG7(https://github.com/keshikan/DSEG) font.

About

This is a browser implementation of the classic game Minesweeper using Angular.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published