[go: up one dir, main page]

Menu

[190a4b]: / lib / isoplane.c  Maximize  Restore  History

Download this file

192 lines (174 with data), 5.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/**
* @file
* Code to deal with 4x4 planes within the board.
*
* Last Modified: Sat Dec 27 09:16:23 PST 2014
* @author Kevin O'Gorman
*/
/*
* Copyright 2012-2014 Kevin O'Gorman <kogorman@gmail.com>.
* Distributed under the GNU General Public License.
*
* This file is part of libqubist, the library of functions for playing
* 4x4x4 tic-tac-toe, also known by some other names outside the USA.
*
* Libqubist is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2.
*
* Libqubist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* @file
* Code to do various things with individual planes of the qube. Not currently used by
* the game engine, but may be of interest to other progams that use this library.
*
* The Qubic board (Qube) has 18 4x4 planes. Each can be thought of as an intersection
* of an infinite plane with the Qube. The count of 18 may seem a bit large if you're
* thinking just of planes that are perpedicular to an axis. It would be, but there are
* other planes that can form 4x4 intersections.
*
* There are 4 planes that are perpendicular to each axis, and 3 axes to form them for a
* total of 12 such planes. There are 6 additional, diagonal planes, each one
* intersecting two opposite edges of the Qube; there are 12 edges total, and thus 6
* diagonal planes. Thus, 18 planes.
*
* Each row is found in two or three different planes. Edge rows, interior rows and
* non-major diagoanl rows are found in two of the perpedicular planes and one diagonal
* plane. Other parallel rows (that do not contain any highly-connected squares) are
* found in two perpendicular planes. Major-diagonal rows are found in three diagonal
* planes.
*
* More information is contained in the iso.c comments.
*/
#include <stdlib.h>
#include <stdio.h>
#include "state.h"
#include "isoplane.h"
#undef NDEBUG
#define NDEBUG
#include <assert.h>
/**
* Array of isomorphisms. The initializer seeds it with the generators,
* and the code forms a kind of transitive closure.
*/
static int planeisos[64][16] = {
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, /* identity */
{12,8,4,0,13,9,5,1,14,10,6,2,15,11,7,3}, /* rotate clockwise */
{3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12}, /* mirror horizontally across vertical axis */
{5,4,7,6,1,0,3,2,13,12,15,14,9,8,11,10}, /* inside-out */
{0,2,1,3,8,10,9,11,4,6,5,7,12,14,13,15}}; /* inside scramble */
/** Count of the isos, intially 5 but should reach 64 */
static int isocount = 5;
#if 0 /* not yet implemented */
/**
* The 10 winning rows on the plane:
* 4 horizontal
* 4 vertical
* 2 diagonals
*/
static int planerows[10][4] = {
{ 0, 1, 2, 3},
{ 4, 5, 6, 7},
{ 8, 9,10,11},
{12,13,14,15},
{ 0, 4, 8,12},
{ 1, 5, 9,13},
{ 2, 6,10,14},
{ 3, 7,11,15},
{ 1, 5,10,15},
{ 3, 6, 9,12}};
static int rowvalues[10];
#endif
/**
* Predicate to tell if an iso is identical to any other that comes before.
*/
static int
qb_plane_isnew(int iso) {
int i, j;
for (i = 0; i < iso; i++) {
for (j = 0; j < 16; j++) {
if (planeisos[i][j] != planeisos[iso][j]) {
break;
}
}
if (j == 16) {
/* equal */
return 0; /* not new */
}
}
return 1;
}
/**
* Initialize the list of isomorphisms of the Qubic plane.
*/
void
qb_plane_create_isos(void) {
int i, j, k;
int nextiso = isocount;
for (i = 1; i < nextiso; i++) {
for (j = 0; j < i; j++) {
for (k = 0; k < 16; k++) {
planeisos[nextiso][k] = planeisos[i][planeisos[j][k]];
}
if (qb_plane_isnew(nextiso)) {
nextiso++;
isocount = nextiso;
break;
}
}
}
#ifndef NDEBUG
printf("There are %d isomorphisms of the Qubic plane.\n", isocount);
for (i = 0; i < isocount; i++) {
printf("%d ", i);
for (j = 0; j < 16; j++) {
printf("%3d", planeisos[i][j]);
}
putchar('\n');
}
#endif
}
int
qb_plane_find_canonic_iso(char *pos) {
int m, iso, bestiso;
bestiso = 0;
for (iso = 1; iso < isocount; iso++) {
for (m = 0; m < 16; m++) {
if (pos[planeisos[iso][m]] > pos[planeisos[bestiso][m]]) {
bestiso = iso;
break;
}
if (pos[planeisos[iso][m]] < pos[planeisos[bestiso][m]]) {
break;
}
}
}
return bestiso;
}
/**
* Interrogate a position in one of the isomorphisms.
*/
int
qb_plane_get_iso_spot(int iso, int spot) {
return planeisos[iso][spot];
}
/**
* Write a resentation of a position, as seen through an isomorphism.
*/
void
qb_write_plane_through_iso(char *pos, int iso, FILE *stream) {
int m;
for (m = 0; m < 16; m++) {
fputc(pos[planeisos[iso][m]], stream);
}
fputc('\n', stream);
}
/* vim: set expandtab autoindent shiftround nosmartindent tabstop=8 softtabstop=2 shiftwidth=2: */