Skip to content

Commit

Permalink
Update README
Browse files Browse the repository at this point in the history
- Use new struct-based tile API
- C++ examples
  • Loading branch information
joelekstrom committed Feb 12, 2018
1 parent f84b974 commit 585664e
Showing 1 changed file with 31 additions and 12 deletions.
43 changes: 31 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
[![Build Status](https://travis-ci.org/accatyyc/libminesweeper.svg?branch=master)](https://travis-ci.org/accatyyc/libminesweeper)
# libminesweeper
A static library for handling Minesweeper game logic, that can run on embedded hardware.
A library for handling Minesweeper game logic, that can run on embedded hardware.
Its goals are to be as efficient as possible memory- and processing power wise. It's written
in "[SDCC](http://sdcc.sourceforge.net) compatible C99", which pretty much means that it's
C99 without inline variable declarations.

## Building
Clone the repo and run `make` in the folder, and you'll get the binary `libminesweeper.a`. Link the binary and include
`include/minesweeper.h` in your projects. You can also check out the reference implentations below. Those repos include this repo
as a `git submodule` and automatically builds it as part of their build chain.
as a `git submodule` and automatically builds it as part of their build chain. You can also simply copy the implementation
file and headers you need directly into your project.

## Usage

Expand All @@ -24,6 +25,10 @@ of this buffer can be retrieved from the function `minesweeper_minimum_buffer_si
To initialize a game in this buffer, call `minesweeper_init(unsigned width, unsigned height, float mine_density, uint8_t *buffer)`,
where mine density is a float value between 0 and 1. If 1, all tiles will contain a mine, and if 0, no tiles will
contain a mine. The game starts to get unplayable around a density of 0.5.

_Note: due to optimizations, not all tiles will actually have mines with a density of 1.0, since
during generation, if a tile is seleted that already has a mine, it will be ignored. This means
that the actual mine count will usually be a bit less than (width * height * mine_density)_

```c
unsigned width = 20;
Expand Down Expand Up @@ -55,22 +60,36 @@ minesweeper_open_tile(game, tile);
To render tiles correctly in your UI, you can find the state of a tile by doing the following:
```c
uint8_t *tile = minesweeper_get_tile_at(game, x, y);
bool contains_flag = *tile & TILE_FLAG;
bool is_opened = *tile & TILE_OPENED;
bool has_mine = *tile & TILE_MINE;
struct minesweeper_tile *tile = minesweeper_get_tile_at(game, x, y);
bool has_mine = tile->has_mine;
```

The trick is that each tile is an 8-bit number of flags representing the state of that tile.
It also contains the number of adjacent mines, which is the number shown on opened tiles
in most minesweepers. You can retrieve it like this:
```c
uint8_t mine_count = minesweeper_get_adjacent_mine_count(tile);
```
A tile has the following properties:
- `adjacent_mine_count`: The number of mines in the tiles surrounding this tile. This corresponds to the number that minesweepers normally draw on an opened tile.
- `has_flag`
- `has_mine`
- `is_opened`

Check out the reference implementations for more examples on how to render a game.
All available functions are documented in minesweeper.h.

### C++ API

There is a header to use the library from C++, in an object-oriented manner.
Here are the same examples, using `minesweeper.hpp`:

```cpp
#include <minesweeper.hpp>

Minesweeper::Game game = Minesweeper::Game(width, height, 0.3);
game.setCursor(0, 0);
game.moveCursor(RIGHT, false);

auto tile = game.selectedTile();
tile.open();
bool hasMine = tile.hasMine();
```

## Testing
Run `make run-c-tests` to run the unit tests. It might be a good idea to run the tests
with your preferred compiler, to catch anything I might've missed. Please add an
Expand Down

0 comments on commit 585664e

Please sign in to comment.