0001: /* ct_puzzle.c

0002:  * by Arnold Wendl, Fürth, anno Domini 2003

0003:  bcc32 -6 -O2

0004:  */
0005: /* eventuell bei UNIX-Compiler noetig:

0006:  * #define __int64  long long

0007:  */
0008: #include <stdio.h>
0009: #include <mem.h>
0010: #include <malloc.h>
0011: #include <windows.h> /* Zeiterfassung - wohl nichts fuer UNIX - und auch die Codepageumschaltung */
0012: 
0013: #define ERGEBNIS  "ct_puzzle_erg.bin"
0014: #define VERBOSE
0015: #define NO_ZAEHLE_LEGUNGEN
0016: #define NO_VERBOSE_1
0017: #define NO_RESULT_CHAIN
0018: // #define SLP_WUERFELGROESSE 10.0

0019: // #define SLP_ERGOUT

0020: // #define MELDUNGSHAEUFIGKEIT 0x1fff

0021: #define MELDUNGSHAEUFIGKEIT 0x03ff
0022: // #define MELDUNGSHAEUFIGKEIT 0x03f

0023: #define DONOT_DEBUGING
0024: #define DONOT_UNTERSCHEIDE_TEXT
0025: #define DONOT_DUMP_TABLE_1
0026: #define DONOT_DUMP_TABLE_2
0027: 
0028: // #define PRESHIFT

0029: // #define MULTISHIFT

0030: 
0031: #ifdef SLP_WUERFELGROESSE
0032: #include <dir.h>
0033: #endif

0034: 
0035: #define SZ1 3
0036: #define SZ2 4
0037: #define SZ3 5
0038: 
0039: #define MAX_TEILWUERFEL    6
0040: #define BAUSTEINZAHL      12
0041: #define BESCHRAENKT_ROTIERTER_BAUSTEIN  6 /* 0 .. BAUSTEINZAHL - 1 (2, 3, 4, 6, 9, 11 */
0042:  /* Gut: 2 mit A4, C2, D4, D2 oder 6 mit A4, B3, C1 bzw. C4, D2, E4, F1 */
0043: #define EINSETZTABELLE   183
0044: #define EINSETZPUNKTE    (SZ1*SZ2*SZ3)
0045: #define KLASSEN          (EINSETZPUNKTE * BAUSTEINZAHL)
0046: #define MAGAZINGROESSE  3132 /* 2964 */
0047: 
0048: 
0049: #define KASTEN_1         {SZ3,SZ2,SZ1}
0050: #define KASTEN_2         {SZ3,SZ1,SZ2}
0051: #define KASTEN_3         {SZ2,SZ3,SZ1}
0052: #define KASTEN_4         {SZ2,SZ1,SZ3}
0053: #define KASTEN_5         {SZ1,SZ3,SZ2}
0054: #define KASTEN_6         {SZ1,SZ2,SZ3}
0055: #define KASTEN_GR        KASTEN_1
0056: #define FUELLKOORDINATE_1 2
0057: #define FUELLKOORDINATE_2 1
0058: #define FUELLKOORDINATE_3 0
0059: int FUELL_BM_FAKTOR_2, FUELL_BM_FAKTOR_3;
0060: 
0061: unsigned long Zeiterfassung_Init = 0,
0062:               Zeiterfassung_Suchen = 0,
0063:               Zeiterfassung_Ausgabe =0,
0064:               Zeiterfassung_Start;
0065: int           Zeiterfassung_Art = 0;
0066: #define ZEITERFASSUNG_INIT    1
0067: #define ZEITERFASSUNG_SUCHEN  2
0068: #define ZEITERFASSUNG_AUSGABE 3
0069: #define ZEITERFASSUNG_ENDE    0
0070: 
0071: unsigned long Resultate = 0;
0072: #ifdef ZAEHLE_LEGUNGEN
0073: #pragma option push -a8
0074: unsigned __int64 Legungen = 0, Ands = 0,
0075:                  LegungenA[BAUSTEINZAHL][25] = {
0076:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0077:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0078:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0079:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0080:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0081:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0082:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0083:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0084:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0085:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0086:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0087:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
0088:                  AndsA[BAUSTEINZAHL][25]     = {
0089:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0090:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0091:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0092:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0093:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0094:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0095:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0096:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0097:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0098:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0099:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0100:                    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
0101: #pragma option pop
0102: #endif

0103: 
0104: void Geschwindigkeitserfassung(void)
0105: { unsigned long Jetztzeit;
0106:   long double Zeitdauer, Ausgabezeitdauer;
0107: #ifdef ZAEHLE_LEGUNGEN
0108:   void PrintLegungen(void);
0109: #endif

0110:   Zeitdauer = ((long double) (GetTickCount() - Zeiterfassung_Start + Zeiterfassung_Suchen)) / 1000.0;
0111:   Ausgabezeitdauer = (long double) Zeiterfassung_Ausgabe;
0112:   if (Zeitdauer < 0.0001) Zeitdauer = 0.0001;
0113:   if (Ausgabezeitdauer >= 1000.0)
0114:     fprintf(stderr, " %6lu Lösungen in %5.3Lf s = %4.1Lf Lösungen / s\n"
0115:                     "      zuzüglich %5.3Lf %% für die Ergebnisausgabe\n",
0116:       Resultate, Zeitdauer, ((long double) Resultate) / Zeitdauer, Ausgabezeitdauer / Zeitdauer * 0.1);
0117:    else
0118:     fprintf(stderr, " %6lu Lösungen in %5.3Lf s = %4.1Lf Lösungen / s\n",
0119:       Resultate, Zeitdauer, ((long double) Resultate) / Zeitdauer);
0120: #ifdef ZAEHLE_LEGUNGEN
0121:     fprintf(stderr, " %I64u Legungen und %I64u Ands bis jetzt\n", Legungen, Ands);
0122:     PrintLegungen();
0123: #endif

0124: }
0125: 
0126: void Zeiterfassung(int NeueArt)
0127: { unsigned long Jetztzeit;
0128: 
0129:   Jetztzeit = GetTickCount(); /* definiert in windows.h */
0130:   switch (Zeiterfassung_Art) {
0131:     case ZEITERFASSUNG_INIT:
0132:       Zeiterfassung_Init += Jetztzeit - Zeiterfassung_Start;
0133:     break;
0134:     case ZEITERFASSUNG_SUCHEN:
0135:       Zeiterfassung_Suchen += Jetztzeit - Zeiterfassung_Start;
0136:     break;
0137:     case ZEITERFASSUNG_AUSGABE:
0138:       Zeiterfassung_Ausgabe += Jetztzeit - Zeiterfassung_Start;
0139:     break;
0140:   }
0141:   Zeiterfassung_Start = Jetztzeit;
0142:   Zeiterfassung_Art = NeueArt;
0143:   if (!NeueArt) fprintf(stdout, "\n"
0144:                                 "Initialisierung: %9.3Lf s\n"
0145:                                 "Suchen:          %9.3Lf s\n"
0146:                                 "Ergebnisausgabe: %9.3Lf s\n",
0147:      ((long double) Zeiterfassung_Init)    / ((long double) 1000.0),
0148:      ((long double) Zeiterfassung_Suchen)  / ((long double) 1000.0),
0149:      ((long double) Zeiterfassung_Ausgabe) / ((long double) 1000.0));
0150: }
0151: 
0152: // typedef int GrInt;

0153:    typedef char GrInt;
0154: // typedef short GrInt;

0155: 
0156: typedef struct TP_KOORD {
0157:   GrInt KOORD[3];
0158: } KOORD;
0159: static KOORD KOORD_NULLPUNKT = { 0,0,0 };
0160: 
0161: typedef struct TP_MATRIX {
0162:   GrInt MATRIX[12];
0163: } MATRIX;
0164: 
0165: typedef struct TP_BAUSTEIN {
0166:   GrInt Teilwuerfelzahl, Beschriftet;
0167:   /*@ Alle Beschriftungen vom 1. Teilwürfel - immer auf (0,0,0) - aus in z-Richtung */
0168:   KOORD Min, Max, Einzelelemente[MAX_TEILWUERFEL];
0169: } BAUSTEIN;
0170: 
0171: MATRIX RotationsMoeglichkeiten[24];
0172: 
0173: const KOORD Kastengroesse = KASTEN_GR;
0174: 
0175: const BAUSTEIN Baustein[BAUSTEINZAHL] = {
0176: /*  1 */ { 5, 1, { 0, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, { 1, 0, 0}, { 0, 1, 0}, { 0, 2, 0}, { 1, 2, 0}, { 0, 0, 0} } },
0177: /*  2 */ { 5, 1, { 0,-1,-2 }, { 0, 1, 0 }, { { 0, 0, 0}, { 0, 1, 0}, { 0, 0,-1}, { 0, 0,-2}, { 0,-1,-2}, { 0, 0, 0} } },
0178: /*  3 */ { 5, 0, { 0, 0, 0 }, { 1, 3, 0 }, { { 0, 0, 0}, { 1, 0, 0}, { 0, 1, 0}, { 0, 2, 0}, { 0, 3, 0}, { 0, 0, 0} } },
0179: /*  4 */ { 5, 0, { 0, 0, 0 }, { 1, 3, 0 }, { { 0, 0, 0}, { 1, 2, 0}, { 0, 1, 0}, { 0, 2, 0}, { 0, 3, 0}, { 0, 0, 0} } },
0180: /*  5 */ { 5, 1, { 0, 0,-1 }, { 1, 1, 0 }, { { 0, 0, 0}, { 1, 0,-1}, { 0, 1, 0}, { 0, 1,-1}, { 0, 0,-1}, { 0, 0, 0} } },
0181: /*  6 */ { 5, 0, {-1, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, {-1, 2, 0}, { 1, 2, 0}, { 0, 1, 0}, { 0, 2, 0}, { 0, 0, 0} } },
0182: /*  7 */ { 5, 0, { 0, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, { 0, 2, 0}, { 1, 1, 0}, { 0, 1, 0}, { 1, 0, 0}, { 0, 0, 0} } },
0183: /*  8 */ { 5, 0, {-1, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, {-1, 2, 0}, {-1, 1, 0}, { 0, 1, 0}, { 1, 0, 0}, { 0, 0, 0} } },
0184: /*  9 */ { 4, 1, { 0, 0,-1 }, { 1, 1, 0 }, { { 0, 0, 0}, { 1, 1,-1}, { 0, 1, 0}, { 0, 1,-1}, { 0, 0, 0}, { 0, 0, 0} } },
0185: /* 10 */ { 5, 0, {-1, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, { 1, 2, 0}, {-1, 1, 0}, { 0, 1, 0}, { 0, 2, 0}, { 0, 0, 0} } },
0186: /* 11 */ { 5, 0, {-1,-1, 0 }, { 1, 1, 0 }, { { 0, 0, 0}, {-1, 0, 0}, { 0,-1, 0}, { 1, 0, 0}, { 0, 1, 0}, { 0, 0, 0} } },
0187: /* 12 */ { 6, 1, { 0, 0, 0 }, { 1, 3, 0 }, { { 0, 0, 0}, { 0, 3, 0}, { 1, 2, 0}, { 1, 0, 0}, { 0, 1, 0}, { 0, 2, 0} } }
0188: };
0189: 
0190: int EinsetztabelleBelegt = 0;
0191: BAUSTEIN BereitgelegterBaustein[EINSETZTABELLE];
0192: MATRIX   BereitgelegteMatrix[EINSETZTABELLE];
0193: int BausteinBereitgelegtAb[BAUSTEINZAHL + 1];
0194: struct BITMASKEN {
0195:   unsigned __int64 Maske;
0196:   int Versatz[3];
0197: } Bitmasken[EINSETZTABELLE];
0198: 
0199: struct POSITIONIERUNG {
0200:   MATRIX Einsetzpunkt;
0201:   int    eingesetzt;
0202: } Positionierung[BAUSTEINZAHL];
0203: 
0204: #pragma option push -a8
0205: int Klassen[KLASSEN + 1];
0206: unsigned __int64 Magazin[MAGAZINGROESSE];
0207: #ifdef ZAEHLE_LEGUNGEN
0208: unsigned int BausteinMagazinRotId[MAGAZINGROESSE];
0209: #endif

0210: #ifdef ERGEBNIS
0211: unsigned int BausteinMagazinId[MAGAZINGROESSE];
0212: FILE *ergdat = NULL;
0213: #endif

0214: #pragma option pop
0215: 
0216: #ifdef VERBOSE
0217: #ifdef ERGEBNIS
0218: void DumpBausteinId(FILE *aus, unsigned int bsid)
0219: { fprintf(aus, "%2d=%d%c%d%c=%d,%d,%d",
0220:           (bsid >> 12) & 15,
0221:           (bsid >> 10) & 3, ((bsid >> 9) & 1) ? '-' : '+',
0222:           (bsid >>  8) & 1, ((bsid >> 7) & 1) ? '-' : '+',
0223:           (bsid >>  4) & 7,  (bsid >> 2) & 3,  bsid & 3);
0224: }
0225: #endif

0226: 
0227: void DumpBitmask(FILE *aus, unsigned __int64 bm)
0228: { int ct, x1, x2;
0229:   for (ct = x1 = x2 = 0; ct < EINSETZPUNKTE; ct++) {
0230:     fprintf(aus, "%c", (bm & (((unsigned __int64) 1) << ct)) ? '#' : '.');
0231:     if (++x1 >= Kastengroesse.KOORD[FUELLKOORDINATE_1]) {
0232:       fprintf(aus, " "); x1 = 0;
0233:       if (++x2 >= Kastengroesse.KOORD[FUELLKOORDINATE_2]) {
0234:         fprintf(aus, " "); x2 = 0;
0235:       }
0236:     }
0237:   }
0238: }
0239: 
0240: int BitMaskBitCount(unsigned __int64 bm)
0241: { int ct, erg;
0242:   unsigned __int64 m;
0243:   erg = 0; m = 1;
0244:   for (ct = 0; ct < 64; ct++) {
0245:     if (bm & m) erg++;
0246:     m <<= 1;
0247:   }
0248:   return erg;
0249: }
0250: 
0251: void DumpMat(FILE *a, MATRIX mat)
0252: { fprintf(a, "{ %2d,%2d,%2d, %2d,%2d,%2d, %2d,%2d,%2d, %2d,%2d,%2d } (%u)\n",
0253:   mat.MATRIX[0], mat.MATRIX[1], mat.MATRIX[2], mat.MATRIX[3], mat.MATRIX[4], mat.MATRIX[5],
0254:   mat.MATRIX[6], mat.MATRIX[7], mat.MATRIX[8], mat.MATRIX[9], mat.MATRIX[10], mat.MATRIX[11],
0255:   stackavail());
0256: }
0257: #endif

0258: 
0259: #ifdef DEBUGING
0260: #define DUMP_MAT(a) DumpMat(stderr, a);
0261: 
0262: int MatDet(MATRIX mat)
0263: { return (mat.MATRIX[0] * mat.MATRIX[4] * mat.MATRIX[8] - mat.MATRIX[2] * mat.MATRIX[4] * mat.MATRIX[6]
0264:         + mat.MATRIX[3] * mat.MATRIX[7] * mat.MATRIX[2] - mat.MATRIX[5] * mat.MATRIX[7] * mat.MATRIX[0]
0265:         + mat.MATRIX[6] * mat.MATRIX[1] * mat.MATRIX[5] - mat.MATRIX[8] * mat.MATRIX[1] * mat.MATRIX[3]);
0266: }
0267: #endif

0268: 
0269: #ifdef VERBOSE
0270: void DumpBS(FILE *a, BAUSTEIN bs)
0271: { int ct;
0272:   fprintf(a, "{%d,%d, {%2d,%2d,%2d}, {%2d,%2d,%2d}", bs.Teilwuerfelzahl, bs.Beschriftet,
0273:   bs.Min.KOORD[0], bs.Min.KOORD[1], bs.Min.KOORD[2],
0274:   bs.Max.KOORD[0], bs.Max.KOORD[1], bs.Max.KOORD[2]);
0275:   for (ct = 0; ct < bs.Teilwuerfelzahl; ct++)
0276:     fprintf(a, "%s{%2d,%2d,%2d}", ct ? ", " : ", {",
0277:     bs.Einzelelemente[ct].KOORD[0], bs.Einzelelemente[ct].KOORD[1], bs.Einzelelemente[ct].KOORD[2]);
0278:   fprintf(a, "}}\n");
0279: }
0280: #endif

0281: 
0282: #ifdef DEBUGING
0283: void Pause(void)
0284: { char Zeile[200];
0285:   fprintf(stderr, "DEBUG>"); fgets(Zeile, 200, stdin);
0286: }
0287: 
0288: #else

0289: #define DUMP_MAT(a)
0290: #endif

0291: 
0292: #ifdef ERGEBNIS
0293: void PauseWait(void)
0294: { char Zeile[200];
0295:   fprintf(stderr, "Bitte RETURN eingeben>"); fgets(Zeile, 200, stdin);
0296: }
0297: #endif

0298: 
0299: unsigned __int64 ErzeugeBitmaske(BAUSTEIN bs)
0300: /*@ Die entstehende Bitmaske muss so aufgebaut sein, daß die Füllreihenfolge aus einem Einzelbitschieben besteht!

0301:  *@ Natürlich auch bei den verschiedenen Füllrichtungen!

0302:  */
0303: { int versatz[3], ct;
0304:   unsigned __int64 erg;
0305:   erg = 0;
0306:   versatz[0] = - bs.Min.KOORD[0];
0307:   versatz[1] = - bs.Min.KOORD[1];
0308:   versatz[2] = - bs.Min.KOORD[2];
0309:   for (ct = 0; ct < bs.Teilwuerfelzahl; ct++) {
0310:     erg |= ((unsigned __int64) 1) << (                      (bs.Einzelelemente[ct].KOORD[FUELLKOORDINATE_1]
0311:                                                                       + versatz[FUELLKOORDINATE_1])
0312:                              + FUELL_BM_FAKTOR_2 * (bs.Einzelelemente[ct].KOORD[FUELLKOORDINATE_2]
0313:                                                                       + versatz[FUELLKOORDINATE_2])
0314:                              + FUELL_BM_FAKTOR_3 * (bs.Einzelelemente[ct].KOORD[FUELLKOORDINATE_3]
0315:                                                                       + versatz[FUELLKOORDINATE_3]));
0316:   }
0317:   return erg;
0318: }
0319: 
0320: void GetBausteinExtends(BAUSTEIN *bs)
0321: { int ct, xmin, ymin, zmin, xmax, ymax, zmax, w;
0322:   // printf("GetBausteinExtends() ...\n");

0323:   // DumpBS(stdout, *bs);

0324:   xmin = xmax = bs->Einzelelemente[0].KOORD[0];
0325:   ymin = ymax = bs->Einzelelemente[0].KOORD[1];
0326:   zmin = zmax = bs->Einzelelemente[0].KOORD[2];
0327:   for (ct = 1; ct < bs->Teilwuerfelzahl; ct++) {
0328:     if ((w = bs->Einzelelemente[ct].KOORD[0]) > xmax) xmax = w;
0329:     else if (w < xmin) xmin = w;
0330:     if ((w = bs->Einzelelemente[ct].KOORD[1]) > ymax) ymax = w;
0331:     else if (w < ymin) ymin = w;
0332:     if ((w = bs->Einzelelemente[ct].KOORD[2]) > zmax) zmax = w;
0333:     else if (w < zmin) zmin = w;
0334:   }
0335:   bs->Min.KOORD[0] = xmin; bs->Min.KOORD[1] = ymin; bs->Min.KOORD[2] = zmin;
0336:   bs->Max.KOORD[0] = xmax; bs->Max.KOORD[1] = ymax; bs->Max.KOORD[2] = zmax;
0337:   // DumpBS(stdout, *bs);

0338: }
0339: 
0340: void VerschiebeBausteinNullpunktElement(BAUSTEIN *bs)
0341: { int ct;
0342:   if (!(bs->Einzelelemente[0].KOORD[0])
0343:    && !(bs->Einzelelemente[0].KOORD[1])
0344:    && !(bs->Einzelelemente[0].KOORD[2])) return; /* es stimmt schon */
0345:   for (ct = 1; ct < bs->Teilwuerfelzahl; ct++) {
0346:     if (!(bs->Einzelelemente[ct].KOORD[0])
0347:      && !(bs->Einzelelemente[ct].KOORD[1])
0348:      && !(bs->Einzelelemente[ct].KOORD[2])) {
0349:       bs->Einzelelemente[ct] = bs->Einzelelemente[0];
0350:       bs->Einzelelemente[0] = KOORD_NULLPUNKT;
0351:       return;
0352:     }
0353:   }
0354: }
0355: 
0356: int PasstBausteinInKasten(BAUSTEIN bs)
0357: { if (bs.Max.KOORD[0] - bs.Min.KOORD[0] >= Kastengroesse.KOORD[0]) return 0;
0358:   if (bs.Max.KOORD[1] - bs.Min.KOORD[1] >= Kastengroesse.KOORD[1]) return 0;
0359:   if (bs.Max.KOORD[2] - bs.Min.KOORD[2] >= Kastengroesse.KOORD[2]) return 0;
0360:   return 1;
0361: }
0362: 
0363: int PasstBausteinInEinsetzsequenz(BAUSTEIN bs)
0364: /*@ Da dieses Programm eine festgelegte Füllrichtung benutzt, können bestimmte Ausformungen

0365:  *@ nie benötigt werden, da diese in einen sicher schon belegten Bereich hineinragen würden

0366:  */
0367: { int u;
0368:   if (bs.Min.KOORD[FUELLKOORDINATE_3] < 0) return 0;
0369:   for (u = 1; u < bs.Teilwuerfelzahl; u++) {
0370:     if (bs.Einzelelemente[u].KOORD[FUELLKOORDINATE_3] == 0) {
0371:       if (bs.Einzelelemente[u].KOORD[FUELLKOORDINATE_2] < 0) return 0;
0372:       if (bs.Einzelelemente[u].KOORD[FUELLKOORDINATE_2] == 0) {
0373:         if (bs.Einzelelemente[u].KOORD[FUELLKOORDINATE_1] < 0) return 0;
0374:       }
0375:     }
0376:   }
0377:   return 1;
0378: }
0379: 
0380: int TeilSymmetriegleichNeu(BAUSTEIN bs, int suche_ab, unsigned __int64 *bitmaske)
0381: { int ct;
0382:   unsigned __int64 bm;
0383:   *bitmaske = bm = ErzeugeBitmaske(bs);
0384: #ifdef UNTERSCHEIDE_TEXT
0385:   return 1;
0386: #else

0387:   for (ct = suche_ab; (ct < EinsetztabelleBelegt) && (ct < EINSETZTABELLE); ct++)
0388:     if ((bm == Bitmasken[ct].Maske)
0389:      && (Bitmasken[ct].Versatz[0] == - bs.Min.KOORD[0])
0390:      && (Bitmasken[ct].Versatz[1] == - bs.Min.KOORD[1])
0391:      && (Bitmasken[ct].Versatz[2] == - bs.Min.KOORD[2])) return 0;
0392:   return 1;
0393: #endif

0394: }
0395: 
0396: MATRIX Mat1(void)
0397: { MATRIX erg;
0398:         memset(&erg, 0, sizeof(MATRIX));
0399:         erg.MATRIX[0] = erg.MATRIX[4] = erg.MATRIX[8] = 1;
0400:         /* DUMP_MAT(erg) */ return erg;
0401: }
0402: 
0403: MATRIX MatOrthoRot(int Achse, int Winkel)
0404: { MATRIX erg;
0405:         memset(&erg, 0, sizeof(MATRIX));
0406:         switch (Winkel & 3) {
0407:                 case 1:
0408:                         switch (Achse) {
0409:                                 case 0: /* 90° um X-Achse */
0410:                                         erg.MATRIX[0] = erg.MATRIX[5] = 1; erg.MATRIX[7] = -1;
0411:                                         break;
0412:                                 case 1: /* 90° um Y-Achse */
0413:                                         erg.MATRIX[4] = erg.MATRIX[6] = 1; erg.MATRIX[2] = -1;
0414:                                         break;
0415:                                 default: /* 90° um Z-Achse */
0416:                                         erg.MATRIX[1] = erg.MATRIX[8] = 1; erg.MATRIX[3] = -1;
0417:                         }
0418:                         break;
0419:                 case 2:
0420:                         switch (Achse) {
0421:                                 case 0: /* 180° um X-Achse */
0422:                                         erg.MATRIX[0] = 1; erg.MATRIX[4] = erg.MATRIX[8] = -1;
0423:                                         break;
0424:                                 case 1: /* 180° um Y-Achse */
0425:                                         erg.MATRIX[4] = 1; erg.MATRIX[0] = erg.MATRIX[8] = -1;
0426:                                         break;
0427:                                 default: /* 180° um Z-Achse */
0428:                                         erg.MATRIX[8] = 1; erg.MATRIX[0] = erg.MATRIX[4] = -1;
0429:                         }
0430:                         break;
0431:                 case 3:
0432:                         switch (Achse) {
0433:                                 case 0: /* -90° um X-Achse */
0434:                                         erg.MATRIX[0] = erg.MATRIX[7] = 1; erg.MATRIX[5] = -1;
0435:                                         break;
0436:                                 case 1: /* -90° um Y-Achse */
0437:                                         erg.MATRIX[4] = erg.MATRIX[2] = 1; erg.MATRIX[6] = -1;
0438:                                         break;
0439:                                 default: /* -90° um Z-Achse */
0440:                                         erg.MATRIX[3] = erg.MATRIX[8] = 1; erg.MATRIX[1] = -1;
0441:                         }
0442:                         break;
0443:                 default: /* 0° um welche Achse auch immer */
0444:                         erg.MATRIX[0] = erg.MATRIX[4] = erg.MATRIX[8] = 1;
0445:                         break;
0446:         }
0447:         /* DUMP_MAT(erg) */ return erg;
0448: }
0449: 
0450: MATRIX MatVersch3i(int x, int y, int z)
0451: { MATRIX erg;
0452:         memset(&erg, 0, sizeof(MATRIX));
0453:         erg.MATRIX[0] = erg.MATRIX[4] = erg.MATRIX[8] = 1;
0454:         erg.MATRIX[9] = x; erg.MATRIX[10] = y; erg.MATRIX[11] = z;
0455:         /* DUMP_MAT(erg) */ return erg;
0456: }
0457: 
0458: MATRIX MatVerschKoord(KOORD v)
0459: { MATRIX erg;
0460:   memset(&erg, 0, sizeof(MATRIX));
0461:   erg.MATRIX[0] = erg.MATRIX[4] = erg.MATRIX[8] = 1;
0462:   memcpy(((KOORD *) &(erg.MATRIX[9])), &v, 3 * sizeof(GrInt));
0463:   /* DUMP_MAT(erg) */ return erg;
0464: }
0465: 
0466: MATRIX MatMul(MATRIX m1, MATRIX m2)
0467: { MATRIX erg;
0468:   memset(&erg, 0, sizeof(MATRIX));
0469:   erg.MATRIX[0] = m1.MATRIX[0] * m2.MATRIX[0] + m1.MATRIX[3] * m2.MATRIX[1] + m1.MATRIX[6] * m2.MATRIX[2];
0470:   erg.MATRIX[1] = m1.MATRIX[1] * m2.MATRIX[0] + m1.MATRIX[4] * m2.MATRIX[1] + m1.MATRIX[7] * m2.MATRIX[2];
0471:   erg.MATRIX[2] = m1.MATRIX[2] * m2.MATRIX[0] + m1.MATRIX[5] * m2.MATRIX[1] + m1.MATRIX[8] * m2.MATRIX[2];
0472:   erg.MATRIX[3] = m1.MATRIX[0] * m2.MATRIX[3] + m1.MATRIX[3] * m2.MATRIX[4] + m1.MATRIX[6] * m2.MATRIX[5];
0473:   erg.MATRIX[4] = m1.MATRIX[1] * m2.MATRIX[3] + m1.MATRIX[4] * m2.MATRIX[4] + m1.MATRIX[7] * m2.MATRIX[5];
0474:   erg.MATRIX[5] = m1.MATRIX[2] * m2.MATRIX[3] + m1.MATRIX[5] * m2.MATRIX[4] + m1.MATRIX[8] * m2.MATRIX[5];
0475:   erg.MATRIX[6] = m1.MATRIX[0] * m2.MATRIX[6] + m1.MATRIX[3] * m2.MATRIX[7] + m1.MATRIX[6] * m2.MATRIX[8];
0476:   erg.MATRIX[7] = m1.MATRIX[1] * m2.MATRIX[6] + m1.MATRIX[4] * m2.MATRIX[7] + m1.MATRIX[7] * m2.MATRIX[8];
0477:   erg.MATRIX[8] = m1.MATRIX[2] * m2.MATRIX[6] + m1.MATRIX[5] * m2.MATRIX[7] + m1.MATRIX[8] * m2.MATRIX[8];
0478:   erg.MATRIX[ 9] = m1.MATRIX[0] * m2.MATRIX[9] + m1.MATRIX[3] * m2.MATRIX[10] + m1.MATRIX[6] * m2.MATRIX[11] + m1.MATRIX[ 9];
0479:   erg.MATRIX[10] = m1.MATRIX[1] * m2.MATRIX[9] + m1.MATRIX[4] * m2.MATRIX[10] + m1.MATRIX[7] * m2.MATRIX[11] + m1.MATRIX[10];
0480:   erg.MATRIX[11] = m1.MATRIX[2] * m2.MATRIX[9] + m1.MATRIX[5] * m2.MATRIX[10] + m1.MATRIX[8] * m2.MATRIX[11] + m1.MATRIX[11];
0481:   /* DUMP_MAT(erg) */ return erg;
0482: }
0483: 
0484: KOORD PosTrans3i(MATRIX m, int x, int y, int z)
0485: { KOORD erg;
0486:   erg.KOORD[0] = m.MATRIX[0] * x + m.MATRIX[3] * y + m.MATRIX[6] * z + m.MATRIX[ 9];
0487:   erg.KOORD[1] = m.MATRIX[1] * x + m.MATRIX[4] * y + m.MATRIX[7] * y + m.MATRIX[10];
0488:   erg.KOORD[2] = m.MATRIX[2] * x + m.MATRIX[5] * y + m.MATRIX[8] * z + m.MATRIX[11];
0489:   return erg;
0490: }
0491: 
0492: KOORD PosTransKoord(MATRIX m, KOORD v)
0493: { KOORD erg;
0494:   erg.KOORD[0] = m.MATRIX[0] * v.KOORD[0] + m.MATRIX[3] * v.KOORD[1] + m.MATRIX[6] * v.KOORD[2] + m.MATRIX[ 9];
0495:   erg.KOORD[1] = m.MATRIX[1] * v.KOORD[0] + m.MATRIX[4] * v.KOORD[1] + m.MATRIX[7] * v.KOORD[2] + m.MATRIX[10];
0496:   erg.KOORD[2] = m.MATRIX[2] * v.KOORD[0] + m.MATRIX[5] * v.KOORD[1] + m.MATRIX[8] * v.KOORD[2] + m.MATRIX[11];
0497:   return erg;
0498: }
0499: 
0500: int RotIdOfMatrix(MATRIX m)
0501: { int erg, t;
0502:   if (m.MATRIX[0]) { erg =  0; t = 5; }
0503:   else
0504:   if (m.MATRIX[1]) { erg =  8; t = 3; }
0505:   else             { erg = 16; t = 4; }
0506:   if (m.MATRIX[0] + m.MATRIX[1] + m.MATRIX[2] < 0) erg += 4;
0507:   if (m.MATRIX[t]) erg += 2;
0508:   if (m.MATRIX[3] + m.MATRIX[4] + m.MATRIX[5] < 0) erg++;
0509:   return erg;
0510: }
0511: 
0512: BAUSTEIN BewegterBaustein(BAUSTEIN bs, MATRIX m)
0513: { BAUSTEIN erg;
0514:   int ct;
0515:   memset(&erg, 0, sizeof(BAUSTEIN));
0516:   erg.Teilwuerfelzahl = bs.Teilwuerfelzahl;
0517:   erg.Beschriftet = bs.Beschriftet;
0518:   for (ct = 0; ct < bs.Teilwuerfelzahl; ct++) {
0519:     erg.Einzelelemente[ct] = PosTransKoord(m, bs.Einzelelemente[ct]);
0520:   }
0521:   GetBausteinExtends(&erg);
0522:   return erg;
0523: }
0524: 
0525: #ifdef SLP_WUERFELGROESSE
0526: void SchreibeBausteinSLP(FILE *aus, int No, MATRIX m)
0527: { char Zeile[100], von[80];
0528:   FILE *ein;
0529:   float fx, fy, fz;
0530:   sprintf(von, "%u.slp", No);
0531:   if ((ein = fopen(von, "rb")) == NULL) {
0532:     fprintf(stderr, "Kann Datei '%s' nicht lesen!\n", von);
0533:     return;
0534:   }
0535:   while (fgets(Zeile, 100, ein) != NULL) {
0536:     if (!strncmp(Zeile, "      normal ", 13)) {
0537:       sscanf(&(Zeile[13]), "%e%e%e", &fx, &fy, &fz);
0538:       fprintf(aus, "      normal %.6e %.6e %.6e\r\n",
0539:         m.MATRIX[0] * fx + m.MATRIX[3] * fy + m.MATRIX[6] * fz,
0540:         m.MATRIX[1] * fx + m.MATRIX[4] * fy + m.MATRIX[7] * fz,
0541:         m.MATRIX[2] * fx + m.MATRIX[5] * fy + m.MATRIX[8] * fz);
0542:     } else
0543:     if (!strncmp(Zeile, "      vertex ", 13)) {
0544:       sscanf(&(Zeile[13]), "%e%e%e", &fx, &fy, &fz);
0545:       fprintf(aus, "      vertex %.6e %.6e %.6e\r\n",
0546:         m.MATRIX[0] * fx + m.MATRIX[3] * fy + m.MATRIX[6] * fz + SLP_WUERFELGROESSE * m.MATRIX[ 9],
0547:         m.MATRIX[1] * fx + m.MATRIX[4] * fy + m.MATRIX[7] * fz + SLP_WUERFELGROESSE * m.MATRIX[10],
0548:         m.MATRIX[2] * fx + m.MATRIX[5] * fy + m.MATRIX[8] * fz + SLP_WUERFELGROESSE * m.MATRIX[11]);
0549:     } else
0550:       fprintf(aus, "%s", Zeile);
0551:   }
0552:   fclose(ein);
0553: }
0554: 
0555: void SchreibeAktuellePositionierung(void)
0556: { char Dateiname[100];
0557:   int ct;
0558:   FILE *aus;
0559:   sprintf(Dateiname, "ct_puzzle_%.6u.slp", Resultate);
0560:   if ((aus = fopen(Dateiname, "wb")) == NULL) {
0561:     fprintf(stderr, "Datei '%s' kann nicht angelegt werden!\n", Dateiname);
0562:     return;
0563:   }
0564:   for (ct = 0; ct < BAUSTEINZAHL; ct++) {
0565:     // fprintf(stderr, "%s ", Positionierung[ct].eingesetzt ? "+" : "-");

0566:     // DUMP_MAT(Positionierung[ct].Einsetzpunkt)

0567:     if (Positionierung[ct].eingesetzt)
0568:       SchreibeBausteinSLP(aus, ct + 1, Positionierung[ct].Einsetzpunkt);
0569:      else fprintf(stderr, "%d. Bauteil ist nicht eingesetzt!\n", ct + 1);
0570:   }
0571:   fclose(aus);
0572: }
0573: 
0574: void SchreibeOrientierungsuebersicht(void)
0575: { int bs, p, h;
0576:   FILE *aus;
0577:   MATRIX m;
0578:   if ((aus = fopen("bausteinrotationsuebersicht.slp", "wb")) == NULL) return;
0579:   for (bs = 0; bs < BAUSTEINZAHL; bs++) {
0580:     h = 0;
0581:     for (p = BausteinBereitgelegtAb[bs]; p < BausteinBereitgelegtAb[bs + 1]; p++) {
0582:       m = MatMul(MatVersch3i( 5 * h  - BereitgelegterBaustein[p].Min.KOORD[0],
0583:                              -5 * bs - BereitgelegterBaustein[p].Min.KOORD[1],
0584:                                      - BereitgelegterBaustein[p].Min.KOORD[2]),
0585:                               BereitgelegteMatrix[p]);
0586:       SchreibeBausteinSLP(aus, bs + 1, m);
0587:       h++;
0588:     }
0589:   }
0590:   fclose(aus);
0591: }
0592: 
0593: void SchreibeTeileuebersicht(void)
0594: { int ct;
0595:   for (ct = 0; ct < BAUSTEINZAHL; ct++) {
0596:     Positionierung[ct].eingesetzt = 1;
0597:     Positionierung[ct].Einsetzpunkt = MatVersch3i(4 * ct, 0, 0);
0598:   }
0599:   SchreibeAktuellePositionierung();
0600:   for (ct = 0; ct < BAUSTEINZAHL; ct++) Positionierung[ct].eingesetzt = 0;
0601: }
0602: 
0603: #endif

0604: 
0605: void Init_RotationsMoeglichkeiten(void)
0606: { int ct;
0607:   ct = 0;
0608:   /*@ die 6 Richtungen, mit welcher die Symmetrieen (bei X-max != Y-max != Z-max != X-max)

0609:    *@ augeschlossen werden können

0610:    */
0611:   /* A4 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(1, 2)   ,   MatOrthoRot(0, 2)   )  ;
0612:   /* B3 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(1, 2)   ,   MatOrthoRot(0, 1)   )  ;
0613:   /* C1 */ RotationsMoeglichkeiten[ct++] = /* MatMul(*/ MatOrthoRot(1, 1) /*,   MatOrthoRot(0, 0)   )*/;
0614:   /* D2 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(1, 1)   ,   MatOrthoRot(0, 3)   )  ;
0615:   /* E4 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(2, 3)   ,   MatOrthoRot(0, 2)   )  ;
0616:   /* F1 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(2, 1)   ,   MatOrthoRot(0, 1)   )  ;
0617:   /*@ die restlichen 18 - 24 gesamt */
0618:   /* A1 */ RotationsMoeglichkeiten[ct++] = /* MatMul(   MatOrthoRot(0, 0)   ,   MatOrthoRot(0, 0)   )*/ Mat1();
0619:   /* A2 */ RotationsMoeglichkeiten[ct++] = /* MatMul(   MatOrthoRot(0, 0)   ,*/ MatOrthoRot(0, 2) /*)*/;
0620:   /* A3 */ RotationsMoeglichkeiten[ct++] = /* MatMul(*/ MatOrthoRot(1, 2) /*,   MatOrthoRot(0, 0)   )*/;
0621: 
0622:   /* B1 */ RotationsMoeglichkeiten[ct++] = /* MatMul(   MatOrthoRot(0, 0)   ,*/ MatOrthoRot(0, 1) /*)*/;
0623:   /* B2 */ RotationsMoeglichkeiten[ct++] = /* MatMul(   MatOrthoRot(0, 0)   ,*/ MatOrthoRot(0, 3) /*)*/;
0624:   /* B4 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(1, 2)   ,   MatOrthoRot(0, 3)   )  ;
0625: 
0626:   /* C2 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(1, 1)   ,   MatOrthoRot(0, 2)   )  ;
0627:   /* C3 */ RotationsMoeglichkeiten[ct++] = /* MatMul(*/ MatOrthoRot(1, 3) /*,   MatOrthoRot(0, 0)   )*/;
0628:   /* C4 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(1, 3)   ,   MatOrthoRot(0, 2)   )  ;
0629: 
0630:   /* D1 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(1, 1)   ,   MatOrthoRot(0, 1)   )  ;
0631:   /* D3 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(1, 3)   ,   MatOrthoRot(0, 1)   )  ;
0632:   /* D4 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(1, 3)   ,   MatOrthoRot(0, 3)   )  ;
0633: 
0634:   /* E1 */ RotationsMoeglichkeiten[ct++] = /* MatMul(*/ MatOrthoRot(2, 1) /*,   MatOrthoRot(0, 0)   )*/;
0635:   /* E2 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(2, 1)   ,   MatOrthoRot(0, 2)   )  ;
0636:   /* E3 */ RotationsMoeglichkeiten[ct++] = /* MatMul(*/ MatOrthoRot(2, 3) /*,   MatOrthoRot(0, 0)   )*/;
0637: 
0638:   /* F2 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(2, 1)   ,   MatOrthoRot(0, 3)   )  ;
0639:   /* F3 */ RotationsMoeglichkeiten[ct++] =    MatMul(   MatOrthoRot(2, 3)   ,   MatOrthoRot(0, 1)   )  ;
0640:   /* F4 */ RotationsMoeglichkeiten[ct  ] =    MatMul(   MatOrthoRot(2, 3)   ,   MatOrthoRot(0, 3)   )  ;
0641: }
0642: 
0643: void Init_Einsetztabelle(void)
0644: { int b, r, u;
0645:   unsigned __int64 bitmaske;
0646:   BAUSTEIN rot_bs, versch_bs;
0647:   MATRIX versch_m;
0648: #ifdef DUMP_TABLE_1
0649:   FILE *aus;
0650:   aus = fopen("table1.txt", "w");
0651: #endif

0652:   for (b = 0; b < BAUSTEINZAHL; b++) {
0653:     BausteinBereitgelegtAb[b] = BausteinBereitgelegtAb[b + 1] = EinsetztabelleBelegt;
0654:     for (r = 0; r < ((b == BESCHRAENKT_ROTIERTER_BAUSTEIN) ? 6 : 24); r++) {
0655:     /* Bei einem (dem letzten) Baustein nämlich nur noch 6 Orientierungen */
0656:       rot_bs = BewegterBaustein(Baustein[b], RotationsMoeglichkeiten[r]);
0657: #ifdef DEBUGING
0658:       if (aus != NULL) {
0659:         fprintf(aus, "\nRotationsMoeglichkeiten[%d] = ", r);
0660:         DumpMat(aus, RotationsMoeglichkeiten[r]);
0661:         fprintf(aus, "rot_bs = ");
0662:         DumpBS(aus, rot_bs);
0663:       }
0664: #endif

0665:       if (PasstBausteinInKasten(rot_bs)) {
0666: #ifdef DEBUGING
0667:         if (aus != NULL) fprintf(aus, "passt hinein\n");
0668: #endif

0669:         for (u = 0; u < rot_bs.Teilwuerfelzahl; u++) {
0670: #ifdef DEBUGING
0671:           if (aus != NULL) fprintf(aus, "%d. Teilwuerfel\n", u);
0672: #endif

0673:           if (u) {
0674:             versch_m = RotationsMoeglichkeiten[r];
0675:             versch_m.MATRIX[ 9] -= rot_bs.Einzelelemente[u].KOORD[0];
0676:             versch_m.MATRIX[10] -= rot_bs.Einzelelemente[u].KOORD[1];
0677:             versch_m.MATRIX[11] -= rot_bs.Einzelelemente[u].KOORD[2];
0678:             versch_bs = BewegterBaustein(Baustein[b], versch_m);
0679:           } else {
0680:             versch_bs = rot_bs; versch_m = RotationsMoeglichkeiten[r];
0681:           }
0682: #ifdef DEBUGING
0683:           if (aus != NULL) {
0684:             fprintf(aus, "versch_m = "); DumpMat(aus, versch_m);
0685:             fprintf(aus, "versch_bs = "); DumpBS(aus, versch_bs);
0686:           }
0687: #endif

0688:           VerschiebeBausteinNullpunktElement(&versch_bs);
0689: #ifdef DEBUGING
0690:           if (aus != NULL) {
0691:             fprintf(aus, "versch_bs = "); DumpBS(aus, versch_bs);
0692:           }
0693: #endif

0694:           if (PasstBausteinInEinsetzsequenz(versch_bs)
0695:            /* und jetzt könnte es noch ein symmetrisch in sich selbst abgebildetes Teil sein! */
0696:            && TeilSymmetriegleichNeu(versch_bs, BausteinBereitgelegtAb[b], &bitmaske)) {
0697:             if (EinsetztabelleBelegt >= EINSETZTABELLE)
0698:              fprintf(stderr, "ACHTUNG! EINSETZTABELLE zu klein - bitte mit neuem Wert (%d) neu kompilieren!\n",
0699:                      EinsetztabelleBelegt);
0700:             else {
0701:               BereitgelegterBaustein[EinsetztabelleBelegt] = versch_bs;
0702:               BereitgelegteMatrix[EinsetztabelleBelegt] = versch_m;
0703:               Bitmasken[EinsetztabelleBelegt].Maske = bitmaske;
0704:               Bitmasken[EinsetztabelleBelegt].Versatz[0] = - versch_bs.Min.KOORD[0];
0705:               Bitmasken[EinsetztabelleBelegt].Versatz[1] = - versch_bs.Min.KOORD[1];
0706:               Bitmasken[EinsetztabelleBelegt].Versatz[2] = - versch_bs.Min.KOORD[2];
0707: #ifdef DEBUGING
0708:               if (aus != NULL) {
0709:                 fprintf(aus, "BereitgelegteMatrix[%d] = ", EinsetztabelleBelegt);
0710:                 DumpMat(aus, BereitgelegteMatrix[EinsetztabelleBelegt]);
0711:                 fprintf(aus, "Versatz = { %d , %d , %d }\n",
0712:                   Bitmasken[EinsetztabelleBelegt].Versatz[0],
0713:                   Bitmasken[EinsetztabelleBelegt].Versatz[1],
0714:                   Bitmasken[EinsetztabelleBelegt].Versatz[2]);
0715:                 fprintf(aus, "BereitgelegterBaustein[%d] = ", EinsetztabelleBelegt);
0716:                 DumpBS(aus, BereitgelegterBaustein[EinsetztabelleBelegt]);
0717:               }
0718: #endif

0719:             }
0720:             EinsetztabelleBelegt++;
0721:           } /* else: kann nie und nimmer so gebraucht werden */
0722:         }
0723:       } /* else: Passt doch garniemalsnienicht bei dieser Drehstellung in die Gesamtabmessungen hinein! */
0724:     }
0725:     // Pause();

0726:   }
0727:   if (EinsetztabelleBelegt > EINSETZTABELLE) {
0728:     EinsetztabelleBelegt = EINSETZTABELLE;
0729:     fprintf(stderr, "\n\nA C H T U N G :   Ergebnis wahrscheinlich unvollständig!\n\n");
0730:   }
0731:   for (b = 0; b < BAUSTEINZAHL; b++)
0732:     if (BausteinBereitgelegtAb[b] > EINSETZTABELLE)
0733:       BausteinBereitgelegtAb[b] = EINSETZTABELLE;
0734:   BausteinBereitgelegtAb[BAUSTEINZAHL] = EinsetztabelleBelegt;
0735: #ifdef VERBOSE
0736:   Zeiterfassung(ZEITERFASSUNG_AUSGABE);
0737:   printf("%d Einsetzvarianten sind belegt.\n", EinsetztabelleBelegt);
0738: #endif

0739: #ifdef DUMP_TABLE_1
0740:   Zeiterfassung(ZEITERFASSUNG_AUSGABE);
0741:   for (b = 0; b < BAUSTEINZAHL; b++)
0742:     for (r = BausteinBereitgelegtAb[b]; (r < BausteinBereitgelegtAb[b + 1]) /* && (r < 70) */; r++) {
0743:     if (aus != NULL) {
0744:       fprintf(aus, "          Rot-ID = %2d ", RotIdOfMatrix(BereitgelegteMatrix[r]) + 1);
0745:       DumpMat(aus, BereitgelegteMatrix[r]);
0746:       fprintf(aus, "%2d: [%4d] ", b, r); DumpMat(aus, BereitgelegteMatrix[r]);
0747:       fprintf(aus, "  ");
0748:       DumpBS(aus, BereitgelegterBaustein[r]);
0749:       fprintf(aus, "   Bitmask: [%d] %d,%d,%d ", BitMaskBitCount(Bitmasken[r].Maske),
0750:       Bitmasken[r].Versatz[0], Bitmasken[r].Versatz[1], Bitmasken[r].Versatz[2]);
0751:       DumpBitmask(aus, Bitmasken[r].Maske);
0752:       fprintf(aus, "\n\n");
0753:     }
0754:   }
0755:   fprintf(aus, "{");
0756:   for (b = 0; b < BAUSTEINZAHL; b++)
0757:     fprintf(aus, " %2d (%2d)", BausteinBereitgelegtAb[b], BausteinBereitgelegtAb[b + 1] - BausteinBereitgelegtAb[b]);
0758:   fprintf(aus, " %2d }\n", BausteinBereitgelegtAb[BAUSTEINZAHL]);
0759: #endif

0760: #ifdef VERBOSE_1
0761:   printf("{");
0762:   for (b = 0; b < BAUSTEINZAHL; b++)
0763:     printf(" %2d (%2d)", BausteinBereitgelegtAb[b], BausteinBereitgelegtAb[b + 1] - BausteinBereitgelegtAb[b]);
0764:   printf(" %2d }\n", BausteinBereitgelegtAb[BAUSTEINZAHL]);
0765:   Zeiterfassung(ZEITERFASSUNG_INIT);
0766: #endif

0767: #ifdef SLP_WUERFELGROESSE
0768:   SchreibeOrientierungsuebersicht();
0769: #endif

0770: #ifdef DUMP_TABLE_1
0771:   if (aus != NULL) fclose(aus);
0772:   Zeiterfassung(ZEITERFASSUNG_INIT);
0773: #endif

0774: }
0775: 
0776: void Init_KlassenMagazin(void)
0777: { int Position, p[3], Baustein, ep, kp, ct, verloren;
0778: #ifdef DUMP_TABLE_2
0779:   FILE *aus;
0780:   aus = fopen("table2.txt", "w");
0781: #endif

0782:   p[0] = p[1] = p[2] = ep = Klassen[0] = verloren = 0;
0783:   kp = 1;
0784:   for (Position = 0; Position < EINSETZPUNKTE; Position++) {
0785:     for (Baustein = 0; Baustein < BAUSTEINZAHL; Baustein++) {
0786:       for (ct = BausteinBereitgelegtAb[Baustein]; ct < BausteinBereitgelegtAb[Baustein + 1]; ct++) {
0787:         if ((Bitmasken[ct].Versatz[0] <= p[0])
0788:          && (Bitmasken[ct].Versatz[1] <= p[1])
0789:          && (Bitmasken[ct].Versatz[2] <= p[2])
0790:          && (BereitgelegterBaustein[ct].Max.KOORD[0] + p[0] < Kastengroesse.KOORD[0])
0791:          && (BereitgelegterBaustein[ct].Max.KOORD[1] + p[1] < Kastengroesse.KOORD[1])
0792:          && (BereitgelegterBaustein[ct].Max.KOORD[2] + p[2] < Kastengroesse.KOORD[2])) {
0793:            if (ep < MAGAZINGROESSE) {
0794:              Magazin[ep] = Bitmasken[ct].Maske >> (  Position
0795: #ifdef PRESHIFT
0796:                                                               + 1
0797: #endif

0798:                                                    - (p[FUELLKOORDINATE_1] - Bitmasken[ct].Versatz[FUELLKOORDINATE_1])
0799:                               - FUELL_BM_FAKTOR_2 *  (p[FUELLKOORDINATE_2] - Bitmasken[ct].Versatz[FUELLKOORDINATE_2])
0800:                               - FUELL_BM_FAKTOR_3 *  (p[FUELLKOORDINATE_3] - Bitmasken[ct].Versatz[FUELLKOORDINATE_3])
0801:                                                    );
0802: #ifdef ZAEHLE_LEGUNGEN
0803:              BausteinMagazinRotId[ep] = RotIdOfMatrix(BereitgelegteMatrix[ct]) + 1;
0804: #endif

0805: #ifdef ERGEBNIS
0806:              BausteinMagazinId[ep] = ((Baustein + 1) << 12)
0807:                                    | (RotIdOfMatrix(BereitgelegteMatrix[ct]) << 7)
0808:                                    | (((BereitgelegteMatrix[ct].MATRIX[ 9] + p[0]) & 7) << 4)
0809:                                    | (((BereitgelegteMatrix[ct].MATRIX[10] + p[1]) & 3) << 2)
0810:                                    |  ((BereitgelegteMatrix[ct].MATRIX[11] + p[2]) & 3);
0811: #endif

0812: #ifdef DUMP_TABLE_2
0813:              if (aus != NULL) {
0814:                fprintf(aus, "Quelle[%3d]  %1d %1d %1d : ", ct, 
0815:                  Bitmasken[ct].Versatz[FUELLKOORDINATE_1],
0816:                  Bitmasken[ct].Versatz[FUELLKOORDINATE_2],
0817:                  Bitmasken[ct].Versatz[FUELLKOORDINATE_3]);
0818:                DumpBitmask(aus, Bitmasken[ct].Maske);
0819:                fprintf(aus, "\nBS %2d Pos %2d Var %2d: ", Baustein, Position, ep - Klassen[kp - 1]);
0820:                DumpBitmask(aus, Magazin[ep]);
0821: #ifdef ERGEBNIS
0822:                fprintf(aus, "\nBaustein-ID: "); DumpBausteinId(aus, BausteinMagazinId[ep]);
0823: #endif

0824:                fprintf(aus, "\n\n");
0825:              }
0826: #endif

0827:              ep++;
0828:            } else verloren++;
0829:          } /* else: Passt an dieser Position nicht mehr in den 'Kasten'. */
0830:       }
0831:       Klassen[kp] = ep;
0832:       kp++;
0833:     }
0834:     if (++p[FUELLKOORDINATE_1] >= Kastengroesse.KOORD[FUELLKOORDINATE_1]) {
0835:       p[FUELLKOORDINATE_1] = 0;
0836:       if (++p[FUELLKOORDINATE_2] >= Kastengroesse.KOORD[FUELLKOORDINATE_2]) {
0837:         p[FUELLKOORDINATE_2] = 0;
0838:         ++p[FUELLKOORDINATE_3];
0839:       }
0840:     }
0841:   }
0842: #ifdef DUMP_TABLE_2
0843:   Zeiterfassung(ZEITERFASSUNG_AUSGABE);
0844:   if (aus != NULL) {
0845:     fprintf(aus, "\n");
0846:     for (Position = ep = 0; Position < EINSETZPUNKTE; Position++) {
0847:       fprintf(aus, "M%.2d:", Position);
0848:       for (Baustein = 0; Baustein < BAUSTEINZAHL; Baustein++) {
0849:         fprintf(aus, " %4d (%2d)", Klassen[ep], Klassen[ep + 1] - Klassen[ep]);
0850:         ep++;
0851:       }
0852:       fprintf(aus, " %2d\n", Klassen[ep]);
0853:     }
0854:     fprintf(aus, "SUM:");
0855:     // kp = 1;

0856:     for (Baustein = 0; Baustein < BAUSTEINZAHL; Baustein++) {
0857:       ep = 0;
0858:       for (Position = 0; Position < EINSETZPUNKTE; Position++)
0859:         ep += Klassen[12 * Position + Baustein + 1] - Klassen[12 * Position + Baustein];
0860:       fprintf(aus, "%10d", ep);
0861:       // kp *= ep;

0862:     }
0863:     fprintf(aus, "\n"); // printf("\nPROD:%9d\n", kp);

0864:     fprintf(aus, "MAX:");
0865:     for (Baustein = 0; Baustein < BAUSTEINZAHL; Baustein++) {
0866:       ep = 0;
0867:       for (Position = 0; Position < EINSETZPUNKTE; Position++)
0868:         if (ep < Klassen[12 * Position + Baustein + 1] - Klassen[12 * Position + Baustein])
0869:           ep = Klassen[12 * Position + Baustein + 1] - Klassen[12 * Position + Baustein];
0870:       fprintf(aus, "%10d", ep);
0871:     }
0872:     fprintf(aus, "\n%d Bitmasken im Magazin\n", Klassen[KLASSEN]);
0873:   }
0874:   Zeiterfassung(ZEITERFASSUNG_INIT);
0875: #endif

0876:   if (verloren) {
0877:     fprintf(stderr, "ACHTUNG: MAGAZINGROESSE ist zu klein! %d Bitmasken wurden verloren!\n"
0878:                     "Bitte Parameter vergrößern und neu kompilieren.\n", verloren);
0879: #ifdef DUMP_TABLE_2
0880:     if (aus != NULL) fprintf(aus, "ACHTUNG: MAGAZINGROESSE ist zu klein! %d Bitmasken wurden verloren!\n");
0881: #endif

0882:   }
0883: #ifdef DUMP_TABLE_2
0884:   if (aus != NULL) fclose(aus);
0885: #endif

0886: #ifdef VERBOSE
0887:   fprintf(stderr, "%d Bitmasken im Magazin.\n\n", Klassen[KLASSEN]);
0888: #endif

0889: }
0890: 
0891: #ifdef ERGEBNIS
0892: unsigned short Ergebnis[BAUSTEINZAHL];
0893: 
0894: #ifdef SLP_ERGOUT
0895: void SchreibeEinzelergebnisAlsSLP(void)
0896: { char Dateiname[100];
0897:   int ct, BS, xdir, ydir;
0898:   FILE *aus;
0899:   MATRIX Mat;
0900:   sprintf(Dateiname, "loesungen\\ct_puzzle_%.6u.slp", Resultate);
0901:   if ((aus = fopen(Dateiname, "wb")) == NULL) {
0902:     fprintf(stderr, "Datei '%s' kann nicht angelegt werden!\n", Dateiname);
0903:     return;
0904:   }
0905:   for (ct = 0; ct < BAUSTEINZAHL; ct++) {
0906:     BS = (Ergebnis[ct] >> 12) & 15;
0907:     memset(&Mat, 0, sizeof(MATRIX));
0908:     /* Richtung X-Achse des Bausteinkoordinatensystems */
0909:     xdir = (Ergebnis[ct] >> 10) & 3;
0910:     Mat.MATRIX[xdir] = ((Ergebnis[ct] >> 9) & 1) ? -1 : 1;
0911:     /* Richtung Y-Achse des Bausteinkoordinatensystems */
0912:     ydir = (xdir + 1 + ((Ergebnis[ct] >> 8) & 1)) % 3 + 3;
0913:     Mat.MATRIX[ydir] = ((Ergebnis[ct] >> 7) & 1) ? -1 : 1;
0914:     /* Kreuzprodukt für Z-Achse */
0915:     Mat.MATRIX[8] = Mat.MATRIX[0] * Mat.MATRIX[4] - Mat.MATRIX[1] * Mat.MATRIX[3];
0916:     Mat.MATRIX[6] = Mat.MATRIX[1] * Mat.MATRIX[5] - Mat.MATRIX[2] * Mat.MATRIX[4];
0917:     Mat.MATRIX[7] = Mat.MATRIX[2] * Mat.MATRIX[3] - Mat.MATRIX[0] * Mat.MATRIX[5];
0918:     /* Ursprung - skaliert wird erst in der folgenden Ausgaberoutine */
0919:     Mat.MATRIX[ 9] = (Ergebnis[ct] >>  4) & 7;
0920:     Mat.MATRIX[10] = (Ergebnis[ct] >> 2) & 3;
0921:     Mat.MATRIX[11] = Ergebnis[ct] & 3;
0922:     // fprintf(stderr, "Baustein %2d: ", ct); DumpMat(stderr, Mat); fprintf(stderr, "\n");

0923:     /* Ausgabe incl. Skalierung der Translation */
0924:     SchreibeBausteinSLP(aus, BS, Mat);
0925:   }
0926:   fclose(aus);
0927: }
0928: #endif

0929: 
0930: void GebeLoesungAus(void)
0931: {
0932:   Zeiterfassung(ZEITERFASSUNG_AUSGABE);
0933:   if (ergdat != NULL) fwrite(Ergebnis, BAUSTEINZAHL * sizeof(unsigned short), 1, ergdat);
0934: #ifdef SLP_ERGOUT
0935:   SchreibeEinzelergebnisAlsSLP();
0936: #endif

0937:   Zeiterfassung(ZEITERFASSUNG_SUCHEN);
0938: }
0939: #endif

0940: 
0941: 
0942: #ifdef ZAEHLE_LEGUNGEN
0943: int BausteinLiegtInRichtung[BAUSTEINZAHL] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
0944: 
0945: void IncAnds(void)
0946: { int bs;
0947:   Ands++;
0948:   for (bs = 0; bs < BAUSTEINZAHL; bs++) AndsA[bs][BausteinLiegtInRichtung[bs]]++;
0949: }
0950: 
0951: void IncLegungen(void)
0952: { int bs;
0953:   Legungen++;
0954:   for (bs = 0; bs < BAUSTEINZAHL; bs++) LegungenA[bs][BausteinLiegtInRichtung[bs]]++;
0955: }
0956: 
0957: void PrintLegungen(void)
0958: { int bs, dir;
0959:   FILE *erg;
0960:   if ((erg = fopen("richtungen.csv", "w")) == NULL) {
0961:     fprintf(stderr, "Richtungsauswertung kann nicht geschrieben werden!\n");
0962:     return;
0963:   }
0964:   fprintf(erg, "LEGUNGEN:\nRichtung:");
0965:   for (dir = 0; dir < 25; dir++) fprintf(erg, ",%d", dir);
0966:   for (bs = 0; bs < 12; bs++) {
0967:     fprintf(erg, "\nBaustein %d:", bs);
0968:     for (dir = 0; dir < 25; dir++) {
0969:       fprintf(erg, ",%8.6lf", ((double) LegungenA[bs][dir]) / 1000000.0);
0970:     }
0971:   }
0972:   fprintf(erg, "\n");
0973:   fprintf(erg, "AND-VERKNUEPFUNGEN:\nRichtung:");
0974:   for (dir = 0; dir < 25; dir++) fprintf(erg, ",%d", dir);
0975:   for (bs = 0; bs < 12; bs++) {
0976:     fprintf(erg, "\nBaustein %d:", bs);
0977:     for (dir = 0; dir < 25; dir++) {
0978:       fprintf(erg, ",%8.6lf", ((double) AndsA[bs][dir]) / 1000000.0);
0979:     }
0980:   }
0981:   fprintf(erg, "\n");
0982:   fclose(erg);
0983: }
0984: #endif

0985: 
0986: int Zaehle_USED[BAUSTEINZAHL] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
0987: #ifdef RESULT_CHAIN
0988: int Zaehle_PLACED[BAUSTEINZAHL + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
0989: int Zaehle_BEREICH[BAUSTEINZAHL + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
0990: int Zaehle_IMBEREICH[BAUSTEINZAHL + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
0991: #endif

0992: int Zaehle_EBENE = 0;
0993: 
0994: void Zaehle_Funktion(int ab_pos12, unsigned __int64 bisherige_maske)
0995: { unsigned __int64 belegt;
0996:   int pos12, poslim, ct, BS;
0997: #ifdef RESULT_CHAIN
0998:   int bereich, bp;
0999:   if (Zaehle_EBENE == 3) {
1000:     fprintf(stderr, "\r  %2d(%2d/%2d) - %2d(%2d/%2d) - %2d(%2d/%2d)",
1001:     Zaehle_PLACED[1] + 1, Zaehle_IMBEREICH[1], Zaehle_BEREICH[1],
1002:     Zaehle_PLACED[2] + 1, Zaehle_IMBEREICH[2], Zaehle_BEREICH[2],
1003:     Zaehle_PLACED[3] + 1, Zaehle_IMBEREICH[3], Zaehle_BEREICH[3]);
1004:   }
1005: #endif

1006: #ifdef ZAEHLE_LEGUNGEN
1007:   IncLegungen();
1008: #endif

1009:   Zaehle_EBENE++;
1010:   belegt = bisherige_maske; pos12 = ab_pos12;
1011:   /* Wo liegt der nächste Einsetzpunkt? */
1012: #ifdef PRESHIFT
1013:   while (((unsigned int) belegt) & 1) { belegt >>= 1; pos12 += 12; }
1014:   belegt >>= 1; pos12 += 12;
1015: #else

1016: #ifndef MULTISHIFT
1017:   do {
1018:     belegt >>= 1; pos12 += 12;
1019:   } while (((unsigned int) belegt) & 1);
1020: #else

1021:   while (!((~((unsigned int) belegt)) & 7)) {
1022:     belegt >>= 3; pos12 += 36;
1023:   }
1024:   while (((unsigned int) belegt) & 1) {
1025:     belegt >>= 1; pos12 += 12;
1026:   }
1027: #endif

1028: #endif

1029:   /* je noch unbenutzter Baustein */
1030:   for (BS = 0; BS < BAUSTEINZAHL; BS++) if (!Zaehle_USED[BS]) {
1031:     /* je grundsätzliche Einsetzmöglichkeit dieses Bausteins an dieser Position */
1032:     poslim = Klassen[pos12 + BS + 1];
1033: #ifdef RESULT_CHAIN
1034:     bereich = poslim - Klassen[pos12 + BS]; bp = 0;
1035:     Zaehle_BEREICH[Zaehle_EBENE] = bereich;
1036: #endif

1037:     for (ct = Klassen[pos12 + BS]; ct < poslim; ct++) {
1038: #ifdef RESULT_CHAIN
1039:       bp++;
1040: #endif

1041: #ifdef DEBUGING
1042:       { int i;
1043:         for (i = 0; i < EINSETZPUNKTE; i++) fprintf(stderr, "%c",
1044:           ((belegt & Magazin[ct]) & (((unsigned __int64) 1) << i)) ? (i == pos12 / 12) ? 'X' : '#' : (i == pos12 / 12) ? 'o' : '.');
1045:         // for (i = 1; i <= Zaehle_EBENE; i++) fprintf(stderr, " %2d", Zaehle_PLACED[i]);

1046:         fprintf(stderr, "\n");
1047:       }
1048: #endif

1049: #ifdef ZAEHLE_LEGUNGEN
1050:       IncAnds();
1051: #endif

1052:       if (!(belegt & Magazin[ct])) { /* Treffer ins Loch: Freier Platz */
1053:         Zaehle_USED[BS] = 1;
1054: #ifdef ERGEBNIS
1055:         Ergebnis[Zaehle_EBENE - 1] = BausteinMagazinId[ct];
1056: #endif

1057: #ifdef ZAEHLE_LEGUNGEN
1058:         BausteinLiegtInRichtung[BS] = BausteinMagazinRotId[ct];
1059: #endif

1060: #ifdef RESULT_CHAIN
1061:         Zaehle_PLACED[Zaehle_EBENE] = BS;
1062:         Zaehle_IMBEREICH[Zaehle_EBENE] = bp;
1063: #endif

1064:         if (Zaehle_EBENE == BAUSTEINZAHL) {
1065:           Resultate++;
1066: #ifdef ERGEBNIS
1067:           GebeLoesungAus();
1068: #endif

1069:           if (!(Resultate & MELDUNGSHAEUFIGKEIT )) {
1070:             Geschwindigkeitserfassung();
1071:             /*

1072:             fprintf(stderr,

1073:             // "%-35s %lu Resultate bis jetzt gefunden.\r", " ", Resultate);

1074:             " %lu Resultate bis jetzt gefunden.\n", Resultate);

1075:             DumpBitmask(stderr, belegt | Magazin[ct]);

1076:             fprintf(stderr, "\n%2d - %2d - %2d - %2d - %2d - %2d - %2d - %2d - %2d - %2d - %2d - %2d\n",

1077:               Zaehle_PLACED[1] + 1, Zaehle_PLACED[2] + 1, Zaehle_PLACED[3] + 1, Zaehle_PLACED[4] + 1,

1078:               Zaehle_PLACED[5] + 1, Zaehle_PLACED[6] + 1, Zaehle_PLACED[7] + 1, Zaehle_PLACED[8] + 1,

1079:               Zaehle_PLACED[9] + 1, Zaehle_PLACED[10] + 1, Zaehle_PLACED[11] + 1, Zaehle_PLACED[12] + 1);

1080:             */
1081:           }
1082:         } else {
1083: #ifdef DEBUGING
1084:           { int i;
1085:             DumpBitmask(stderr, belegt | Magazin[ct]);
1086:             for (i = 1; i <= Zaehle_EBENE; i++) fprintf(stderr, " %2d", Zaehle_PLACED[i]);
1087:             fprintf(stderr, "\n");
1088:           }
1089: #endif

1090:           Zaehle_Funktion(pos12, belegt | Magazin[ct]);
1091:         }
1092: #ifdef ZAEHLE_LEGUNGEN
1093:         BausteinLiegtInRichtung[BS] = 0;
1094: #endif

1095:       }
1096:     }
1097:     Zaehle_USED[BS] = 0;
1098:   }
1099:   Zaehle_EBENE--;
1100: }
1101: 
1102: 
1103: void Zaehle_Moeglichkeiten(void)
1104: { Resultate = 0;
1105: #ifdef ERGEBNIS
1106:   ergdat = fopen(ERGEBNIS, "wb");
1107: #endif

1108: #ifdef MULTISHIFT
1109:   Zaehle_Funktion(  0, (unsigned __int64) 0);
1110: #else

1111:   Zaehle_Funktion(-12, (unsigned __int64) 0);
1112: #endif

1113:                   
1114: #ifdef ERGEBNIS
1115:   fclose(ergdat);
1116: #endif

1117:   printf("\n\nc't-Puzzle: %lu Zusammenbaulösungen gefunden.\n", Resultate);
1118: }
1119: 
1120: void Init_Bitmaskparameter(void)
1121: { FUELL_BM_FAKTOR_2 = Kastengroesse.KOORD[FUELLKOORDINATE_1];
1122:   FUELL_BM_FAKTOR_3 = Kastengroesse.KOORD[FUELLKOORDINATE_1] * Kastengroesse.KOORD[FUELLKOORDINATE_2];
1123: }
1124: 
1125: void InitParametercheck(void)
1126: { if (EINSETZPUNKTE > 8 * sizeof(__int64)) {
1127:     fprintf(stderr, "Bitmasken-Bearbeitung nicht für Volumen über %d Einheiten ausgelegt!\n",
1128:             8 * sizeof(__int64));
1129:     exit(9);
1130:   }
1131: }
1132: 
1133: int main()
1134: {
1135:   UINT CodePage;
1136:   CodePage = GetConsoleOutputCP();
1137:   SetConsoleOutputCP(1252);
1138: #ifdef ERGEBNIS
1139: #ifdef SLP_ERGOUT
1140:   mkdir("loesungen");
1141: #endif

1142: #endif

1143: 
1144:   Zeiterfassung(ZEITERFASSUNG_INIT);
1145:   InitParametercheck();
1146:   Init_Bitmaskparameter();
1147:   Init_RotationsMoeglichkeiten();
1148: #ifdef DEBUGING
1149:   Zeiterfassung(ZEITERFASSUNG_AUSGABE);
1150:   { int ct;
1151:     printf("RotationsMoeglichkeiten[]:\n");
1152:     for (ct = 0; ct < 24; ct++) {
1153:       printf("[%2d] (Det = %d) = ", ct, MatDet(RotationsMoeglichkeiten[ct]));
1154:       DumpMat(stdout, RotationsMoeglichkeiten[ct]);
1155:     }
1156:   }
1157:   Zeiterfassung(ZEITERFASSUNG_INIT);
1158: #endif

1159:   Init_Einsetztabelle();
1160:   Init_KlassenMagazin();
1161:   /*

1162:    * Zeiterfassung(ZEITERFASSUNG_AUSGABE);

1163:    * SchreibeTeileuebersicht();

1164:    */
1165:   Zeiterfassung(ZEITERFASSUNG_SUCHEN);
1166:   Zaehle_Moeglichkeiten();
1167:   Zeiterfassung(ZEITERFASSUNG_ENDE);
1168: #ifdef ERGEBNIS
1169:   PauseWait();
1170: #endif

1171: #ifdef ZAEHLE_LEGUNGEN
1172:   printf("%I64u Legungen und %I64u Ands ausgeführt.\n", Legungen, Ands);
1173:   PrintLegungen();
1174: #endif

1175:   SetConsoleOutputCP(CodePage);
1176:   return 0;
1177: }