Files
nd-wfc/demos/nonogram/README.md
2025-08-22 15:00:50 +09:00

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