mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
New grid type: the trihexagonal tiling, or 'kagome lattice'.
Regular hexagons and equilateral triangles in strict alternation, with two of each interleaved around each vertex. https://en.wikipedia.org/wiki/Trihexagonal_tiling Thanks to Michael Quevillon for the patch.
This commit is contained in:
3
LICENCE
3
LICENCE
@ -2,7 +2,8 @@ This software is copyright (c) 2004-2014 Simon Tatham.
|
|||||||
|
|
||||||
Portions copyright Richard Boulton, James Harvey, Mike Pinna, Jonas
|
Portions copyright Richard Boulton, James Harvey, Mike Pinna, Jonas
|
||||||
K<EFBFBD>lker, Dariusz Olszewski, Michael Schierl, Lambros Lambrou, Bernd
|
K<EFBFBD>lker, Dariusz Olszewski, Michael Schierl, Lambros Lambrou, Bernd
|
||||||
Schmidt, Steffen Bauer, Lennard Sprong and Rogier Goossens.
|
Schmidt, Steffen Bauer, Lennard Sprong, Rogier Goossens and Michael
|
||||||
|
Quevillon.
|
||||||
|
|
||||||
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
|
||||||
|
96
grid.c
96
grid.c
@ -2060,6 +2060,102 @@ static grid *grid_new_greathexagonal(int width, int height, const char *desc)
|
|||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define KAGOME_TILESIZE 18
|
||||||
|
/* Vector for side of triangle - ratio is close to sqrt(3) */
|
||||||
|
#define KAGOME_A 15
|
||||||
|
#define KAGOME_B 26
|
||||||
|
|
||||||
|
static void grid_size_kagome(int width, int height,
|
||||||
|
int *tilesize, int *xextent, int *yextent)
|
||||||
|
{
|
||||||
|
int a = KAGOME_A;
|
||||||
|
int b = KAGOME_B;
|
||||||
|
|
||||||
|
*tilesize = KAGOME_TILESIZE;
|
||||||
|
*xextent = (4*a) * (width-1) + 6*a;
|
||||||
|
*yextent = (2*b) * (height-1) + 2*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grid *grid_new_kagome(int width, int height, const char *desc)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
int a = KAGOME_A;
|
||||||
|
int b = KAGOME_B;
|
||||||
|
|
||||||
|
/* Upper bounds - don't have to be exact */
|
||||||
|
int max_faces = 6 * (width + 1) * (height + 1);
|
||||||
|
int max_dots = 6 * width * height;
|
||||||
|
|
||||||
|
tree234 *points;
|
||||||
|
|
||||||
|
grid *g = grid_empty();
|
||||||
|
g->tilesize = KAGOME_TILESIZE;
|
||||||
|
g->faces = snewn(max_faces, grid_face);
|
||||||
|
g->dots = snewn(max_dots, grid_dot);
|
||||||
|
|
||||||
|
points = newtree234(grid_point_cmp_fn);
|
||||||
|
|
||||||
|
for (y = 0; y < height; y++) {
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
grid_dot *d;
|
||||||
|
/* centre of hexagon */
|
||||||
|
int px = (4*a) * x;
|
||||||
|
int py = (2*b) * y;
|
||||||
|
if (y % 2)
|
||||||
|
px += 2*a;
|
||||||
|
|
||||||
|
/* hexagon */
|
||||||
|
grid_face_add_new(g, 6);
|
||||||
|
d = grid_get_dot(g, points, px + a, py - b); grid_face_set_dot(g, d, 0);
|
||||||
|
d = grid_get_dot(g, points, px + 2*a, py ); grid_face_set_dot(g, d, 1);
|
||||||
|
d = grid_get_dot(g, points, px + a, py + b); grid_face_set_dot(g, d, 2);
|
||||||
|
d = grid_get_dot(g, points, px - a, py + b); grid_face_set_dot(g, d, 3);
|
||||||
|
d = grid_get_dot(g, points, px - 2*a, py ); grid_face_set_dot(g, d, 4);
|
||||||
|
d = grid_get_dot(g, points, px - a, py - b); grid_face_set_dot(g, d, 5);
|
||||||
|
|
||||||
|
/* Triangle above right */
|
||||||
|
if ((x < width - 1) || (!(y % 2) && y)) {
|
||||||
|
grid_face_add_new(g, 3);
|
||||||
|
d = grid_get_dot(g, points, px + 3*a, py - b); grid_face_set_dot(g, d, 0);
|
||||||
|
d = grid_get_dot(g, points, px + 2*a, py ); grid_face_set_dot(g, d, 1);
|
||||||
|
d = grid_get_dot(g, points, px + a, py - b); grid_face_set_dot(g, d, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Triangle below right */
|
||||||
|
if ((x < width - 1) || (!(y % 2) && (y < height - 1))) {
|
||||||
|
grid_face_add_new(g, 3);
|
||||||
|
d = grid_get_dot(g, points, px + 3*a, py + b); grid_face_set_dot(g, d, 0);
|
||||||
|
d = grid_get_dot(g, points, px + a, py + b); grid_face_set_dot(g, d, 1);
|
||||||
|
d = grid_get_dot(g, points, px + 2*a, py ); grid_face_set_dot(g, d, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Left triangles */
|
||||||
|
if (!x && (y % 2)) {
|
||||||
|
/* Triangle above left */
|
||||||
|
grid_face_add_new(g, 3);
|
||||||
|
d = grid_get_dot(g, points, px - a, py - b); grid_face_set_dot(g, d, 0);
|
||||||
|
d = grid_get_dot(g, points, px - 2*a, py ); grid_face_set_dot(g, d, 1);
|
||||||
|
d = grid_get_dot(g, points, px - 3*a, py - b); grid_face_set_dot(g, d, 2);
|
||||||
|
|
||||||
|
/* Triangle below left */
|
||||||
|
if (y < height - 1) {
|
||||||
|
grid_face_add_new(g, 3);
|
||||||
|
d = grid_get_dot(g, points, px - a, py + b); grid_face_set_dot(g, d, 0);
|
||||||
|
d = grid_get_dot(g, points, px - 3*a, py + b); grid_face_set_dot(g, d, 1);
|
||||||
|
d = grid_get_dot(g, points, px - 2*a, py ); grid_face_set_dot(g, d, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freetree234(points);
|
||||||
|
assert(g->num_faces <= max_faces);
|
||||||
|
assert(g->num_dots <= max_dots);
|
||||||
|
|
||||||
|
grid_make_consistent(g);
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
#define OCTAGONAL_TILESIZE 40
|
#define OCTAGONAL_TILESIZE 40
|
||||||
/* b/a approx sqrt(2) */
|
/* b/a approx sqrt(2) */
|
||||||
#define OCTAGONAL_A 29
|
#define OCTAGONAL_A 29
|
||||||
|
1
grid.h
1
grid.h
@ -100,6 +100,7 @@ typedef struct grid {
|
|||||||
A(SNUBSQUARE,snubsquare) \
|
A(SNUBSQUARE,snubsquare) \
|
||||||
A(CAIRO,cairo) \
|
A(CAIRO,cairo) \
|
||||||
A(GREATHEXAGONAL,greathexagonal) \
|
A(GREATHEXAGONAL,greathexagonal) \
|
||||||
|
A(KAGOME,kagome) \
|
||||||
A(OCTAGONAL,octagonal) \
|
A(OCTAGONAL,octagonal) \
|
||||||
A(KITE,kites) \
|
A(KITE,kites) \
|
||||||
A(FLORET,floret) \
|
A(FLORET,floret) \
|
||||||
|
3
loopy.c
3
loopy.c
@ -278,6 +278,7 @@ static void check_caches(const solver_state* sstate);
|
|||||||
A("Penrose (kite/dart)",PENROSE_P2,3,3) \
|
A("Penrose (kite/dart)",PENROSE_P2,3,3) \
|
||||||
A("Penrose (rhombs)",PENROSE_P3,3,3) \
|
A("Penrose (rhombs)",PENROSE_P3,3,3) \
|
||||||
A("Great-Great-Dodecagonal",GREATGREATDODECAGONAL,2,2) \
|
A("Great-Great-Dodecagonal",GREATGREATDODECAGONAL,2,2) \
|
||||||
|
A("Kagome",KAGOME,3,3) \
|
||||||
/* end of list */
|
/* end of list */
|
||||||
|
|
||||||
#define GRID_NAME(title,type,amin,omin) title,
|
#define GRID_NAME(title,type,amin,omin) title,
|
||||||
@ -544,6 +545,7 @@ static const game_params loopy_presets_more[] = {
|
|||||||
#ifdef SMALL_SCREEN
|
#ifdef SMALL_SCREEN
|
||||||
{ 7, 7, DIFF_HARD, LOOPY_GRID_HONEYCOMB },
|
{ 7, 7, DIFF_HARD, LOOPY_GRID_HONEYCOMB },
|
||||||
{ 5, 4, DIFF_HARD, LOOPY_GRID_GREATHEXAGONAL },
|
{ 5, 4, DIFF_HARD, LOOPY_GRID_GREATHEXAGONAL },
|
||||||
|
{ 5, 4, DIFF_HARD, LOOPY_GRID_KAGOME },
|
||||||
{ 5, 5, DIFF_HARD, LOOPY_GRID_OCTAGONAL },
|
{ 5, 5, DIFF_HARD, LOOPY_GRID_OCTAGONAL },
|
||||||
{ 3, 3, DIFF_HARD, LOOPY_GRID_FLORET },
|
{ 3, 3, DIFF_HARD, LOOPY_GRID_FLORET },
|
||||||
{ 3, 3, DIFF_HARD, LOOPY_GRID_DODECAGONAL },
|
{ 3, 3, DIFF_HARD, LOOPY_GRID_DODECAGONAL },
|
||||||
@ -552,6 +554,7 @@ static const game_params loopy_presets_more[] = {
|
|||||||
#else
|
#else
|
||||||
{ 10, 10, DIFF_HARD, LOOPY_GRID_HONEYCOMB },
|
{ 10, 10, DIFF_HARD, LOOPY_GRID_HONEYCOMB },
|
||||||
{ 5, 4, DIFF_HARD, LOOPY_GRID_GREATHEXAGONAL },
|
{ 5, 4, DIFF_HARD, LOOPY_GRID_GREATHEXAGONAL },
|
||||||
|
{ 5, 4, DIFF_HARD, LOOPY_GRID_KAGOME },
|
||||||
{ 7, 7, DIFF_HARD, LOOPY_GRID_OCTAGONAL },
|
{ 7, 7, DIFF_HARD, LOOPY_GRID_OCTAGONAL },
|
||||||
{ 5, 5, DIFF_HARD, LOOPY_GRID_FLORET },
|
{ 5, 5, DIFF_HARD, LOOPY_GRID_FLORET },
|
||||||
{ 5, 4, DIFF_HARD, LOOPY_GRID_DODECAGONAL },
|
{ 5, 4, DIFF_HARD, LOOPY_GRID_DODECAGONAL },
|
||||||
|
Reference in New Issue
Block a user