Subversion Repositories Kolibri OS

Rev

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