Add 'nix/' from commit '7b13e4eae43815718be53d26d170b8a11bdf3043'
git-subtree-dir: nix git-subtree-mainline:fbea8b264cgit-subtree-split:7b13e4eae4
This commit is contained in:
13
nix/.gitignore
vendored
Normal file
13
nix/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Nix build outputs
|
||||||
|
result
|
||||||
|
result-*
|
||||||
|
|
||||||
|
# Nix evaluation caches
|
||||||
|
.direnv/
|
||||||
|
.envrc
|
||||||
|
|
||||||
|
# Editor noise
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
183
nix/README.md
Normal file
183
nix/README.md
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
# Shikaku — Native NixOS Puzzle Game
|
||||||
|
|
||||||
|
A fully offline, ad-free [Shikaku](https://en.wikipedia.org/wiki/Shikaku) rectangle
|
||||||
|
puzzle game. Built with Python + GTK4. Packaged to nixpkgs standards.
|
||||||
|
|
||||||
|
## What is Shikaku?
|
||||||
|
|
||||||
|
Divide the grid into rectangles. Each rectangle must:
|
||||||
|
- Contain **exactly one** number clue
|
||||||
|
- Have an **area (in cells) equal to that number**
|
||||||
|
|
||||||
|
All puzzles are procedurally generated and guaranteed solvable — the generator
|
||||||
|
works backwards, partitioning the grid into valid rectangles first and then
|
||||||
|
placing clue numbers, so every puzzle has a solution by construction.
|
||||||
|
|
||||||
|
## Controls
|
||||||
|
|
||||||
|
| Action | Input |
|
||||||
|
|---------------------|----------------------------------|
|
||||||
|
| Draw a rectangle | Click and drag across cells |
|
||||||
|
| Erase a rectangle | Right-click any cell inside it |
|
||||||
|
| Check your solution | Click **Check** |
|
||||||
|
| New puzzle | Click **New Puzzle** |
|
||||||
|
| Clear all | Click **Clear** |
|
||||||
|
|
||||||
|
## Puzzle sizes
|
||||||
|
|
||||||
|
| Size | Status |
|
||||||
|
|-------|--------|
|
||||||
|
| 5×5 | ✅ |
|
||||||
|
| 7×7 | ✅ |
|
||||||
|
| 10×10 | 🔜 |
|
||||||
|
| 15×15 | 🔜 |
|
||||||
|
| 20×20 | 🔜 |
|
||||||
|
| 25×25 | 🔜 |
|
||||||
|
|
||||||
|
---
|
||||||
|
## TODO
|
||||||
|
- [x] Fix window size to auto resize when changing game mode
|
||||||
|
- [x] Show number of cells selected during a mouse drag, before placing
|
||||||
|
- [x] Remove ability to select just 1 cell
|
||||||
|
- [x] Add some kind of zoom feature
|
||||||
|
- Scroll wheel
|
||||||
|
- and/or a ui button for zoom in/out
|
||||||
|
- [x] Remove red color from rectangle option
|
||||||
|
- [x] Allow user to show the "seed" of the puzzle
|
||||||
|
- [x] Option to input a custom seed
|
||||||
|
|
||||||
|
### Possible Features
|
||||||
|
- Keep local "high score" for each puzzle type
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Using the package locally (before it lands in nixpkgs)
|
||||||
|
|
||||||
|
### Quick test with nix-build
|
||||||
|
|
||||||
|
Copy the `pkgs/by-name/sh/shikaku/` directory into your local nixpkgs checkout,
|
||||||
|
then from the nixpkgs root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix-build -A shikaku
|
||||||
|
./result/bin/shikaku
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install into your profile
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix-env -f '<nixpkgs>' -iA shikaku
|
||||||
|
```
|
||||||
|
|
||||||
|
### In your NixOS `configuration.nix` (via an overlay)
|
||||||
|
|
||||||
|
```nix
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(final: prev: {
|
||||||
|
shikaku = final.callPackage /path/to/pkgs/by-name/sh/shikaku/package.nix { };
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = [ pkgs.shikaku ];
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Submitting to nixpkgs
|
||||||
|
|
||||||
|
### File layout (already correct for the PR)
|
||||||
|
|
||||||
|
```
|
||||||
|
pkgs/by-name/sh/shikaku/
|
||||||
|
├── package.nix ← the derivation
|
||||||
|
└── shikaku.py ← the game source (single file)
|
||||||
|
```
|
||||||
|
|
||||||
|
The `pkgs/by-name` directory is automatically wired into nixpkgs — no edits to
|
||||||
|
`all-packages.nix` are needed. The package attribute `pkgs.shikaku` is created
|
||||||
|
automatically from the directory name.
|
||||||
|
|
||||||
|
### Steps before opening the PR
|
||||||
|
|
||||||
|
1. **Host the source.** Push this repo to GitHub (or another forge). The
|
||||||
|
`src.rev` and `src.hash` in `package.nix` must point to a real tagged commit.
|
||||||
|
Get the hash with:
|
||||||
|
```bash
|
||||||
|
nix-prefetch-url --unpack https://github.com/YOU/shikaku/archive/v0.1.0.tar.gz
|
||||||
|
# or with the newer tooling:
|
||||||
|
nix store prefetch-file --hash-type sha256 --unpack \
|
||||||
|
https://github.com/YOU/shikaku/archive/refs/tags/v0.1.0.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Add yourself as a maintainer.** Edit `maintainers/maintainer-list.nix` in
|
||||||
|
nixpkgs to add your handle, then reference it in `package.nix`:
|
||||||
|
```nix
|
||||||
|
maintainers = with lib.maintainers; [ your-handle ];
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Build and run locally** from the nixpkgs root:
|
||||||
|
```bash
|
||||||
|
nix-build -A shikaku
|
||||||
|
./result/bin/shikaku
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Check nixpkgs-vet passes** (CI runs this automatically, but you can run it
|
||||||
|
locally too):
|
||||||
|
```bash
|
||||||
|
nix-build pkgs/top-level/release.nix -A tarball.nixpkgs-basic-release-checks \
|
||||||
|
--arg supportedSystems '["x86_64-linux"]'
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Open the PR** with the commit message format nixpkgs expects:
|
||||||
|
```
|
||||||
|
shikaku: init at 0.1.0
|
||||||
|
```
|
||||||
|
Include in the PR description:
|
||||||
|
- A screenshot of the game running
|
||||||
|
- Link to the upstream source
|
||||||
|
- Confirmation it builds on x86_64-linux (and aarch64-linux if you can)
|
||||||
|
|
||||||
|
### nixpkgs reviewer checklist (pre-answered)
|
||||||
|
|
||||||
|
| Requirement | Status |
|
||||||
|
|---|---|
|
||||||
|
| `pkgs/by-name/sh/shikaku/package.nix` | ✅ |
|
||||||
|
| `pname` lowercase, no spaces | ✅ `"shikaku"` |
|
||||||
|
| `version` present | ✅ |
|
||||||
|
| Source from `fetchFromGitHub` with pinned `rev` and `hash` | ✅ (fill in hash) |
|
||||||
|
| `meta.description` — short, no trailing period | ✅ |
|
||||||
|
| `meta.license` | ✅ `lib.licenses.mit` |
|
||||||
|
| `meta.maintainers` | ⚠️ add yourself |
|
||||||
|
| `meta.homepage` | ⚠️ add your repo URL |
|
||||||
|
| `meta.platforms` | ✅ `lib.platforms.linux` (GTK4, Linux only) |
|
||||||
|
| `meta.mainProgram` | ✅ `"shikaku"` |
|
||||||
|
| `wrapGAppsHook4` for GTK4 app | ✅ |
|
||||||
|
| `gobject-introspection` in `nativeBuildInputs` | ✅ |
|
||||||
|
| No `flake.nix` in the package dir | ✅ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How puzzle generation works
|
||||||
|
|
||||||
|
Puzzles are generated in reverse, guaranteeing solvability:
|
||||||
|
|
||||||
|
1. The full grid is **partitioned into random non-overlapping rectangles**
|
||||||
|
(every cell belongs to exactly one rectangle, no gaps).
|
||||||
|
2. Each rectangle gets **one randomly chosen clue cell**, with the rectangle's
|
||||||
|
area written as the number.
|
||||||
|
3. The player sees only the clue numbers and must reconstruct the rectangles.
|
||||||
|
|
||||||
|
Because the rectangles are generated first and clues derived from them, every
|
||||||
|
puzzle is solvable by construction. There is no backtracking solver needed.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
| Dependency | Why |
|
||||||
|
|---|---|
|
||||||
|
| `python3` | Runtime |
|
||||||
|
| `pygobject3` | GTK4 Python bindings |
|
||||||
|
| `gtk4` | GUI toolkit |
|
||||||
|
| `gobject-introspection` | Required at build time for PyGObject |
|
||||||
|
| `wrapGAppsHook4` | Wraps binary with correct GDK/GI env vars at runtime |
|
||||||
|
|
||||||
|
All managed by Nix — nothing to install manually.
|
||||||
3
nix/default.nix
Normal file
3
nix/default.nix
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{ pkgs ? import <nixpkgs> { } }:
|
||||||
|
|
||||||
|
pkgs.callPackage ./package.nix { }
|
||||||
89
nix/package.nix
Normal file
89
nix/package.nix
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
python3Packages,
|
||||||
|
gtk4,
|
||||||
|
gobject-introspection,
|
||||||
|
wrapGAppsHook4,
|
||||||
|
}:
|
||||||
|
|
||||||
|
python3Packages.buildPythonApplication rec {
|
||||||
|
pname = "shikaku";
|
||||||
|
version = "0.1.0";
|
||||||
|
pyproject = false;
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
gobject-introspection
|
||||||
|
wrapGAppsHook4
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
gtk4
|
||||||
|
];
|
||||||
|
|
||||||
|
dependencies = with python3Packages; [
|
||||||
|
pygobject3
|
||||||
|
];
|
||||||
|
|
||||||
|
# Pure Python — nothing to compile
|
||||||
|
dontBuild = true;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
install -Dm755 shikaku.py $out/share/shikaku/shikaku.py
|
||||||
|
|
||||||
|
# Wrapper script so wrapGAppsHook4 can inject GDK/GI env vars
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cat > $out/bin/shikaku << EOF
|
||||||
|
#!${python3Packages.python.interpreter}
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, "$out/share/shikaku")
|
||||||
|
import shikaku
|
||||||
|
shikaku.main()
|
||||||
|
EOF
|
||||||
|
chmod +x $out/bin/shikaku
|
||||||
|
|
||||||
|
# Desktop entry for app launchers (GNOME, KDE, etc.)
|
||||||
|
install -Dm644 /dev/stdin $out/share/applications/shikaku.desktop << EOF
|
||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Type=Application
|
||||||
|
Name=Shikaku
|
||||||
|
Comment=Rectangle partition logic puzzle
|
||||||
|
Exec=shikaku
|
||||||
|
Icon=applications-games
|
||||||
|
Terminal=false
|
||||||
|
Categories=Game;LogicGame;BoardGame;
|
||||||
|
Keywords=puzzle;shikaku;logic;grid;rectangle;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
# wrapGAppsHook4 handles GDK_PIXBUF_MODULE_FILE, XDG_DATA_DIRS, GI_TYPELIB_PATH, etc.
|
||||||
|
# but it expects to wrap a binary. Point it at our wrapper script.
|
||||||
|
dontWrapGApps = false;
|
||||||
|
|
||||||
|
passthru.tests.shikaku-starts = python3Packages.pytestCheckHook;
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Rectangle partition logic puzzle (Shikaku)";
|
||||||
|
longDescription = ''
|
||||||
|
Shikaku is a logic puzzle where you partition a grid into non-overlapping
|
||||||
|
rectangles. Each rectangle must contain exactly one number, and that number
|
||||||
|
equals the area of the rectangle in cells. Puzzles are procedurally generated
|
||||||
|
and guaranteed to be solvable. Supports 5×5 and 7×7 grids, with larger sizes
|
||||||
|
planned. Built with Python and GTK4; plays fully offline.
|
||||||
|
'';
|
||||||
|
homepage = "https://github.com/your-github-username/shikaku"; # TODO
|
||||||
|
# changelog = "https://github.com/your-github-username/shikaku/blob/v${version}/CHANGELOG.md";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
maintainers = with lib.maintainers; [
|
||||||
|
# your-nixpkgs-handle # TODO: add yourself to maintainers/maintainer-list.nix first
|
||||||
|
];
|
||||||
|
platforms = lib.platforms.linux;
|
||||||
|
mainProgram = "shikaku";
|
||||||
|
};
|
||||||
|
}
|
||||||
1001
nix/shikaku.py
Normal file
1001
nix/shikaku.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user