12 pattern_record(struct pattern3s
*p
, char *str
, hash3_t pat
, int fixed_color
)
15 while (p
->hash
[hpat
& pattern3_hash_mask
].pattern
!= pat
16 && p
->hash
[hpat
& pattern3_hash_mask
].value
!= 0)
18 p
->hash
[hpat
& pattern3_hash_mask
].pattern
= pat
;
19 p
->hash
[hpat
& pattern3_hash_mask
].value
= fixed_color
? fixed_color
: 3;
20 //fprintf(stderr, "[%s] %04x %d\n", str, pat, fixed_color);
24 pat_vmirror(hash3_t pat
)
26 /* V mirror pattern; reverse order of 3-2-3 chunks */
27 return ((pat
& 0xfc00) >> 10) | (pat
& 0x03c0) | ((pat
& 0x003f) << 10);
31 pat_hmirror(hash3_t pat
)
33 /* H mirror pattern; reverse order of 2-bit values within the chunks */
34 #define rev3(p) ((p >> 4) | (p & 0xc) | ((p & 0x3) << 4))
35 #define rev2(p) ((p >> 2) | ((p & 0x3) << 2))
36 return (rev3((pat
& 0xfc00) >> 10) << 10)
37 | (rev2((pat
& 0x03c0) >> 6) << 6)
38 | rev3((pat
& 0x003f));
44 pat_90rot(hash3_t pat
)
46 /* Rotate by 90 degrees:
50 /* I'm too lazy to optimize this :) */
52 for (int i
= 0; i
< 8; i
++)
53 vals
[i
] = (pat
>> (i
* 2)) & 0x3;
55 vals2
[0] = vals
[5]; vals2
[1] = vals
[3]; vals2
[2] = vals
[0];
56 vals2
[3] = vals
[6]; vals2
[4] = vals
[1];
57 vals2
[5] = vals
[7]; vals2
[6] = vals
[4]; vals2
[7] = vals
[2];
59 for (int i
= 0; i
< 8; i
++)
60 p2
|= vals2
[i
] << (i
* 2);
65 pattern3_transpose(hash3_t pat
, hash3_t (*transp
)[8])
69 (*transp
)[i
++] = pat_vmirror(pat
);
70 (*transp
)[i
++] = pat_hmirror(pat
);
71 (*transp
)[i
++] = pat_vmirror(pat_hmirror(pat
));
72 (*transp
)[i
++] = pat_90rot(pat
);
73 (*transp
)[i
++] = pat_90rot(pat_vmirror(pat
));
74 (*transp
)[i
++] = pat_90rot(pat_hmirror(pat
));
75 (*transp
)[i
++] = pat_90rot(pat_vmirror(pat_hmirror(pat
)));
79 pattern_gen(struct pattern3s
*p
, hash3_t pat
, char *src
, int srclen
, int fixed_color
)
81 for (; srclen
> 0; src
++, srclen
--) {
84 int patofs
= (srclen
> 5 ? srclen
- 1 : srclen
) - 1;
87 *src
= '.'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
88 *src
= 'X'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
89 *src
= 'O'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
90 *src
= '#'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
91 *src
= '?'; // for future recursions
94 *src
= '.'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
95 *src
= 'O'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
96 *src
= '#'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
97 *src
= 'x'; // for future recursions
100 *src
= '.'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
101 *src
= 'X'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
102 *src
= '#'; pattern_gen(p
, pat
, src
, srclen
, fixed_color
);
103 *src
= 'o'; // for future recursions
105 case '.': /* 0 */ break;
106 case 'X': pat
|= S_BLACK
<< (patofs
* 2); break;
107 case 'O': pat
|= S_WHITE
<< (patofs
* 2); break;
108 case '#': pat
|= S_OFFBOARD
<< (patofs
* 2); break;
112 /* Original pattern, all transpositions and rotations */
114 pattern3_transpose(pat
, &transp
);
115 for (int i
= 0; i
< 8; i
++) {
116 /* Original color assignment */
117 pattern_record(p
, src
- 9, transp
[i
], fixed_color
);
118 /* Reverse color assignment */
120 fixed_color
= 2 - (fixed_color
== 2);
121 pattern_record(p
, src
- 9, pattern3_reverse(transp
[i
]), fixed_color
);
126 patterns_gen(struct pattern3s
*p
, char src
[][11], int src_n
)
128 for (int i
= 0; i
< src_n
; i
++) {
129 //printf("<%s>\n", src[i]);
132 case 'X': fixed_color
= S_BLACK
; break;
133 case 'O': fixed_color
= S_WHITE
; break;
135 //fprintf(stderr, "** %s **\n", src[i]);
136 pattern_gen(p
, 0, src
[i
], 9, fixed_color
);
141 patterns_load(char src
[][11], int src_n
, char *filename
)
143 FILE *f
= fopen("moggy.patterns", "r");
144 if (!f
) return false;
147 for (i
= 0; i
< src_n
; i
++) {
149 if (!fgets(line
, sizeof(line
), f
))
151 int l
= strlen(line
);
152 if (l
!= 10 + (line
[l
- 1] == '\n'))
154 memcpy(src
[i
], line
, 10);
156 fprintf(stderr
, "moggy.patterns: %d patterns loaded\n", i
);
160 fprintf(stderr
, "Error loading moggy.patterns.\n");
166 pattern3s_init(struct pattern3s
*p
, char src
[][11], int src_n
)
168 char nsrc
[src_n
][11];
170 if (!patterns_load(nsrc
, src_n
, "moggy.patterns")) {
171 /* Use default pattern set. */
172 for (int i
= 0; i
< src_n
; i
++)
173 strcpy(nsrc
[i
], src
[i
]);
176 patterns_gen(p
, nsrc
, src_n
);