New puzzle: `Filling', a Fillomino implementation by Jonas Koelker.

[originally from svn r7326]
This commit is contained in:
Simon Tatham
2007-02-25 11:37:05 +00:00
parent 8b1b6bc9a3
commit df31d4f419
8 changed files with 1677 additions and 17 deletions

View File

@ -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
View File

@ -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
View 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

1539
filling.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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

View File

@ -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

View File

@ -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