152 lines
3.8 KiB
Markdown
152 lines
3.8 KiB
Markdown
# Nonogram Loader
|
|
|
|
A memory-efficient C++ nonogram loader that stores nonogram solution and instructions in a separate class, using minimal memory while only storing important information.
|
|
|
|
## Features
|
|
|
|
- **Memory Efficient**: Uses compact storage for hints (uint8_t) and solutions (1 bit per cell)
|
|
- **Standard Format Support**: Reads `.non` format files as specified in the format specification
|
|
- **Ignores Unnecessary Data**: Only stores essential puzzle data, ignores author names and other metadata
|
|
- **Multiple Loading Methods**: Load from files, strings, or entire directories
|
|
- **Solution Support**: Optional solution storage when present in the file
|
|
|
|
## Memory Usage
|
|
|
|
The loader is designed to use minimal memory:
|
|
|
|
- **Hints**: Stored as `uint8_t` arrays with compact indexing
|
|
- **Solutions**: Stored as bit arrays (1 bit per cell)
|
|
- **Dimensions**: Stored as `uint16_t` for puzzles up to 65535x65535
|
|
|
|
For a 10x10 puzzle:
|
|
- Row hints: ~10 bytes
|
|
- Column hints: ~10 bytes
|
|
- Solution: ~13 bytes (10x10 bits = 100 bits = 13 bytes)
|
|
- Total: ~33 bytes + overhead
|
|
|
|
## Usage
|
|
|
|
### Basic Usage
|
|
|
|
```cpp
|
|
#include "nonogram.h"
|
|
|
|
// Load a single nonogram from file
|
|
auto nonogram = NonogramLoader::fromFile("puzzle.non");
|
|
if (nonogram) {
|
|
std::cout << "Loaded: " << nonogram->getWidth() << "x" << nonogram->getHeight() << std::endl;
|
|
|
|
// Access row hints
|
|
for (size_t i = 0; i < nonogram->getRowCount(); ++i) {
|
|
auto hints = nonogram->getRowHints(i);
|
|
// Process hints...
|
|
}
|
|
|
|
// Access column hints
|
|
for (size_t i = 0; i < nonogram->getColumnCount(); ++i) {
|
|
auto hints = nonogram->getColumnHints(i);
|
|
// Process hints...
|
|
}
|
|
|
|
// Access solution if available
|
|
if (nonogram->hasSolution()) {
|
|
for (size_t row = 0; row < nonogram->getHeight(); ++row) {
|
|
for (size_t col = 0; col < nonogram->getWidth(); ++col) {
|
|
bool filled = nonogram->getSolutionCell(row, col);
|
|
// Process cell...
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Load from Directory
|
|
|
|
```cpp
|
|
// Load all nonograms from a directory
|
|
auto puzzles = NonogramLoader::fromDirectory("/path/to/nonograms");
|
|
for (const auto& puzzle : puzzles) {
|
|
// Process each puzzle...
|
|
}
|
|
```
|
|
|
|
### Load from String
|
|
|
|
```cpp
|
|
std::string content = R"(
|
|
width 5
|
|
height 5
|
|
|
|
rows
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
|
|
columns
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
|
|
goal 1000010000100001000010000
|
|
)";
|
|
|
|
auto nonogram = NonogramLoader::fromString(content);
|
|
```
|
|
|
|
## Classes
|
|
|
|
### Nonogram
|
|
Main class storing puzzle data:
|
|
- `getWidth()` / `getHeight()`: Puzzle dimensions
|
|
- `getRowHints(row)`: Get hints for a specific row
|
|
- `getColumnHints(col)`: Get hints for a specific column
|
|
- `hasSolution()`: Check if solution is available
|
|
- `getSolutionCell(row, col)`: Get solution cell value
|
|
|
|
### NonogramLoader
|
|
Static utility class for loading:
|
|
- `fromFile(filename)`: Load from file
|
|
- `fromString(content)`: Load from string
|
|
- `fromDirectory(dirname)`: Load all .non files from directory
|
|
|
|
## Storage Details
|
|
|
|
### Hints Storage
|
|
- Uses `NonogramHintsStorage` class
|
|
- Each hint is a `uint8_t` (0-255)
|
|
- Compact storage with offset arrays
|
|
- Handles comma-separated hint sequences
|
|
|
|
### Solution Storage
|
|
- Uses `NonogramSolutionStorage` class
|
|
- 1 bit per cell (filled/empty)
|
|
- Packed into bytes for efficiency
|
|
- Supports loading from goal strings with or without quotes
|
|
|
|
## Supported Format
|
|
|
|
The loader supports the standard `.non` format:
|
|
- Width/height dimensions
|
|
- Row and column hints (comma-separated numbers)
|
|
- Optional solution/goal string
|
|
- Ignores metadata (author, title, copyright, etc.)
|
|
|
|
## Building
|
|
|
|
```bash
|
|
# Compile with C++17
|
|
g++ -std=c++17 -o myprogram main.cpp nonogram.cpp
|
|
```
|
|
|
|
## Example
|
|
|
|
See `example.cpp` for a complete usage example that demonstrates:
|
|
- Loading from file
|
|
- Accessing hints and solutions
|
|
- Loading from directory
|
|
- Displaying puzzle information
|