C++ simple gobang AI design and implementation

  • 2020-06-12 10:05:45
  • OfStack

This article shares C++5 sub-chess AI design code for your reference, the specific content is as follows

Design idea: get the information through the interface to determine the color, set_chess function to determine the landing point.

Scores of two colored pieces are given for each point position, which are stored in two 15*15 arrays respectively, and the array subscripts represent the positions of the points. After determining where the maximum value is in the array, traverse the array to find all the positions corresponding to the maximum value, then count the points of the pieces of another color to these positions, and select the maximum value once again, so as to determine the position of the drop point. Design of scoring function: count in 4 directions and add them up. For the score statistics in a certain direction, it can be divided into positive and negative directions. If there are 5 consecutive points, a maximum value (the highest score) will be directly returned. In other cases, different weights are set according to different situations, and the events that trigger the end of statistics in a certain direction are as follows: More than two blank squares; You hit a checkerboard boundary. Which have different color of pieces and boundary are considered to be one side to be blocked, compared with the blank for appropriate points, while a blank compared to fully continuous should appropriate points again, finally take 10 times the power, to ensure the priority of different circumstances, namely not appear because down to the position A can form four living under 2 instead of 4 position B can form a live.

The specific code is as follows:


#pragma once
#ifndef AI_H
#define AI_H
#include "renju.h"
#include <vector>
#include <math.h>

class Ai
{
public:
  Ai(chessboard &bd, state hm)
  {
    ms.set_color(hm);
    this->p_bd = &bd;
  }
  chess set_chess();

private:
  int evaluate(position pos, state color, position (*pf)(position ,bool ));// Gives the drop position and direction movement function, and returns the score of the drop position in that direction 

  int point(position pos, state color);// given 1 Returns the score for that drop 

  void whole_points(int points[][15], state color );// For a given color   , record the color of the pieces under each 1 The score 

  int best_posits(const int points[][15], position p_s[], int& count); // Give an array of scores and find out where the maximum value corresponds to (it could be more than that 1 ), returns the maximum score 

  chess ms;
  const chessboard *p_bd;
};

// Determine the move later 
chess Ai:: set_chess()
{
  int points_b[15][15];    // Record black's points 
  int points_w[15][15];    // Record white's points 
  position best_b[20];    // Record the position where black ends up with the highest score 
  position best_w[20];    // Record the position of the position corresponding to white's maximum score 
  int s_black = 0, s_white = 0;    // Record the maximum points for black and white 
  int count_b = 0,count_w = 0;      // Record the number of positions corresponding to the maximum score of black and white 

  whole_points(points_b, black);
  whole_points(points_w, white);
  s_white = best_posits(points_w, best_w,count_w);
  s_black = best_posits(points_b, best_b,count_b);

  if( s_black > s_white )   // The highest score of black is higher than that of White, and the highest score of White is selected from the position corresponding to the highest score of black 
  {
  sb: int a[20];
    for(int i = 0;i < count_b;i++)
    {
      a[i] = point(best_b[i],white);
    }
    int max_w = MAX(a, count_b);
    for(int i = 0;i < count_b;i++)
    {
      if(a[i] == max_w)
      {
        ms.set_point(best_b[i]);
        return ms;
      }
    }
  }
  if( s_black < s_white )   // The highest score of white is higher than that of black, and the position with the highest score of White is selected 
  {
  sw: int a[20];
    for(int i = 0;i < count_w;i++)
    {
      a[i] = point(best_w[i],black);
    }
    int max_b = MAX(a, count_b);
    for(int i = 0;i < count_w;i++)
    {
      if(a[i] == max_b)
      {
        ms.set_point(best_w[i]);
        return ms;
      }
    }
  }
  if( s_black == s_white )  
  {
    if(ms.get_color() == white)
      goto sw;
    if(ms.get_color() == black)
      goto sb;
  }
}

// Give an array of scores and find out where the maximum value corresponds to (it could be more than that 1 ), returns the maximum score 
int Ai::best_posits(const int points[][15], position p_s[], int& count)
{
  int max_row[15];
  int max_all;
  for(int i = 0;i < 15;i++)
  max_row[i] = MAX(points[i],15);
  max_all = MAX(max_row,15);
  cout<<"maxall"<<max_all;
  count = 0;
  for(int i = 0;i < 15;i++)
  {
    for(int j =0;j < 15;j++)
    {
      if(points[i][j] == max_all)
      {
        position x(i,j);
        p_s[count] = x;
        count++;
      }
    }
  }
  return max_all;
}

// For a given color   , record the color of the pieces under each 1 The score 
void Ai::whole_points(int points[][15], state color )
{
  for( int i =0;i < 15;i++)
  {
    for(int j = 0;j < 15;j++)
    {
      position temp(i,j);
      points[i][j] = point(temp,color);
    }
  }
}

// A position function used to move a piece up and down and determine if it is out of bounds 
position up(position pos,bool dir)
{
  position r;
  if(dir)
  {
    while(pos.y > 0)
    {
      r.x = pos.x;
      r.y = pos.y - 1;
      return r;
    }
    throw 0;
  }
  else
  {
    while(pos.y < 14)
    {
      r.x = pos.x;
      r.y = pos.y + 1;
      return r;
    }
    throw 0;
  }
}

// Position function, used to move the pieces left and right and determine if they are out of bounds 
position left(position pos,bool dir)
{
  position r;
  if(dir)
  {
    while(pos.x > 0)
    {
      r.x = pos.x - 1;
      r.y = pos.y;
      return r;
    }
    throw 0;
  }
  else
  {
    while(pos.x < 14)
    {
      r.x = pos.x + 1;
      r.y = pos.y;
      return r;
    }
    throw 0;
  }
}

// The position function is used to move pieces from left to right and to determine if they are out of bounds 
position left_up(position pos,bool dir)
{
  position r;
  if(dir)
  {
    while(pos.x > 0 && pos.y > 0)
    {
      r.x = pos.x - 1;
      r.y = pos.y - 1;
      return r;
    }
    throw 0;
  }
  else
  {
    while(pos.x < 14 && pos.y < 14)
    {
      r.x = pos.x + 1;
      r.y = pos.y + 1;
      return r;
    }
    throw 0;
  }
}

// The position function is used to move a piece from the top right to the bottom left and to determine if it is out of bounds 
position right_up(position pos,bool dir)
{
  position r;
  if(dir)
  {
    while(pos.x < 14 && pos.y > 0)
    {
      r.x = pos.x + 1;
      r.y = pos.y - 1;
      return r;
    }
    throw 0;
  }
  else
  {
    while(pos.x > 0 && pos.y < 14)
    {
      r.x = pos.x - 1;
      r.y = pos.y + 1;
      return r;
    }
    throw 0;
  }
}

int Ai::evaluate(position pos, state color, position (*pf)(position ,bool ))
{
  int sum = 0;
  position p_i = pos;
  int count = 0,mc = 1;
  bool flag = true;
  int c_blank = 0;
  state judge_t;

  try
  {
    do
    {
      p_i = pf(p_i, flag);
      judge_t = p_bd -> viewboard(p_i);
      if(judge_t == color)
      {
        if(c_blank == 1)
        {
          count += 1;
        }
        else
        {
          mc++;
          if(mc == 5)
            return 100000000000;
          count += 2;
        }
      }
      else 
      {
        if(judge_t == blank)
        {
          if(c_blank >= 1)
            flag = false;
          else
          {
            c_blank++;
          }
        }
        else
        {
          count-=2;
          flag = false;
        }
      }
    }while(flag);
  }
  catch(int key)
  {
    flag = false;
    if(c_blank == 0)count-=2;
  }

  p_i = pos;
  int b_blank = 0;// Record the other 1 A half blank grid 
  try
  {
    do
    {
      p_i = pf(p_i, flag);
      judge_t = p_bd -> viewboard(p_i);
      if(judge_t == color)
      {
        if(b_blank == 1)
        {
          count += 1;
        }
        else
        {
          if(c_blank == 0 && b_blank == 0)
            mc++;
          if(mc == 5)
            return 100000000000;
          count += 2;
        }
      }
      else 
      {
        if(judge_t == blank)
        {
        if(b_blank >= 1)
            flag = true;
          else
          {
            b_blank++;
          }
        }
        else
        {
          count-=2;
          flag = true;
        }
      }
    }while(!flag);
  }
  catch(int key)
  {
    if(b_blank == 0)count-=2;
    return pow(10,count);
  }
  return pow(10,count);
}
// given 1 Returns the score for that drop 
int Ai::point(position pos, state color)
{
  if(p_bd -> viewboard(pos) != blank)
  {
    return 0;
  }

  position (*p_f)(position,bool) = NULL;
  int sum = 0;

  p_f = up;
  sum += evaluate(pos, color, p_f);
  p_f = left;
  sum += evaluate(pos, color, p_f);
  p_f = left_up;
  sum += evaluate(pos, color, p_f);
  p_f = right_up;
  sum += evaluate(pos, color, p_f);

  return sum;
}
#endif

The required header file was mentioned in the previous article: C++ language design and implementation of 5 child chess pieces


Related articles: