0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008: #include <stdio.h>
0009: #include <mem.h>
0010: #include <malloc.h>
0011: #include <windows.h>
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:
0019:
0020:
0021: #define MELDUNGSHAEUFIGKEIT 0x03ff
0022:
0023: #define DONOT_DEBUGING
0024: #define DONOT_UNTERSCHEIDE_TEXT
0025: #define DONOT_DUMP_TABLE_1
0026: #define DONOT_DUMP_TABLE_2
0027:
0028:
0029:
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
0042:
0043: #define EINSETZTABELLE 183
0044: #define EINSETZPUNKTE (SZ1*SZ2*SZ3)
0045: #define KLASSEN (EINSETZPUNKTE * BAUSTEINZAHL)
0046: #define MAGAZINGROESSE 3132
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();
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:
0153: typedef char GrInt;
0154:
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:
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: { 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: { 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: { 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: { 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, 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: { 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: { 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: { 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: { 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: { 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: { 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: { 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:
0301:
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:
0323:
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:
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;
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:
0365:
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: 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:
0410: erg.MATRIX[0] = erg.MATRIX[5] = 1; erg.MATRIX[7] = -1;
0411: break;
0412: case 1:
0413: erg.MATRIX[4] = erg.MATRIX[6] = 1; erg.MATRIX[2] = -1;
0414: break;
0415: default:
0416: erg.MATRIX[1] = erg.MATRIX[8] = 1; erg.MATRIX[3] = -1;
0417: }
0418: break;
0419: case 2:
0420: switch (Achse) {
0421: case 0:
0422: erg.MATRIX[0] = 1; erg.MATRIX[4] = erg.MATRIX[8] = -1;
0423: break;
0424: case 1:
0425: erg.MATRIX[4] = 1; erg.MATRIX[0] = erg.MATRIX[8] = -1;
0426: break;
0427: default:
0428: erg.MATRIX[8] = 1; erg.MATRIX[0] = erg.MATRIX[4] = -1;
0429: }
0430: break;
0431: case 3:
0432: switch (Achse) {
0433: case 0:
0434: erg.MATRIX[0] = erg.MATRIX[7] = 1; erg.MATRIX[5] = -1;
0435: break;
0436: case 1:
0437: erg.MATRIX[4] = erg.MATRIX[2] = 1; erg.MATRIX[6] = -1;
0438: break;
0439: default:
0440: erg.MATRIX[3] = erg.MATRIX[8] = 1; erg.MATRIX[1] = -1;
0441: }
0442: break;
0443: default:
0444: erg.MATRIX[0] = erg.MATRIX[4] = erg.MATRIX[8] = 1;
0445: break;
0446: }
0447: 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: 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: 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: 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:
0566:
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:
0609:
0610:
0611: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(1, 2) , MatOrthoRot(0, 2) ) ;
0612: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(1, 2) , MatOrthoRot(0, 1) ) ;
0613: ;
0614: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(1, 1) , MatOrthoRot(0, 3) ) ;
0615: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(2, 3) , MatOrthoRot(0, 2) ) ;
0616: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(2, 1) , MatOrthoRot(0, 1) ) ;
0617:
0618: Mat1();
0619: ;
0620: ;
0621:
0622: ;
0623: ;
0624: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(1, 2) , MatOrthoRot(0, 3) ) ;
0625:
0626: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(1, 1) , MatOrthoRot(0, 2) ) ;
0627: ;
0628: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(1, 3) , MatOrthoRot(0, 2) ) ;
0629:
0630: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(1, 1) , MatOrthoRot(0, 1) ) ;
0631: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(1, 3) , MatOrthoRot(0, 1) ) ;
0632: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(1, 3) , MatOrthoRot(0, 3) ) ;
0633:
0634: ;
0635: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(2, 1) , MatOrthoRot(0, 2) ) ;
0636: ;
0637:
0638: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(2, 1) , MatOrthoRot(0, 3) ) ;
0639: RotationsMoeglichkeiten[ct++] = MatMul( MatOrthoRot(2, 3) , MatOrthoRot(0, 1) ) ;
0640: 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:
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:
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: }
0722: }
0723: }
0724: }
0725:
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++) {
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: }
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:
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:
0862: }
0863: fprintf(aus, "\n");
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:
0909: xdir = (Ergebnis[ct] >> 10) & 3;
0910: Mat.MATRIX[xdir] = ((Ergebnis[ct] >> 9) & 1) ? -1 : 1;
0911:
0912: ydir = (xdir + 1 + ((Ergebnis[ct] >> 8) & 1)) % 3 + 3;
0913: Mat.MATRIX[ydir] = ((Ergebnis[ct] >> 7) & 1) ? -1 : 1;
0914:
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:
0919: Mat.MATRIX[ 9] = (Ergebnis[ct] >> 4) & 7;
0920: Mat.MATRIX[10] = (Ergebnis[ct] >> 2) & 3;
0921: Mat.MATRIX[11] = Ergebnis[ct] & 3;
0922:
0923:
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:
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:
1030: for (BS = 0; BS < BAUSTEINZAHL; BS++) if (!Zaehle_USED[BS]) {
1031:
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:
1046: fprintf(stderr, "\n");
1047: }
1048: #endif
1049: #ifdef ZAEHLE_LEGUNGEN
1050: IncAnds();
1051: #endif
1052: if (!(belegt & Magazin[ct])) {
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:
1073:
1074:
1075:
1076:
1077:
1078:
1079:
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:
1163:
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: }