001: /*
002: 
003:   File: Puzzle.cpp
004: 
005:   (c) 2003 by Oliver Ehli
006: 
007:      This program is free software; you can redistribute it and/or modify
008:      it under the terms of the GNU General Public License as published by
009:      the Free Software Foundation; either version 2 of the License, or
010:      (at your option) any later version.
011: 
012:      This program is distributed in the hope that it will be useful,
013:      but WITHOUT ANY WARRANTY; without even the implied warranty of
014:      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015:      GNU General Public License for more details.
016: 
017:      You should have received a copy of the GNU General Public License
018:      along with this program; if not, write to the Free Software
019:      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
020: 
021:      See File LICENSE for more Information.
022: 
023: */
024: #include <stdlib.h>
025: #include <iostream.h>
026: #include "Puzzle.h"
027: 
028: 
029: 
030: 
031: long long Puzzle::translateToOrigin(long long piece)
032: {
033: 
034:   int xMin=GC_X_DIM;
035:   for (int k=0; k < GC_Z_DIM; k++)
036:     for (int j=0; j < GC_Y_DIM; j++) {
037:       long long mask = (1ll << (k*GC_Y_DIM*GC_X_DIM) << j*GC_X_DIM);
038:       for (int i=0; i < GC_X_DIM; i++)
039:         if(piece & (mask<<i) && i < xMin) xMin = i;
040:     }
041: 
042:   int yMin=GC_Y_DIM;
043:   for (int k=0; k < GC_Z_DIM; k++)
044:     for (int j=0; j < GC_Y_DIM; j++) {
045:       long long mask = (1ll << (k*GC_Y_DIM*GC_X_DIM) << j*GC_X_DIM);
046:       for (int i=0; i < GC_X_DIM; i++)
047:         if(piece & (mask<<i) && j < yMin) yMin = j;
048:     }
049: 
050:   int zMin=GC_Z_DIM;
051:   for (int k=0; k < GC_Z_DIM; k++)
052:     for (int j=0; j < GC_Y_DIM; j++) {
053:       long long mask = (1ll << (k*GC_Y_DIM*GC_X_DIM) << j*GC_X_DIM);
054:       for (int i=0; i < GC_X_DIM; i++)
055:         if(piece & (mask<<i) && k < zMin) zMin = k;
056:     }
057: 
058:   return (((piece >> xMin) >> (yMin*GC_X_DIM)) >> (zMin*GC_X_DIM*GC_Y_DIM)) ;
059: }
060: 
061: 
062: long long Puzzle::rotate(long long piece, int xAngle, int yAngle, int zAngle, int bbox[], int xMask)
063: {
064:   if(xAngle) return xRotate(piece, xAngle, yAngle, zAngle, bbox, xMask);
065:   if(yAngle) return yRotate(piece, xAngle, yAngle, zAngle, bbox, xMask);
066:   if(zAngle) return zRotate(piece, xAngle, yAngle, zAngle, bbox, xMask);
067: 
068:   return piece;
069: }
070: 
071: 
072: 
073: 
074: 
075: long long Puzzle::zRotate(long long inPiece, int xAngle, int yAngle, int zAngle,
076:                      int bbox[], int xMask)
077: {
078:   long long piece;
079:   long long result;
080: 
081:   result = inPiece;
082: 
083: 
084:   if(zAngle>=2) {
085:     piece = result;
086:     result = 0;
087: 
088:     long long mask = 1;
089:     for (int i = 0; i < GC_Z_DIM; i++) {
090:       for (int j = 0; j < GC_Y_DIM; j++)
091:         for (int k = 0; k < GC_X_DIM; k++, mask <<= 1) {
092:           if(piece & mask)
093:             result |= ((1ll << (i*GC_Y_DIM*GC_X_DIM))
094:                        << ((GC_Y_DIM-1-j)*GC_X_DIM)) << (GC_X_DIM-1-k);
095:         }
096:     }
097:     result = translateToOrigin(result);
098:   }
099: 
100: 
101:   if(zAngle%2) {
102:     piece = result;
103:     result = 0;
104: 
105:     long long mask = 1;
106:     for (int i = 0; i < GC_Z_DIM; i++) {
107:       for (int j = 0; j < GC_Y_DIM; j++)
108:         for (int k = 0; k < GC_X_DIM; k++, mask <<= 1) {
109:           if(!(piece & mask) || k >= GC_Y_DIM || j >= GC_X_DIM) continue;
110:           result |= ((1ll << (i*GC_Y_DIM*GC_X_DIM))
111:                      << (k*GC_X_DIM)) << (GC_X_DIM-1-j);
112:         }
113:     }
114:     result = translateToOrigin(result);
115:   }
116:   return result;
117: }
118: 
119: 
120: 
121: long long Puzzle::yRotate(long long inPiece, int xAngle, int yAngle, int zAngle,
122:                           int bbox[], int xMask)
123: {
124:   long long  piece;
125:   long long result;
126: 
127:   result = inPiece;
128: 
129:   if(yAngle>=2) {
130:     piece = result;
131:     result = 0;
132: 
133:     long long mask = 1;
134:     for (int i = 0; i < GC_Z_DIM; i++)
135:       for (int j = 0; j < GC_Y_DIM; j++)
136:         for (int k = 0; k < GC_X_DIM; k++, mask <<= 1) {
137:           if(piece & mask)
138:             result |= ((1ll << (GC_X_DIM-1-k)) << (j*GC_X_DIM))
139:                                        << ((GC_Z_DIM-1-i)*GC_Y_DIM*GC_X_DIM);
140:         }
141: 
142:     result = translateToOrigin(result);
143:   }
144: 
145:   if(yAngle %2) {
146:     piece = result;
147:     result = 0;
148: 
149:     long long mask = 1;
150:     for (int i = 0; i < GC_Z_DIM; i++)
151:       for (int j = 0; j < GC_Y_DIM; j++)
152:         for (int k = 0; k < GC_X_DIM; k++, mask <<= 1) {
153:           if(!(piece & mask) ||(k >= GC_Z_DIM || i >= GC_X_DIM)) continue;
154:           result |= ((1ll << (GC_X_DIM-1-i)) << (j*GC_X_DIM)) << (k*GC_Y_DIM*GC_X_DIM);
155:         }
156: 
157:     result = translateToOrigin(result);
158:   }
159:   return result;
160: }
161: 
162: 
163: 
164: 
165: 
166: 
167: long long Puzzle::xRotate(long long inPiece, int xAngle, int yAngle, int zAngle,
168:                           int bbox[], int xMask)
169: {
170:   long long  piece;
171:   long long result;
172: 
173:   result = inPiece;
174: 
175:   if(xAngle >= 2) {
176:     long long mask = 1;
177:     piece = result;
178:     result = 0;
179: 
180:     for (int i = 0; i < GC_Z_DIM; i++)
181:       for (int j = 0; j < GC_Y_DIM; j++)
182:         for (int k = 0; k < GC_X_DIM; k++, mask <<= 1) {
183:           if(!(piece & mask) || ((xAngle%2 && (j >= GC_Z_DIM || i >= GC_Y_DIM)))) continue;
184:           result |= ((1ll << k) << ((GC_Y_DIM-1-j)*GC_X_DIM)) << ((GC_Z_DIM-1-i)*GC_Y_DIM*GC_X_DIM);
185:         }
186:     result = translateToOrigin(result);
187:   }
188: 
189:   if(xAngle %2) {
190:     long long mask = 1;
191:     piece = result;
192:     result = 0;
193: 
194:     for (int i = 0; i < GC_Z_DIM; i++)
195:       for (int j = 0; j < GC_Y_DIM; j++)
196:         for (int k = 0; k < GC_X_DIM; k++, mask <<= 1) {
197:           if(!(piece & mask) || ((xAngle%2 && (j >= GC_Z_DIM || i >= GC_Y_DIM)))) continue;
198:           result |= ((1ll << k) << ((i)*GC_X_DIM)) << ((GC_Z_DIM-1-j)*GC_Y_DIM*GC_X_DIM);
199:         }
200:     result = translateToOrigin(result);
201:   }
202: 
203: 
204:   return result;
205: }
206: 
207: 
208: // setup puzzle..
209: #include "PuzzlePieces.h"
210: 
211: 
212: Puzzle::PieceDescription Puzzle::piece_desc[] =
213:     {
214:      { &piece8_dim,  &piece8_desc },
215:      { &piece11_dim,  &piece11_desc },
216:      { &piece4_dim,  &piece4_desc },
217:      { &piece5_dim,  &piece5_desc },
218:      { &piece3_dim,  &piece3_desc }, // #define T_PIECE        4
219:      { &piece10_dim,  &piece10_desc },
220:      { &piece12_dim,  &piece12_desc },
221:      { &piece1_dim, &piece1_desc },  // #define C_PIECE        7
222:      { &piece9_dim,  &piece9_desc },
223:      { &piece2_dim,  &piece2_desc },
224:      { &piece6_dim, &piece6_desc },
225:      { &piece7_dim, &piece7_desc },// #define APO1_PIECE     11
226:     };
227: 
228: