Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1805 | yogev_ezra | 1 | #ifndef _HEADER_TMP_PLAYER_H |
2 | #define _HEADER_TMP_PLAYER_H |
||
3 | |||
4 | #include "player.h" |
||
5 | |||
6 | class CompPosition : public Position |
||
7 | { |
||
8 | public: |
||
9 | bool Move; |
||
10 | |||
11 | CompPosition() : Position() {Move = 1;} |
||
12 | CompPosition(CompPosition &p, bool IsChange = 0) : Position(p) |
||
13 | {Move = p.Move + IsChange;} |
||
14 | CompPosition& operator=(CompPosition &p) |
||
15 | {for(int i = 0; i < 32; i++) SH[i] = p.SH[i]; Move = p.Move; return *this;} |
||
16 | CompPosition& Init(Position &p, bool MoveColor = 1) |
||
17 | {for(int i = 0; i < 32; i++) SH[i] = p.SH[i]; Move = MoveColor; return *this;} |
||
18 | }; |
||
19 | |||
20 | namespace ComputerMove |
||
21 | { |
||
22 | #define BCM_START -256 |
||
23 | #define BCM_ISM1 -257 |
||
24 | |||
25 | class BestMove; |
||
26 | bool MoveEat(BestMove* BM); |
||
27 | bool MovePr(BestMove* BM); |
||
28 | |||
29 | class BestMove |
||
30 | { |
||
31 | public: |
||
32 | BestMove (CompPosition &Pos1, BestMove *par = 0) |
||
33 | {Pos = Pos1; Parent = par; NMax = 0;} |
||
34 | |||
35 | void StartMove() |
||
36 | { |
||
37 | if (Parent->NomP == BCM_ISM1) return; |
||
38 | if (Parent->NomP == BCM_START) NomP = 258; else NomP = Parent->NomP; |
||
39 | if (!MoveEat(this)) |
||
40 | { |
||
41 | bool IsNP256 = 0, IsNP258 = 0; |
||
42 | if (NomP == 258) IsNP258 = 1; |
||
43 | if (NomP == 256) |
||
44 | { |
||
45 | IsNP256 = 1; int NSH1 = 0; int NSH0 = 0; |
||
46 | for (int i = 0; i < 32; i++) |
||
47 | { |
||
48 | if (Pos.SH[i] == 1 + Pos.Move) NSH1 += 1; |
||
49 | else if (Pos.SH[i] == 2 - Pos.Move) NSH0 += 1; |
||
50 | else if (Pos.SH[i] == 3 + Pos.Move) NSH1 += 6; |
||
51 | else if (Pos.SH[i] == 4 - Pos.Move) NSH0 += 6; |
||
52 | } |
||
53 | int NSH = NSH0 * NSH1; |
||
54 | if (NSH > 100) NomP = 0; else if (NSH > 30) NomP = 1; |
||
55 | else if (NSH > 5) NomP = 2; else NomP = 3; |
||
56 | } |
||
57 | else if (NomP == 0) NomP = BCM_ISM1; else NomP--; |
||
58 | if (!MovePr(this)) |
||
59 | { |
||
60 | NextPreim = -16777472; |
||
61 | for (int i = 0; i < 32; i++) |
||
62 | { |
||
63 | if (Pos.SH[i] == 1 + Pos.Move) NextPreim -= 512; |
||
64 | else if (Pos.SH[i] == 2 - Pos.Move) NextPreim -= 32; |
||
65 | else if (Pos.SH[i] == 3 + Pos.Move) NextPreim -= 4096; |
||
66 | else if (Pos.SH[i] == 4 - Pos.Move) NextPreim -= 32; |
||
67 | } |
||
68 | } |
||
69 | else if (NomP == BCM_ISM1) |
||
70 | { |
||
71 | char NomDM0 = 0, NomDM1 = 0; |
||
72 | NextPreim = 0; |
||
73 | for (int i = 0; i < 32; i++) |
||
74 | { |
||
75 | short PreimSHPos[32] = {243, 243, 243, 245, |
||
76 | 240, 240, 240, 240, |
||
77 | 244, 244, 244, 244, |
||
78 | 245, 248, 248, 245, |
||
79 | 249, 250, 250, 248, |
||
80 | 256, 260, 260, 256, |
||
81 | 280, 280, 280, 260, |
||
82 | 280, 280, 280, 280}; |
||
83 | if (Pos.SH[i] == 1 + Pos.Move) |
||
84 | NextPreim += PreimSHPos[Pos.Move ? (31 - i) : i]; |
||
85 | else if (Pos.SH[i] == 2 - Pos.Move) |
||
86 | NextPreim -= PreimSHPos[Pos.Move ? i : (31 - i)]; |
||
87 | else if (Pos.SH[i] == 3 + Pos.Move) NomDM1++; |
||
88 | else if (Pos.SH[i] == 4 - Pos.Move) NomDM0++; |
||
89 | } |
||
90 | if (NomDM1 > 0) |
||
91 | { |
||
92 | NextPreim += 560; NomDM1--; |
||
93 | if (NomDM1 > 0) |
||
94 | { |
||
95 | NextPreim += 432; NomDM1--; |
||
96 | NextPreim += long(NomDM1) * 384; |
||
97 | } |
||
98 | } |
||
99 | if (NomDM0 > 0) |
||
100 | { |
||
101 | NextPreim -= 560; NomDM0--; |
||
102 | if (NomDM0 > 0) |
||
103 | { |
||
104 | NextPreim -= 432; NomDM0--; |
||
105 | NextPreim -= long(NomDM0) * 384; |
||
106 | } |
||
107 | } |
||
108 | } |
||
109 | else if (IsNP256 && NextPreim < 16777216 && NextPreim > -16777216) |
||
110 | { |
||
111 | char NSH1 = 0, NSH0 = 0, NDM1 = 0, NDM0 = 0; |
||
112 | for (int i = 0; i < 32; i++) |
||
113 | { |
||
114 | if (Pos.SH[i] == 1 + Pos.Move) NSH1++; |
||
115 | else if (Pos.SH[i] == 2 - Pos.Move) NSH0++; |
||
116 | else if (Pos.SH[i] == 3 + Pos.Move) NDM1++; |
||
117 | else if (Pos.SH[i] == 4 - Pos.Move) NDM0++; |
||
118 | } |
||
119 | if (NDM1 > 0 && NDM0 > 0 && NSH1 + NSH0 < 3) |
||
120 | { |
||
121 | unsigned char HwoBD = 0; char Sh0BD = 1, Sh1BD = 1; |
||
122 | for (int i = 0; i < 8; i++) |
||
123 | { |
||
124 | char ShBD = Pos.SH[PoleToNum(i, 7 - i)]; |
||
125 | if (ShBD == 1 + Pos.Move) Sh1BD++; |
||
126 | else if (ShBD == 2 - Pos.Move) Sh0BD++; |
||
127 | else if (ShBD == 3 + Pos.Move) HwoBD |= 2; |
||
128 | else if (ShBD == 4 - Pos.Move) HwoBD |= 1; |
||
129 | } |
||
130 | if (HwoBD == 2) NextPreim += 128 / Sh0BD; |
||
131 | if (HwoBD == 1) NextPreim -= 128 / Sh1BD; |
||
132 | if (NDM1 >= 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0 && HwoBD == 1) |
||
133 | { |
||
134 | char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; |
||
135 | char Add = 0; |
||
136 | for (int i = 0; i < 4; i++) Add |= |
||
137 | (char(Pos.SH[Best4P[i][0]] == 3 + Pos.Move) * 3 + |
||
138 | char(Pos.SH[Best4P[i][1]] == 3 + Pos.Move)); |
||
139 | if (Add >= 4) NextPreim += 32; else if (Add == 3) NextPreim += 24; |
||
140 | else if (Add >= 1) NextPreim += 16; |
||
141 | } |
||
142 | else if (NDM0 >= 3 && NDM1 == 1 && NSH0 == 0 && NSH1 == 0 && HwoBD == 2) |
||
143 | { |
||
144 | char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; |
||
145 | char Add = 0; |
||
146 | for (int i = 0; i < 4; i++) Add |= |
||
147 | (char(Pos.SH[Best4P[i][0]] == 4 - Pos.Move) * 3 + |
||
148 | char(Pos.SH[Best4P[i][1]] == 4 - Pos.Move)); |
||
149 | if (Add >= 4) NextPreim -= 32; else if (Add == 3) NextPreim -= 24; |
||
150 | else if (Add >= 1) NextPreim -= 16; |
||
151 | } |
||
152 | } |
||
153 | else |
||
154 | { |
||
155 | for (int i = 0; i < 32; i++) |
||
156 | { |
||
157 | char Color = Pos.SH[i] - 1; |
||
158 | if (Color == 0 || Color == 1) |
||
159 | { |
||
160 | char qi = Color ? (31 - i) : i; |
||
161 | char Zn = Color ? -1 : 1; |
||
162 | char PreZ = (Color == Pos.Move) ? 1 : -1; |
||
163 | if (Pos.SH[i + Zn * 8] != 2 - Color) |
||
164 | { |
||
165 | if (qi / 4 == 2) |
||
166 | { |
||
167 | char IsFree = 0; |
||
168 | if (Pos.SH[i - Zn * 4] == 2 - Color) IsFree += 2; |
||
169 | else if (qi != 8) |
||
170 | { |
||
171 | if (Pos.SH[i - Zn ] == 2 - Color || |
||
172 | Pos.SH[i - Zn * 9] == 2 - Color) IsFree += 2; |
||
173 | else if (Color != Pos.Move) |
||
174 | if (Pos.SH[i - Zn * 5] == 2 - Color) IsFree++; |
||
175 | } |
||
176 | if (qi == 11) IsFree += 2; |
||
177 | else if (Pos.SH[i + Zn ] == 2 - Color || |
||
178 | Pos.SH[i - Zn * 3] == 2 - Color || |
||
179 | Pos.SH[i - Zn * 7] == 2 - Color) IsFree += 2; |
||
180 | else if (Color != Pos.Move && qi != 10) |
||
181 | if (Pos.SH[i - Zn * 2] == 2 - Color) IsFree++; |
||
182 | if (IsFree < 3) NextPreim += PreZ * 176 / (1 + NDM0 + NDM1); |
||
183 | else if (qi == 9 || qi == 10) NextPreim += |
||
184 | PreZ * 128 / (1 + NDM0 + NDM1); |
||
185 | } |
||
186 | else if (qi / 4 == 3) |
||
187 | { |
||
188 | char IsFree = 0; |
||
189 | if (Pos.SH[i - Zn * 12] == 2 - Color) |
||
190 | {if (Color == Pos.Move) IsFree += 11; else IsFree += 12;} |
||
191 | else if (Pos.SH[i - Zn * 4] == 2 - Color) IsFree += 11; |
||
192 | else if (qi == 15) IsFree += 5; |
||
193 | else if (Pos.SH[i - Zn * 7] == 2 - Color) IsFree += 9; |
||
194 | else if (Pos.SH[i + Zn] == 2 - Color) IsFree += 8; |
||
195 | else if (Pos.SH[i - Zn * 11] == 2 - Color) |
||
196 | {if (Color == Pos.Move) IsFree += 5; else IsFree += 7;} |
||
197 | else if (Pos.SH[i - Zn * 3] == 2 - Color) IsFree += 5; |
||
198 | else if (qi != 14) |
||
199 | { |
||
200 | if (Pos.SH[i - Zn * 6] == 2 - Color) IsFree += 3; |
||
201 | else if (Color != Pos.Move) |
||
202 | if (Pos.SH[i - Zn * 10] == 2 - Color) IsFree++; |
||
203 | } |
||
204 | if (qi == 12) IsFree += 7; |
||
205 | else if (Pos.SH[i - Zn * 13] == 2 - Color) |
||
206 | {if (Color == Pos.Move) IsFree += 11; else IsFree += 12;} |
||
207 | else if (Pos.SH[i - Zn * 5] == 2 - Color) IsFree += 11; |
||
208 | else if (Pos.SH[i - Zn * 9] == 2 - Color) IsFree += 9; |
||
209 | else if (Pos.SH[i - Zn] == 2 - Color) IsFree += 8; |
||
210 | else if (qi != 13) |
||
211 | { |
||
212 | if (Pos.SH[i - Zn * 14] == 2 - Color) |
||
213 | {if (Color == Pos.Move) IsFree += 5; else IsFree += 7;} |
||
214 | else if (Pos.SH[i - Zn * 6] == 2 - Color) IsFree += 5; |
||
215 | else if (Pos.SH[i - Zn * 10] == 2 - Color) IsFree += 3; |
||
216 | else if (Color != Pos.Move && qi != 14) |
||
217 | if (Pos.SH[i - Zn * 15] == 2 - Color) IsFree++; |
||
218 | } |
||
219 | if (IsFree < ((Color == Pos.Move) ? 14 : 12)) |
||
220 | NextPreim += PreZ * 160 / (1 + NDM0 + NDM1); |
||
221 | } |
||
222 | } |
||
223 | } |
||
224 | } |
||
225 | } |
||
226 | } |
||
227 | else if (IsNP258 && NextPreim < 16777216 && NextPreim > -16777216) |
||
228 | { |
||
229 | char NSH1 = 0, NSH0 = 0, NDM1 = 0, NDM0 = 0; |
||
230 | for (int i = 0; i < 32; i++) |
||
231 | { |
||
232 | if (Pos.SH[i] == 1 + Pos.Move) NSH1++; |
||
233 | else if (Pos.SH[i] == 2 - Pos.Move) NSH0++; |
||
234 | else if (Pos.SH[i] == 3 + Pos.Move) NDM1++; |
||
235 | else if (Pos.SH[i] == 4 - Pos.Move) NDM0++; |
||
236 | } |
||
237 | if (NDM1 > 0 && NDM0 > 0 && NSH1 == 0 && NSH0 == 0) |
||
238 | { |
||
239 | short PrP = 0; char Cpos3 = -1; |
||
240 | if (NDM1 == 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0) Cpos3 = 1; |
||
241 | else if (NDM1 == 1 && NDM0 == 3 && NSH1 == 0 && NSH0 == 0) Cpos3 = 0; |
||
242 | if (Cpos3 >= 0) |
||
243 | { |
||
244 | for (char Osm = 0; Osm <= 1; Osm++) for (char Csm = 0; Csm <= 1; Csm++) |
||
245 | { |
||
246 | char PosSH[7][3] = {{13, 17, 18}, {6, 17, 18}, {9, 21, 22}, |
||
247 | {17, 18, 19}, {9, 10, 15}, {11, 14, 18}, {2, 14, 18}}; |
||
248 | for (char PosNi = 0; PosNi < 7; PosNi++) |
||
249 | { |
||
250 | bool IsPosR = 1; |
||
251 | for (char ShNi = 0; ShNi < 3; ShNi++) |
||
252 | { |
||
253 | char DNomSh = (Csm == 1) ? (31 - PosSH[PosNi][ShNi]) |
||
254 | : PosSH[PosNi][ShNi]; |
||
255 | if (Osm == 1) {int x, y; NumToPole(DNomSh, x, y); |
||
256 | DNomSh = PoleToNum(y, x);} |
||
257 | if (Pos.SH[DNomSh] != 3 + (Cpos3 == Pos.Move)) IsPosR = 0; |
||
258 | } |
||
259 | if (IsPosR) |
||
260 | { |
||
261 | if (PosNi == 3) |
||
262 | { |
||
263 | if (Cpos3 == 1) {if (Pos.SH[(Csm == 1) ? 29 : 2] != |
||
264 | 4 - (Cpos3 == Pos.Move) && Pos.SH[(Csm == 1) ? 11 : 20] |
||
265 | != 4 - (Cpos3 == Pos.Move)) PrP = 216;} |
||
266 | else |
||
267 | { |
||
268 | bool PrPZ = 1; |
||
269 | for (int i = 0; i < 6; i++) |
||
270 | if (Pos.SH[PoleToNum((Csm == 1) ? (i + 2) : i, |
||
271 | (Csm == 1) ? (7 - i) : (5 - i))] == |
||
272 | 4 - (Cpos3 == Pos.Move)) PrPZ = 0; |
||
273 | if (PrPZ) PrP = -216; |
||
274 | } |
||
275 | } |
||
276 | else if (PosNi == 4) |
||
277 | { |
||
278 | if (Cpos3 == 1) |
||
279 | {if (Pos.SH[ 0] != 4 - (Cpos3 == Pos.Move) |
||
280 | && Pos.SH[ 4] != 4 - (Cpos3 == Pos.Move) |
||
281 | && Pos.SH[27] != 4 - (Cpos3 == Pos.Move) |
||
282 | && Pos.SH[31] != 4 - (Cpos3 == Pos.Move)) PrP = 216;} |
||
283 | else {if (Pos.SH[(Csm == Osm) ? 4 : 0] != 4 - (Cpos3 == Pos.Move) |
||
284 | && Pos.SH[(Csm == Osm) ? 8 : 5] != 4 - (Cpos3 == Pos.Move) |
||
285 | && Pos.SH[(Csm == Osm) ? 26 : 23] != 4 - (Cpos3 == Pos.Move) |
||
286 | && Pos.SH[(Csm == Osm) ? 31 : 27] != 4 - (Cpos3 == Pos.Move)) |
||
287 | PrP = -216;} |
||
288 | } |
||
289 | else if (PosNi == 5) |
||
290 | { |
||
291 | char DNomSh = (Cpos3 == 1) ? ((Osm == 1) ? 16 : 6) |
||
292 | : ((Osm == 1) ? 20 : 2); |
||
293 | if (Csm == 1) DNomSh = 31 - DNomSh; |
||
294 | if (Pos.SH[DNomSh] == 4 - (Cpos3 == Pos.Move)) |
||
295 | PrP = (Cpos3 == 1) ? 160 : -160; |
||
296 | } |
||
297 | else if (PosNi == 6) |
||
298 | { |
||
299 | if (Cpos3 == 1) |
||
300 | {if (Pos.SH[ 1] == 4 - (Cpos3 == Pos.Move) |
||
301 | || Pos.SH[12] == 4 - (Cpos3 == Pos.Move) |
||
302 | || Pos.SH[19] == 4 - (Cpos3 == Pos.Move) |
||
303 | || Pos.SH[30] == 4 - (Cpos3 == Pos.Move)) PrP = 168;} |
||
304 | else |
||
305 | {if (Pos.SH[(Csm == 1) ? 15 : 6] == 4 - (Cpos3 == Pos.Move) |
||
306 | || Pos.SH[(Csm == 1) ? 25 : 16] == 4 - (Cpos3 == Pos.Move)) |
||
307 | PrP = -168;} |
||
308 | } |
||
309 | else PrP = ((Cpos3 == 1) ? 1 : -1) * ((PosNi == 0) ? 200 : 208); |
||
310 | } |
||
311 | } |
||
312 | } |
||
313 | } |
||
314 | if (PrP == 0) |
||
315 | { |
||
316 | unsigned char HwoBD = 0; char NShSBD = 0; |
||
317 | for (int i = 0; i < 8; i++) |
||
318 | { |
||
319 | char ShBD = Pos.SH[PoleToNum(i, 7 - i)]; |
||
320 | if (ShBD == 3 + Pos.Move) {HwoBD |= 2; NShSBD++;} |
||
321 | else if (ShBD == 4 - Pos.Move) {HwoBD |= 1; NShSBD++;} |
||
322 | } |
||
323 | if (NDM1 >= 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0 && HwoBD == 2) |
||
324 | { |
||
325 | if (NShSBD >= 1) NextPreim -= NShSBD - 1; |
||
326 | if (Pos.SH[ 3] == 3 + Pos.Move) NextPreim--; |
||
327 | if (Pos.SH[28] == 3 + Pos.Move) NextPreim--; |
||
328 | char Drg1 = 0; bool Drg1p = 0; char DrgPS = 0; |
||
329 | for (int i = 0; i < 7; i++) |
||
330 | { |
||
331 | char Sh7D = Pos.SH[PoleToNum(i, i + 1)]; |
||
332 | if (Sh7D == 3 + Pos.Move) {Drg1++; DrgPS |= 1;} |
||
333 | else if (Sh7D == 4 - Pos.Move) Drg1p = 1; |
||
334 | Sh7D = Pos.SH[PoleToNum(i + 1, i)]; |
||
335 | if (Sh7D == 3 + Pos.Move) {Drg1++; DrgPS |= 2;} |
||
336 | else if (Sh7D == 4 - Pos.Move) Drg1p = 1; |
||
337 | } |
||
338 | if (Pos.SH[0] == 3 + Pos.Move || Pos.SH[4] == 3 + Pos.Move || |
||
339 | Pos.SH[27] == 3 + Pos.Move || Pos.SH[31] == 3 + Pos.Move) |
||
340 | {if (Drg1p) NextPreim += 4; else NextPreim -= 1;} |
||
341 | if ((Pos.SH[14] == 3 + Pos.Move) == (Pos.SH[17] == 3 + Pos.Move)) |
||
342 | {if (Drg1 == 1) NextPreim += 2;} |
||
343 | else |
||
344 | { |
||
345 | if (Drg1 >= 2) |
||
346 | { |
||
347 | if (Drg1 > 2) NextPreim -= 1; |
||
348 | if (DrgPS == 3) NextPreim += 4; |
||
349 | if (Drg1p) NextPreim += 4; else NextPreim += 16; |
||
350 | if (!Drg1p && DrgPS) |
||
351 | { |
||
352 | Drg1 = 0; Drg1p = 0; DrgPS = 0; |
||
353 | for (int i = 0; i < 6; i++) |
||
354 | { |
||
355 | char Sh7D = Pos.SH[PoleToNum(i, 5 - i)]; |
||
356 | if (Sh7D == 3 + Pos.Move) {Drg1++; DrgPS |= 1;} |
||
357 | else if (Sh7D == 4 - Pos.Move) Drg1p = 1; |
||
358 | Sh7D = Pos.SH[PoleToNum(i + 2, 7 - i)]; |
||
359 | if (Sh7D == 3 + Pos.Move) {Drg1++; DrgPS |= 2;} |
||
360 | else if (Sh7D == 4 - Pos.Move) Drg1p = 1; |
||
361 | } |
||
362 | if (Pos.SH[2] == 3 + Pos.Move || Pos.SH[11] == 3 + Pos.Move || |
||
363 | Pos.SH[20] == 3 + Pos.Move || Pos.SH[29] == 3 + Pos.Move) |
||
364 | NextPreim += 4; |
||
365 | if ((Pos.SH[14] == 3 + Pos.Move) |
||
366 | ? (Pos.SH[13] == 3 + Pos.Move || Pos.SH[22] == 3 + Pos.Move) |
||
367 | : (Pos.SH[ 9] == 3 + Pos.Move || Pos.SH[18] == 3 + Pos.Move)) |
||
368 | { |
||
369 | if (Drg1 >= 2) |
||
370 | { |
||
371 | if (DrgPS == 3) NextPreim += 4; |
||
372 | if (Drg1p) NextPreim += 4; else NextPreim += 16; |
||
373 | } |
||
374 | else if (Drg1 == 1) NextPreim += 1; |
||
375 | } |
||
376 | else if (Drg1 == 1) NextPreim += 2; |
||
377 | } |
||
378 | } |
||
379 | } |
||
380 | } |
||
381 | else if (NDM0 >= 3 && NDM1 == 1 && NSH0 == 0 && NSH1 == 0 && HwoBD == 1) |
||
382 | { |
||
383 | if (NShSBD >= 1) NextPreim += NShSBD - 1; |
||
384 | if (Pos.SH[ 3] == 4 - Pos.Move) NextPreim++; |
||
385 | if (Pos.SH[28] == 4 - Pos.Move) NextPreim++; |
||
386 | char Drg1 = 0; bool Drg1p = 0; char DrgPS = 0; |
||
387 | for (int i = 0; i < 7; i++) |
||
388 | { |
||
389 | char Sh7D = Pos.SH[PoleToNum(i, i + 1)]; |
||
390 | if (Sh7D == 4 - Pos.Move) {Drg1++; DrgPS |= 1;} |
||
391 | else if (Sh7D == 3 + Pos.Move) Drg1p = 1; |
||
392 | Sh7D = Pos.SH[PoleToNum(i + 1, i)]; |
||
393 | if (Sh7D == 4 - Pos.Move) {Drg1++; DrgPS |= 2;} |
||
394 | else if (Sh7D == 3 + Pos.Move) Drg1p = 1; |
||
395 | } |
||
396 | if (Pos.SH[0] == 4 - Pos.Move || Pos.SH[4] == 4 - Pos.Move || |
||
397 | Pos.SH[27] == 4 - Pos.Move || Pos.SH[31] == 4 - Pos.Move) |
||
398 | {if (Drg1p) NextPreim -= 4; else NextPreim += 1;} |
||
399 | if ((Pos.SH[14] == 4 - Pos.Move) == (Pos.SH[17] == 4 - Pos.Move)) |
||
400 | {if (Drg1 == 1) NextPreim -= 2;} |
||
401 | else |
||
402 | { |
||
403 | if (Drg1 >= 2) |
||
404 | { |
||
405 | if (Drg1 > 2) NextPreim += 1; |
||
406 | if (DrgPS == 3) NextPreim -= 4; |
||
407 | if (Drg1p) NextPreim -= 4; else NextPreim -= 16; |
||
408 | if (!Drg1p && DrgPS) |
||
409 | { |
||
410 | Drg1 = 0; Drg1p = 0; DrgPS = 0; |
||
411 | for (int i = 0; i < 6; i++) |
||
412 | { |
||
413 | char Sh7D = Pos.SH[PoleToNum(i, 5 - i)]; |
||
414 | if (Sh7D == 4 - Pos.Move) {Drg1++; DrgPS |= 1;} |
||
415 | else if (Sh7D == 3 + Pos.Move) Drg1p = 1; |
||
416 | Sh7D = Pos.SH[PoleToNum(i + 2, 7 - i)]; |
||
417 | if (Sh7D == 4 - Pos.Move) {Drg1++; DrgPS |= 2;} |
||
418 | else if (Sh7D == 3 + Pos.Move) Drg1p = 1; |
||
419 | } |
||
420 | if (Pos.SH[2] == 4 - Pos.Move || Pos.SH[11] == 4 - Pos.Move || |
||
421 | Pos.SH[20] == 4 - Pos.Move || Pos.SH[29] == 4 - Pos.Move) |
||
422 | NextPreim -= 4; |
||
423 | if ((Pos.SH[14] == 4 - Pos.Move) |
||
424 | ? (Pos.SH[13] == 4 - Pos.Move || Pos.SH[22] == 4 - Pos.Move) |
||
425 | : (Pos.SH[ 9] == 4 - Pos.Move || Pos.SH[18] == 4 - Pos.Move)) |
||
426 | { |
||
427 | if (Drg1 >= 2) |
||
428 | { |
||
429 | if (DrgPS == 3) NextPreim -= 4; |
||
430 | if (Drg1p) NextPreim -= 4; else NextPreim -= 16; |
||
431 | } |
||
432 | else if (Drg1 == 1) NextPreim -= 1; |
||
433 | } |
||
434 | else if (Drg1 == 1) NextPreim -= 2; |
||
435 | } |
||
436 | } |
||
437 | } |
||
438 | } |
||
439 | else if (NDM1 >= 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0 && HwoBD == 1) |
||
440 | { |
||
441 | char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; |
||
442 | char Add = 0; |
||
443 | for (int i = 0; i < 4; i++) Add |= |
||
444 | (char(Pos.SH[Best4P[i][0]] == 3 + Pos.Move) * 3 + |
||
445 | char(Pos.SH[Best4P[i][1]] == 3 + Pos.Move)); |
||
446 | if (Add >= 4) NextPreim += 3; else if (Add == 3) NextPreim += 2; |
||
447 | else if (Add >= 1) NextPreim += 1; |
||
448 | } |
||
449 | else if (NDM0 >= 3 && NDM1 == 1 && NSH0 == 0 && NSH1 == 0 && HwoBD == 2) |
||
450 | { |
||
451 | char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; |
||
452 | char Add = 0; |
||
453 | for (int i = 0; i < 4; i++) Add |= |
||
454 | (char(Pos.SH[Best4P[i][0]] == 4 - Pos.Move) * 3 + |
||
455 | char(Pos.SH[Best4P[i][1]] == 4 - Pos.Move)); |
||
456 | if (Add >= 4) NextPreim -= 3; else if (Add == 3) NextPreim -= 2; |
||
457 | else if (Add >= 1) NextPreim -= 1; |
||
458 | } |
||
459 | } |
||
460 | else NextPreim += PrP; |
||
461 | } |
||
462 | } |
||
463 | } |
||
464 | Parent->TakeMove(Pos, -NextPreim); |
||
465 | } |
||
466 | |||
467 | void TakeMove(CompPosition &Pos1, long Preim) |
||
468 | { |
||
469 | if (Preim >= 16777216) Preim--; else if (Preim <= -16777216) Preim++; |
||
470 | bool b = (NMax == 0 || Preim > NextPreim); if (NMax == 0) NMax = 1; |
||
471 | if (!b && Preim == NextPreim) {b = (random(NMax + 1) == 0); NMax++;} |
||
472 | if (b) {if (NomP == BCM_START) *NextPos = Pos1; NextPreim = Preim;} |
||
473 | } |
||
474 | |||
475 | CompPosition Pos; int NomP; BestMove *Parent; |
||
476 | |||
477 | CompPosition *NextPos; char NMax; long NextPreim; |
||
478 | }; |
||
479 | |||
480 | class MoveEatParam |
||
481 | { |
||
482 | public: |
||
483 | char Home; |
||
484 | char Eaten[15]; char NomEat; |
||
485 | BestMove* BM; |
||
486 | |||
487 | MoveEatParam(){} |
||
488 | |||
489 | char RealPlase(char N) |
||
490 | { |
||
491 | char RP; |
||
492 | if (N == Home) RP = 0; else RP = BM->Pos.SH[N]; |
||
493 | for (int i = 0; i < NomEat; i++) if (N == Eaten[i]) RP = 0; |
||
494 | return RP; |
||
495 | } |
||
496 | }; |
||
497 | |||
498 | void EatContinue(MoveEatParam& MEP, bool IsDMC, char Start, char Kurs) |
||
499 | { |
||
500 | bool IsCanEat = 0; |
||
501 | int x, y; NumToPole(Start, x, y); |
||
502 | if (y == 7 - MEP.BM->Pos.Move * 7) IsDMC = 1; |
||
503 | if (IsDMC) |
||
504 | { |
||
505 | int KursY = Kurs / abs(Kurs); int KursX = Kurs - KursY * 2; |
||
506 | for (int i = x, j = y; |
||
507 | i >= 0 && j >= 0 && i < 8 && j < 8; |
||
508 | i += KursX, j += KursY) |
||
509 | { |
||
510 | int Shash = MEP.RealPlase(PoleToNum(i, j)); |
||
511 | if (Shash == 2 - MEP.BM->Pos.Move || Shash == 4 - MEP.BM->Pos.Move) |
||
512 | { |
||
513 | if (i + KursX >= 0 && j + KursY >= 0 && i + KursX < 8 && j + KursY < 8) |
||
514 | if (MEP.RealPlase(PoleToNum(i + KursX, j + KursY)) == 0) |
||
515 | { |
||
516 | IsCanEat = 1; |
||
517 | MEP.Eaten[MEP.NomEat++] = PoleToNum(i, j); |
||
518 | EatContinue(MEP, 1, PoleToNum(i + KursX, j + KursY), |
||
519 | KursX + 2 * KursY); |
||
520 | MEP.NomEat--; |
||
521 | } |
||
522 | break; |
||
523 | } |
||
524 | else if (Shash == 1 + MEP.BM->Pos.Move || Shash == 3 + MEP.BM->Pos.Move) break; |
||
525 | else for (int Rotate = -1; Rotate <= 1; Rotate += 2) |
||
526 | for (int i1 = i + KursY * Rotate, j1 = j - KursX * Rotate; |
||
527 | i1 >= 0 && j1 >= 0 && i1 < 8 && j1 < 8; |
||
528 | i1 += KursY * Rotate, j1 -= KursX * Rotate) |
||
529 | { |
||
530 | int Shash = MEP.RealPlase(PoleToNum(i1, j1)); |
||
531 | if (Shash == 2 - MEP.BM->Pos.Move || Shash == 4 - MEP.BM->Pos.Move) |
||
532 | { |
||
533 | if (i1 + KursY * Rotate >= 0 && j1 - KursX * Rotate >= 0 && |
||
534 | i1 + KursY * Rotate < 8 && j1 - KursX * Rotate < 8) |
||
535 | if (MEP.RealPlase(PoleToNum(i1 + KursY * Rotate, j1 - KursX * Rotate)) == 0) |
||
536 | { |
||
537 | IsCanEat = 1; |
||
538 | MEP.Eaten[MEP.NomEat++] = PoleToNum(i1, j1); |
||
539 | EatContinue(MEP, 1, PoleToNum(i1 + KursY * Rotate, |
||
540 | j1 - KursX * Rotate), |
||
541 | KursY * Rotate - 2 * KursX * Rotate); |
||
542 | MEP.NomEat--; |
||
543 | } |
||
544 | break; |
||
545 | } |
||
546 | else if (Shash == 1 + MEP.BM->Pos.Move || Shash == 3 + MEP.BM->Pos.Move) break; |
||
547 | } |
||
548 | } |
||
549 | if (!IsCanEat) |
||
550 | { |
||
551 | for (int ii = x, jj = y; ii >= 0 && jj >= 0 && |
||
552 | ii < 8 && jj < 8; ii += KursX, jj += KursY) |
||
553 | { |
||
554 | if (MEP.RealPlase(PoleToNum(ii, jj)) != 0) break; |
||
555 | BestMove BMove(MEP.BM->Pos, MEP.BM); BMove.Pos.SH[MEP.Home] = 0; |
||
556 | for (int i = 0; i < MEP.NomEat; i++) {BMove.Pos.SH[MEP.Eaten[i]] = 0;} |
||
557 | BMove.Pos.SH[PoleToNum(ii, jj)] = 3 + MEP.BM->Pos.Move; |
||
558 | BMove.Pos.Move = !BMove.Pos.Move; |
||
559 | BMove.StartMove(); |
||
560 | } |
||
561 | } |
||
562 | } |
||
563 | else |
||
564 | { |
||
565 | for (int i = -1; i <= 1; i += 2) for (int j = -1; j <= 1; j += 2) |
||
566 | if (i + 2 * j != -Kurs) if (x + 2 * i >= 0 |
||
567 | && y + 2 * j >= 0 && x + 2*i < 8 && y + 2 * j < 8) |
||
568 | { |
||
569 | char FESH = PoleToNum(x + i, y + j); char FESHrp = MEP.RealPlase(FESH); |
||
570 | char FMSH = PoleToNum(x + 2 * i, y + 2 * j); |
||
571 | if ((FESHrp == 2 - MEP.BM->Pos.Move || FESHrp == 4 - MEP.BM->Pos.Move) |
||
572 | && MEP.RealPlase(FMSH) == 0) |
||
573 | { |
||
574 | IsCanEat = 1; |
||
575 | MEP.Eaten[MEP.NomEat++] = FESH; |
||
576 | EatContinue(MEP, 0, FMSH, i + 2 * j); |
||
577 | MEP.NomEat--; |
||
578 | } |
||
579 | } |
||
580 | if (!IsCanEat) |
||
581 | { |
||
582 | BestMove BMove(MEP.BM->Pos, MEP.BM); BMove.Pos.SH[MEP.Home] = 0; |
||
583 | for (int i = 0; i < MEP.NomEat; i++) {BMove.Pos.SH[MEP.Eaten[i]] = 0;} |
||
584 | BMove.Pos.SH[Start] = 1 + MEP.BM->Pos.Move; |
||
585 | BMove.Pos.Move = !BMove.Pos.Move; |
||
586 | BMove.StartMove(); |
||
587 | } |
||
588 | } |
||
589 | } |
||
590 | |||
591 | bool MoveEat(BestMove* BM) |
||
592 | { |
||
593 | bool IsCanEat = 0; |
||
594 | MoveEatParam MEP; MEP.BM = BM; |
||
595 | for (MEP.Home = 0; MEP.Home < 32; MEP.Home++) |
||
596 | { |
||
597 | if (BM->Pos.SH[MEP.Home] == 1 + BM->Pos.Move) |
||
598 | { |
||
599 | int x, y; NumToPole(MEP.Home, x, y); |
||
600 | for (int i = -1; i <= 1; i += 2) for (int j = -1; j <= 1; j += 2) |
||
601 | if (x + 2*i >= 0 && y + 2*j >= 0 && x + 2*i < 8 && y + 2*j < 8) |
||
602 | { |
||
603 | int FESH = PoleToNum(x + i, y + j); |
||
604 | int FMSH = PoleToNum(x + 2 * i, y + 2 * j); |
||
605 | if ((BM->Pos.SH[FESH] == 2 - BM->Pos.Move || BM->Pos.SH[FESH] == 4 - BM->Pos.Move) |
||
606 | && BM->Pos.SH[FMSH] == 0) |
||
607 | { |
||
608 | IsCanEat = 1; |
||
609 | MEP.NomEat = 1; MEP.Eaten[0] = FESH; |
||
610 | EatContinue(MEP, 0, FMSH, i + 2 * j); |
||
611 | } |
||
612 | } |
||
613 | } |
||
614 | else if (BM->Pos.SH[MEP.Home] == 3 + BM->Pos.Move) |
||
615 | { |
||
616 | int x, y; NumToPole(MEP.Home, x, y); |
||
617 | for (int i = -1; i <= 1; i += 2) for (int j = -1; j <= 1; j += 2) |
||
618 | for (int a = x + i, b = y + j; |
||
619 | a >= 0 && b >= 0 && a < 8 && b < 8; |
||
620 | a += i, b += j) |
||
621 | { |
||
622 | char Shash = PoleToNum(a, b); |
||
623 | char Shash1 = PoleToNum(a + i, b + j); |
||
624 | if (BM->Pos.SH[Shash] == 2 - BM->Pos.Move || BM->Pos.SH[Shash] == 4 - BM->Pos.Move) |
||
625 | { |
||
626 | if (a + i >= 0 && b + j >= 0 && a + i < 8 && b + j < 8) |
||
627 | if (BM->Pos.SH[Shash1] == 0) |
||
628 | { |
||
629 | IsCanEat = 1; |
||
630 | MEP.NomEat = 1; MEP.Eaten[0] = Shash; |
||
631 | EatContinue(MEP, 1, Shash1, i + 2 * j); |
||
632 | } |
||
633 | break; |
||
634 | } |
||
635 | else if (BM->Pos.SH[Shash] == 1 + BM->Pos.Move || BM->Pos.SH[Shash] == 3 + BM->Pos.Move) break; |
||
636 | } |
||
637 | } |
||
638 | } |
||
639 | return IsCanEat; |
||
640 | } |
||
641 | |||
642 | bool MovePr(BestMove* BM) |
||
643 | { |
||
644 | bool IsCanMove = 0; |
||
645 | for (int N = 0; N < 32; N++) |
||
646 | { |
||
647 | if (BM->Pos.SH[N] == 1 + BM->Pos.Move) |
||
648 | { |
||
649 | int x, y; NumToPole(N, x, y); |
||
650 | int j = 1 - 2 * BM->Pos.Move; |
||
651 | for (int i = -1; i <= 1; i += 2) |
||
652 | if (x + i >= 0 && y + j >= 0 && x + i < 8 && y + j < 8) |
||
653 | { |
||
654 | int FMSH = PoleToNum(x + i, y + j); |
||
655 | if (BM->Pos.SH[FMSH] == 0) |
||
656 | { |
||
657 | IsCanMove = 1; |
||
658 | BestMove BMove(BM->Pos, BM); BMove.Pos.SH[N] = 0; |
||
659 | BMove.Pos.SH[FMSH] = 1 + BM->Pos.Move + 2 * |
||
660 | (y + j == 7 - BM->Pos.Move * 7); |
||
661 | BMove.Pos.Move = !BMove.Pos.Move; |
||
662 | BMove.StartMove(); |
||
663 | } |
||
664 | } |
||
665 | } |
||
666 | else if (BM->Pos.SH[N] == 3 + BM->Pos.Move) |
||
667 | { |
||
668 | int x, y; NumToPole(N, x, y); |
||
669 | for (int i = -1; i <= 1; i += 2) for (int j = -1; j <= 1; j += 2) |
||
670 | for (int a = x + i, b = y + j; |
||
671 | a >= 0 && b >= 0 && a < 8 && b < 8; |
||
672 | a += i, b += j) |
||
673 | { |
||
674 | if (BM->Pos.SH[PoleToNum(a, b)] != 0) break; |
||
675 | IsCanMove = 1; |
||
676 | BestMove BMove(BM->Pos, BM); BMove.Pos.SH[N] = 0; |
||
677 | BMove.Pos.SH[PoleToNum(a, b)] = 3 + BM->Pos.Move; |
||
678 | BMove.Pos.Move = !BMove.Pos.Move; |
||
679 | BMove.StartMove(); |
||
680 | } |
||
681 | } |
||
682 | } |
||
683 | return IsCanMove; |
||
684 | } |
||
685 | |||
686 | int StartMove(Position& Pos, bool CompColor) |
||
687 | { |
||
688 | CompPosition Pos1; Pos1.Init(Pos, CompColor); |
||
689 | BestMove MainMove(Pos1); MainMove.NomP = BCM_START; |
||
690 | MainMove.NextPos = &Pos1; |
||
691 | if (!MoveEat(&MainMove)) if (!MovePr(&MainMove)) return 1; |
||
692 | Pos = Pos1; MainMove.Pos = Pos1; |
||
693 | MainMove.NomP = BCM_ISM1; |
||
694 | if (!MoveEat(&MainMove)) if (!MovePr(&MainMove)) return -1; |
||
695 | return 0; |
||
696 | } |
||
697 | |||
698 | #undef BCM_ISM1 |
||
699 | #undef BCM_START |
||
700 | } |
||
701 | |||
702 | |||
703 | class TemporaryPlayer : public TChPlayer |
||
704 | { |
||
705 | public: |
||
706 | TemporaryPlayer() {} |
||
707 | |||
708 | virtual int Move(PMv &pmv); |
||
709 | }; |
||
710 | |||
711 | int TemporaryPlayer::Move(PMv &pmv) |
||
712 | { |
||
713 | TComputerPlayer::Z z; |
||
714 | z.FindAllMoves(pmv); |
||
715 | if (z.narr <= 0) return 0; |
||
716 | int r, s = ComputerMove::StartMove(pmv.pos, pmv.pos.wmove); |
||
717 | if (s > 0) return 0; |
||
718 | for (r = 0; r < z.narr; r++) |
||
719 | { |
||
720 | if (memcmp(z.array[r].pos.SH, pmv.pos.SH, sizeof(pmv.pos.SH)) == 0) |
||
721 | { |
||
722 | pmv = z.array[r]; |
||
723 | return 1; |
||
724 | } |
||
725 | } |
||
726 | return 0; |
||
727 | } |
||
728 | |||
729 | #endif //_HEADER_TMP_PLAYER_H>=>>>=>=>>>=>>>>>>=>=>>>=>=>>>>>=>=>>>>>>>>=>>>>>>=>>>>>>>>>>>=>=>>>>>>>>>>>>>>>>> |