Add 'nix/' from commit '7b13e4eae43815718be53d26d170b8a11bdf3043'

git-subtree-dir: nix
git-subtree-mainline: fbea8b264c
git-subtree-split: 7b13e4eae4
This commit is contained in:
Brian Nelson
2026-09-15 08:41:23 -04:00
5 changed files with 1289 additions and 0 deletions

13
nix/.gitignore vendored Normal file
View 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
View 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
View File

@@ -0,0 +1,3 @@
{ pkgs ? import <nixpkgs> { } }:
pkgs.callPackage ./package.nix { }

89
nix/package.nix Normal file
View 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

File diff suppressed because it is too large Load Diff