Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  730.