mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
New puzzle: `Filling', a Fillomino implementation by Jonas Koelker.
[originally from svn r7326]
This commit is contained in:
3
LICENCE
3
LICENCE
@ -1,6 +1,7 @@
|
|||||||
This software is copyright (c) 2004-2007 Simon Tatham.
|
This software is copyright (c) 2004-2007 Simon Tatham.
|
||||||
|
|
||||||
Portions copyright Richard Boulton, James Harvey and Mike Pinna.
|
Portions copyright Richard Boulton, James Harvey, Mike Pinna and
|
||||||
|
Jonas K<>lker.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation files
|
obtaining a copy of this software and associated documentation files
|
||||||
|
38
dsf.c
38
dsf.c
@ -64,11 +64,13 @@ void dsf_init(int *dsf, int size)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) dsf[i] = 6;
|
||||||
/* Bottom bit of each element of this array stores whether that element
|
/* Bottom bit of each element of this array stores whether that
|
||||||
* is opposite to its parent, which starts off as false */
|
* element is opposite to its parent, which starts off as
|
||||||
dsf[i] = i << 1;
|
* false. Second bit of each element stores whether that element
|
||||||
}
|
* is the root of its tree or not. If it's not the root, the
|
||||||
|
* remaining 30 bits are the parent, otherwise the remaining 30
|
||||||
|
* bits are the number of elements in the tree. */
|
||||||
}
|
}
|
||||||
|
|
||||||
int *snew_dsf(int size)
|
int *snew_dsf(int size)
|
||||||
@ -93,6 +95,10 @@ void dsf_merge(int *dsf, int v1, int v2)
|
|||||||
edsf_merge(dsf, v1, v2, FALSE);
|
edsf_merge(dsf, v1, v2, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dsf_size(int *dsf, int index) {
|
||||||
|
return dsf[dsf_canonify(dsf, index)] >> 2;
|
||||||
|
}
|
||||||
|
|
||||||
int edsf_canonify(int *dsf, int index, int *inverse_return)
|
int edsf_canonify(int *dsf, int index, int *inverse_return)
|
||||||
{
|
{
|
||||||
int start_index = index, canonical_index;
|
int start_index = index, canonical_index;
|
||||||
@ -106,9 +112,9 @@ int edsf_canonify(int *dsf, int index, int *inverse_return)
|
|||||||
/* Find the index of the canonical element of the 'equivalence class' of
|
/* Find the index of the canonical element of the 'equivalence class' of
|
||||||
* which start_index is a member, and figure out whether start_index is the
|
* which start_index is a member, and figure out whether start_index is the
|
||||||
* same as or inverse to that. */
|
* same as or inverse to that. */
|
||||||
while ((dsf[index] >> 1) != index) {
|
while ((dsf[index] & 2) == 0) {
|
||||||
inverse ^= (dsf[index] & 1);
|
inverse ^= (dsf[index] & 1);
|
||||||
index = dsf[index] >> 1;
|
index = dsf[index] >> 2;
|
||||||
/* fprintf(stderr, "index = %2d, ", index); */
|
/* fprintf(stderr, "index = %2d, ", index); */
|
||||||
/* fprintf(stderr, "inverse = %d\n", inverse); */
|
/* fprintf(stderr, "inverse = %d\n", inverse); */
|
||||||
}
|
}
|
||||||
@ -121,9 +127,9 @@ int edsf_canonify(int *dsf, int index, int *inverse_return)
|
|||||||
* canonical member. */
|
* canonical member. */
|
||||||
index = start_index;
|
index = start_index;
|
||||||
while (index != canonical_index) {
|
while (index != canonical_index) {
|
||||||
int nextindex = dsf[index] >> 1;
|
int nextindex = dsf[index] >> 2;
|
||||||
int nextinverse = inverse ^ (dsf[index] & 1);
|
int nextinverse = inverse ^ (dsf[index] & 1);
|
||||||
dsf[index] = (canonical_index << 1) | inverse;
|
dsf[index] = (canonical_index << 2) | inverse;
|
||||||
inverse = nextinverse;
|
inverse = nextinverse;
|
||||||
index = nextindex;
|
index = nextindex;
|
||||||
}
|
}
|
||||||
@ -143,16 +149,26 @@ void edsf_merge(int *dsf, int v1, int v2, int inverse)
|
|||||||
/* fprintf(stderr, "Merge [%2d,%2d], %d\n", v1, v2, inverse); */
|
/* fprintf(stderr, "Merge [%2d,%2d], %d\n", v1, v2, inverse); */
|
||||||
|
|
||||||
v1 = edsf_canonify(dsf, v1, &i1);
|
v1 = edsf_canonify(dsf, v1, &i1);
|
||||||
|
assert(dsf[v1] & 2);
|
||||||
inverse ^= i1;
|
inverse ^= i1;
|
||||||
v2 = edsf_canonify(dsf, v2, &i2);
|
v2 = edsf_canonify(dsf, v2, &i2);
|
||||||
|
assert(dsf[v2] & 2);
|
||||||
inverse ^= i2;
|
inverse ^= i2;
|
||||||
|
|
||||||
/* fprintf(stderr, "Doing [%2d,%2d], %d\n", v1, v2, inverse); */
|
/* fprintf(stderr, "Doing [%2d,%2d], %d\n", v1, v2, inverse); */
|
||||||
|
|
||||||
if (v1 == v2)
|
if (v1 == v2)
|
||||||
assert(!inverse);
|
assert(!inverse);
|
||||||
else
|
else {
|
||||||
dsf[v2] = (v1 << 1) | !!inverse;
|
assert(inverse == 0 || inverse == 1);
|
||||||
|
if ((dsf[v2] >> 2) > (dsf[v1] >> 2)) {
|
||||||
|
int v3 = v1;
|
||||||
|
v1 = v2;
|
||||||
|
v2 = v3;
|
||||||
|
}
|
||||||
|
dsf[v1] += (dsf[v2] >> 2) << 2;
|
||||||
|
dsf[v2] = (v1 << 2) | !!inverse;
|
||||||
|
}
|
||||||
|
|
||||||
v2 = edsf_canonify(dsf, v2, &i2);
|
v2 = edsf_canonify(dsf, v2, &i2);
|
||||||
assert(v2 == v1);
|
assert(v2 == v1);
|
||||||
|
24
filling.R
Normal file
24
filling.R
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# -*- makefile -*-
|
||||||
|
|
||||||
|
FILLING = filling dsf filling-icon|no-icon
|
||||||
|
|
||||||
|
fillingsolver : [U] filling[STANDALONE_SOLVER] dsf STANDALONE
|
||||||
|
fillingsolver : [C] filling[STANDALONE_SOLVER] dsf STANDALONE
|
||||||
|
|
||||||
|
filling : [X] GTK COMMON FILLING
|
||||||
|
|
||||||
|
filling : [G] WINDOWS COMMON FILLING
|
||||||
|
|
||||||
|
ALL += filling
|
||||||
|
|
||||||
|
!begin gtk
|
||||||
|
GAMES += filling
|
||||||
|
!end
|
||||||
|
|
||||||
|
!begin >list.c
|
||||||
|
A(filling) \
|
||||||
|
!end
|
||||||
|
|
||||||
|
!begin >wingames.lst
|
||||||
|
filling.exe:Filling
|
||||||
|
!end
|
@ -1,8 +1,8 @@
|
|||||||
# Makefile for Puzzles icons.
|
# Makefile for Puzzles icons.
|
||||||
|
|
||||||
PUZZLES = blackbox bridges cube dominosa fifteen flip galaxies guess inertia \
|
PUZZLES = blackbox bridges cube dominosa fifteen filling flip galaxies guess \
|
||||||
lightup loopy map mines net netslide pattern pegs rect samegame \
|
inertia lightup loopy map mines net netslide pattern pegs rect \
|
||||||
sixteen slant solo tents twiddle unequal untangle
|
samegame sixteen slant solo tents twiddle unequal untangle
|
||||||
|
|
||||||
BASE = $(patsubst %,%-base.png,$(PUZZLES))
|
BASE = $(patsubst %,%-base.png,$(PUZZLES))
|
||||||
WEB = $(patsubst %,%-web.png,$(PUZZLES))
|
WEB = $(patsubst %,%-web.png,$(PUZZLES))
|
||||||
@ -55,6 +55,7 @@ blackbox-ibase.png : override CROP=352x352 144x144+0+208
|
|||||||
bridges-ibase.png : override CROP=264x264 107x107+157+157
|
bridges-ibase.png : override CROP=264x264 107x107+157+157
|
||||||
dominosa-ibase.png : override CROP=304x272 152x152+152+0
|
dominosa-ibase.png : override CROP=304x272 152x152+152+0
|
||||||
fifteen-ibase.png : override CROP=240x240 120x120+0+120
|
fifteen-ibase.png : override CROP=240x240 120x120+0+120
|
||||||
|
filling-ibase.png : override CROP=256x256 131x131+15+79
|
||||||
flip-ibase.png : override CROP=288x288 145x145+120+72
|
flip-ibase.png : override CROP=288x288 145x145+120+72
|
||||||
galaxies-ibase.png : override CROP=288x288 165x165+0+0
|
galaxies-ibase.png : override CROP=288x288 165x165+0+0
|
||||||
guess-ibase.png : override CROP=263x420 178x178+75+17
|
guess-ibase.png : override CROP=263x420 178x178+75+17
|
||||||
|
38
icons/filling.sav
Normal file
38
icons/filling.sav
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
|
||||||
|
VERSION :1:1
|
||||||
|
GAME :7:Filling
|
||||||
|
PARAMS :3:7x7
|
||||||
|
CPARAMS :3:7x7
|
||||||
|
SEED :15:279172739852696
|
||||||
|
DESC :49:0000000031051240010004000001106171000400001013105
|
||||||
|
NSTATES :2:30
|
||||||
|
STATEPOS:2:13
|
||||||
|
MOVE :4:38_3
|
||||||
|
MOVE :4:39_3
|
||||||
|
MOVE :4:36_4
|
||||||
|
MOVE :4:43_4
|
||||||
|
MOVE :4:35_4
|
||||||
|
MOVE :4:47_5
|
||||||
|
MOVE :4:40_5
|
||||||
|
MOVE :4:34_5
|
||||||
|
MOVE :4:41_5
|
||||||
|
MOVE :4:25_7
|
||||||
|
MOVE :4:23_6
|
||||||
|
MOVE :4:16_6
|
||||||
|
MOVE :4:18_7
|
||||||
|
MOVE :4:19_7
|
||||||
|
MOVE :4:20_7
|
||||||
|
MOVE :4:26_7
|
||||||
|
MOVE :4:24_7
|
||||||
|
MOVE :4:29_6
|
||||||
|
MOVE :4:22_6
|
||||||
|
MOVE :4:15_6
|
||||||
|
MOVE :3:7_4
|
||||||
|
MOVE :3:0_4
|
||||||
|
MOVE :3:1_3
|
||||||
|
MOVE :3:2_3
|
||||||
|
MOVE :3:6_2
|
||||||
|
MOVE :3:5_5
|
||||||
|
MOVE :3:4_5
|
||||||
|
MOVE :3:3_5
|
||||||
|
MOVE :4:10_5
|
42
puzzles.but
42
puzzles.but
@ -2204,12 +2204,52 @@ difficulty level may require backtracking.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\C{filling} \i{Filling}
|
||||||
|
|
||||||
|
\cfg{winhelp-topic}{games.filling}
|
||||||
|
|
||||||
|
You have a grid of squares, some of which contain digits, and the
|
||||||
|
rest of which are empty. Your job is to fill in digits in the empty
|
||||||
|
squares, in such a way that each connected region of squares all
|
||||||
|
containing the same digit has an area equal to that digit.
|
||||||
|
|
||||||
|
(\q{Connected region}, for the purposes of this game, does not count
|
||||||
|
diagonally separated squares as adjacent.)
|
||||||
|
|
||||||
|
For example, it follows that no square can contain a zero, and that
|
||||||
|
two adjacent squares can not both contain a one. No region has an
|
||||||
|
area greater than 9 (because then its area would not be a single
|
||||||
|
digit).
|
||||||
|
|
||||||
|
Credit for this puzzle goes to \i{Nikoli} \k{nikoli-fillomino}.
|
||||||
|
|
||||||
|
Filling was contributed to this collection by Jonas K\u00F6{oe}lker.
|
||||||
|
|
||||||
|
\B{nikoli-fillomino}
|
||||||
|
\W{http://www.nikoli.co.jp/en/puzzles/fillomino/}\cw{http://www.nikoli.co.jp/en/puzzles/fillomino/}
|
||||||
|
|
||||||
|
\H{filling-controls} \I{controls, for Filling}Filling controls
|
||||||
|
|
||||||
|
To play Filling, simply click the mouse in any empty square and then
|
||||||
|
type a digit on the keyboard to fill that square. If you make a
|
||||||
|
mistake, click the mouse in the incorrect square and press 0, Space,
|
||||||
|
Backspace or Enter to clear it again (or use the Undo feature).
|
||||||
|
|
||||||
|
(All the actions described in \k{common-actions} are also available.)
|
||||||
|
|
||||||
|
\H{filling-parameters} \I{parameters, for Filling}Filling parameters
|
||||||
|
|
||||||
|
Filling allows you to configure the number of rows and columns of the
|
||||||
|
grid, through the \q{Type} menu.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\A{licence} \I{MIT licence}\ii{Licence}
|
\A{licence} \I{MIT licence}\ii{Licence}
|
||||||
|
|
||||||
This software is \i{copyright} 2004-2007 Simon Tatham.
|
This software is \i{copyright} 2004-2007 Simon Tatham.
|
||||||
|
|
||||||
Portions copyright Richard Boulton, James Harvey and Mike Pinna.
|
Portions copyright Richard Boulton, James Harvey, Mike Pinna and
|
||||||
|
Jonas K\u00F6{oe}lker.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation files
|
obtaining a copy of this software and associated documentation files
|
||||||
|
@ -288,6 +288,7 @@ void print_dsf(int *dsf, int size);
|
|||||||
* indicating whether the canonical element is inverse to val. */
|
* indicating whether the canonical element is inverse to val. */
|
||||||
int edsf_canonify(int *dsf, int val, int *inverse);
|
int edsf_canonify(int *dsf, int val, int *inverse);
|
||||||
int dsf_canonify(int *dsf, int val);
|
int dsf_canonify(int *dsf, int val);
|
||||||
|
int dsf_size(int *dsf, int val);
|
||||||
|
|
||||||
/* Allow the caller to specify that two elements should be in the same
|
/* Allow the caller to specify that two elements should be in the same
|
||||||
* equivalence class. If 'inverse' is TRUE, the elements are actually opposite
|
* equivalence class. If 'inverse' is TRUE, the elements are actually opposite
|
||||||
|
Reference in New Issue
Block a user