[人工智能]五子棋

#include<iostream>
#include<memory.h>
#include<string>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
const int N = 20; //定义棋盘规模
int pace = 0;//统计步数
const char chess[2] = {'X', 'O'}; //定义数组显示棋子颜色 黑 白

bool SystemError = 0;

int lastI = 0, lastJ = 0;
int maxI = 9, maxJ = 9;

void InitChess(char *board)//初始化棋盘√
{
  for(int i = 0; i < N; i++)
    for(int j = 0; j < N; j++)
      board[i * N + j] = '.';
  return;
}

void PrintChess(char *board)//打印棋盘√
{
  for(int i = 0; i < N; i++)
    printf("%2d", i + 1);
  cout << endl;
  for(int i = 0; i < N; i++)
  {
    printf("%2d", i + 1);

    for(int j = 0; j < N; j++)
    {
      cout << board[i * N + j];
      cout << " ";
    }
    cout << endl;
  }
  return;
}

void Player(char * board, int color)//玩家落子√
{
  int i, j;
  while(1)
  {
    cout << "请玩家输入坐标(x y)" << endl;

    cin >> j >> i;

    i--;
    j--;

    if(i < 0 || i > 20 || j < 0 || j > 20)
      cout << "请输入1--20有效数" << endl;
    else if(board[i * N + j] != '.')
      cout << "已有棋子,请重下" << endl;
    else
      break;
  }

  board[i * N + j] = chess[color];//在棋盘上标记
  //记录当前棋子坐标
  lastI = i;
  lastJ = j;
  pace++;//步数+1
  return;
}


void ComputeValue(int color, char *board)//计算落子位置值评估函数√
{
  int maxmax = 0, mark[400] = {0};//初始分数为0
  char I;
  char U;

  if(color == 0)
  {
    I = 'X';
    U = 'O';
  }
  else
  {
    I = 'O';
    U = 'X';
  }

  for(int i = 1; i < N; i++)
  {
    for(int j = 1; j < N; j++)//全局扫描寻找最佳的落子位置
    {
      if(board[i * N + j] == '.')
      {
        if((board[(i - 1) * N + j] == I )|| (board[(i + 1) * N + j] == I )||
          (board[i * N + (j + 1)] == I) || (board[i * N + (j - 1)] == I) )
        {
          mark[i * N + j] += 9;
        }//四周有己方1棋o

        if((board[(i - 1) * N + j] == U) || (board[(i + 1) * N + j] == U) ||
          (board[i * N + (j + 1)] == U) || (board[i * N + (j - 1)] == U))
        {
          mark[i * N + j] += 10;
        }//四周有对方1棋x

        if((board[(i - 1) * N + j] == I && board[(i - 2) * N + j] == I)
        || (board[i * N + (j - 1)] == I && board[i * N + (j - 2)] == I)
        || (board[i*N+(j+1)]==I && board[i*N+(j+2)]==I)
        || (board[(i + 1) * N+j]==I && board[(i+2)*N+j]==I)
        || (board[(i - 1)*N+(j+1)]==I && board[(i-2)*N+(j+2)]==I)
        || (board[(i+1)*N+(j+1)]==I && board[(i+2)*N+(j+2)]==I)
        || (board[(i-1)*N+(j-1)]==I && board[(i-2)*N+(j-2)]==I)
        || (board[(i+1)*N+(j-1)]==I && board[(i+2)*N+(j-2)]==I))
        {
          mark[i*N+j]+=70;
        }//八个方向己方连续2棋oo

        if((board[(i-1)*N+j]==U&& board[(i-2)*N+j]==U)
        || (board[i*N+(j-1)]==U && board[i*N+(j-2)]==U)
        || (board[i*N+(j+1)]==U && board[i*N+(j+2)]==U)
        || (board[(i+1)*N+j]==U && board[(i+2)*N+j]==U)
        || (board[i-1*N+j+1]==U && board[i-2*N+j+2]==U)
        || (board[i+1*N+j+1]==U && board[i+2*N+j+2]==U)
        || (board[i-1*N+j-1]==U && board[i-2*N+j-2]==U)
        || (board[i+1*N+j-1]==U && board[i+2*N+j-2]==U))
        {
          mark[i*N+j]+=50;
        }//八个方向对方连续2棋xx

        if((board[i-1*N+j]==I && board[i+1*N+j])
        || (board[i*N+j-1]==I && board[i*N+j+1]==I)
        || (board[i-1*N+j-1]==I && board[i+1*N+j+1]==I)
        || (board[i-1*N+j+1]==I && board[i+1*N+j-1]==I))
        {
          mark[i*N+j]+=75;
        }//四周己方#o#
        if((board[i-1*N+j]==U && board[i+1*N+j]==U)
        || (board[i*N+j-1]==U && board[i*N+j+1]==U)
        || (board[i-1*N+j-1]==U && board[i+1*N+j+1]==U)
        || (board[i-1*N+j+1]==U && board[i+1*N+j-1]==U))
        {
          mark[i*N+j]+=55;
        }//四周对方0x0

        if((board[(i-3)*N+j]==I&& board[(i-2)*N+j]==I&& board[(i-1)*N+j]==I)
        || (board[(i+1)*N+j]==I&& board[(i+2)*N+j]==I && board[(i+3)*N+j]==I)
        || (board[i*N+(j-3)]==I&& board[i*N+(j-2)]==I&& board[i*N+(j-1)]==I)
        || (board[i*N+(j+1)]==I&& board[i*N+(j+2)]==I&& board[i*N+(j+3)]==I)
        || (board[(i-3)*N+(j-3)]==I&& board[(i-2)*N+(j-2)]==I&& board[(i-1)*N+(j-1)]==I)
        || (board[(i+3)*N+(j+3)]==I&& board[(i+2)*N+(j+2)]==I&& board[(i+1)*N+(j+1)]==I)
        || (board[(i-3)*N+(j+3)]==I&& board[(i-2)*N+(j+2)]==I&& board[(i-1)*N+(j+1)]==I)
        || (board[(i+3)*N+(j-3)]==I&& board[(i+2)*N+(j-2)]==I&& board[(i+1)*N+(j-1)]==I))
        {
          mark[i*N+j]+= 100;
        }//己方###
        if((board[(i-3)*N+j]==U&& board[(i-2)*N+j]==U&& board[(i-1)*N+j]==U)
        || (board[(i+1)*N+j]==U&& board[(i+2)*N+j]==U&& board[(i+3)*N+j]==0)
        || (board[i*N+(j-3)]==U&& board[i*N+(j-2)]==U&& board[i*N+(j-1)]==U)
        || (board[i*N+(j+1)]==U&& board[i*N+(j+2)]==U&& board[i*N+(j+3)]==U)
        || (board[(i-3)*N+(j-3)]==U&& board[(i-2)*N+(j-2)]==U&& board[(i-1)*N+(j-1)]==U)
        || (board[(i+3)*N+(j+3)]==U&& board[(i+2)*N+(j+2)]==U&& board[(i+1)*N+(j+1)]==U)
        || (board[(i-3)*N+(j+3)]==U&& board[(i-2)*N+(j+2)]==U&& board[(i-1)*N+(j+1)]==U)
        || (board[(i+3)*N+(j-3)]==U&& board[(i+2)*N+(j-2)]==U&& board[(i+1)*N+(j-1)]==U))
        {
          mark[i*N+j]+= 200;
        }//对方000
        if((board[(i+1)*N+j]==I&& board[(i-2)*N+j]==I&& board[(i-1)*N+j]==I)
        || (board[(i+1)*N+j]==I&& board[(i+2)*N+j]==I&& board[(i-1)*N+j]==I)
        || (board[i*N+(j+1)]==I&& board[i*N+(j-2)]==U&& board[i*N+(j-1)]==I)
        || (board[i*N+(j+1)]==I&& board[i*N+(j+2)]==U&& board[i*N+(j-1)]==I)
        || (board[(i+1)*N+(j+1)]==I&& board[(i-2)*N+(j-2)]==I&& board[(i-1)*N+(j-1)]==I)
        || (board[(i-1)*N+(j-1)]==I&& board[(i+2)*N+(j+2)]==I&& board[(i+1)*N+(j+1)]==I)
        || (board[(i+1)*N+(j-1)]==I&& board[(i-2)*N+(j+2)]==I&& board[(i-1)*N+(j+1)]==I)
        || (board[(i-1)*N+(j+1)]==I&& board[(i+2)*N+(j-2)]==I&& board[(i+1)*N+(j-1)]==I))
        {
          mark[i*N+j]+= 300;
        }//己方## #
        if((board[(i+1)*N+j]==U&& board[(i-2)*N+j]==U&& board[(i-1)*N+j]==U)
        || (board[(i+1)*N+j]==U&& board[(i+2)*N+j]==U&& board[(i-1)*N+j]==U)
        || (board[i*N+(j+1)]==U&& board[i*N+(j-2)]==U&& board[i*N+(j-1)]==U)
        || (board[i*N+(j+1)]==U&& board[i*N+(j+2)]==U&& board[i*N+(j-1)]==U)
        || (board[(i+1)*N+(j+1)]==U&& board[(i-2)*N+(j-2)]==U&& board[(i-1)*N+(j-1)]==U)
        || (board[(i-1)*N+(j-1)]==U&& board[(i+2)*N+(j+2)]==U&& board[(i+1)*N+(j+1)]==U)
        || (board[(i+1)*N+(j-1)]==U&& board[(i-2)*N+(j+2)]==U&& board[(i-1)*N+(j+1)]==U)
        || (board[(i-1)*N+(j+1)]==U&& board[(i+2)*N+(j-2)]==U&& board[(i+1)*N+(j-1)]==U))
        {
          mark[i*N+j]+= 400;
        }//对方00 0
        if((board[(i-4)*N+j]==I&& board[(i-3)*N+j]==I&& board[(i-2)*N+j]==I&& board[(i-1)*N+j]==I)
        || (board[(i+1)*N+j]==I&& board[(i+2)*N+j]==I&& board[(i+3)*N+j]==I&& board[(i+4)*N+j]==I)
        || (board[i*N+(j-4)]==I&& board[i*N+(j-3)]==I&& board[i*N+(j-2)]==I&& board[i*N+(j-1)]==I)
        || (board[i*N+(j+1)]==I&& board[i*N+(j+2)]==I&& board[i*N+(j+3)]==I&& board[i*N+(j+4)]==I)
        || (board[(i-4)*N+(j-4)]==I&& board[(i-3)*N+(j-3)]==I&& board[(i-2)*N+(j-2)]==I&& board[(i-1)*N+(j-1)]==I)
        || (board[(i+4)*N+(j+4)]==I&& board[(i+3)*N+(j+3)]==I&& board[(i+2)*N+(j+2)]==I&& board[(i+1)*N+(j+1)]==I)
        || (board[(i-4)*N+(j+4)]==I&& board[(i-3)*N+(j+3)]==I&& board[(i-2)*N+(j+2)]==I&& board[(i-1)*N+(j+1)]==I)
        || (board[(i+4)*N+(j-4)]==I&& board[(i+3)*N+(j-3)]==I&& board[(i+2)*N+(j-2)]==I&& board[(i+1)*N+(j-1)]==I))
        {
          mark[i*N+j]+= 1000;
        }//己方####
        if((board[(i-4)*N+j]==U&& board[(i-3)*N+j]==U&& board[(i-2)*N+j]==U&& board[(i-1)*N+j]==U)
        || (board[(i+1)*N+j]==U&& board[(i+2)*N+j]==U&& board[(i+3)*N+j]==U&& board[(i+4)*N+j]==U)
        || (board[i*N+(j-4)]==U&& board[i*N+(j-3)]==U&& board[i*N+(j-2)]==U&& board[i*N+(j-1)]==U)
        || (board[i*N+(j+1)]==U&& board[i*N+(j+2)]==U&& board[i*N+(j+3)]==U&& board[i*N+(j+4)]==U)
        || (board[(i-4)*N+(j-4)]==U&& board[(i-3)*N+(j-3)]==U&& board[(i-2)*N+(j-2)]==U&& board[(i-1)*N+(j-1)]==U)
        || (board[(i+4)*N+(j+4)]==U&& board[(i+3)*N+(j+3)]==U&& board[(i+2)*N+(j+2)]==U&& board[(i+1)*N+(j+1)]==U)
        || (board[(i-4)*N+(j+4)]==U&& board[(i-3)*N+(j+3)]==U&& board[(i-2)*N+(j+2)]==U&& board[(i-1)*N+(j+1)]==U)
        || (board[(i+4)*N+(j-4)]==U&& board[(i+3)*N+(j-3)]==U&& board[(i+2)*N+(j-2)]==U&& board[(i+1)*N+(j-1)]==U))
        {
          mark[i*N+j]+= 900;
        }//对方0000

        if(mark[i * N + j] > maxmax)//记录当前最优情况
        {
          maxmax = mark[i * N + j];
          maxI= i;
          maxJ= j;
        }
      }
    }
  }
}
void Computer(char * board, int color)  //放棋子√
{
  ComputeValue(color, board);
  board[maxI * N + maxJ] = chess[color];
  lastI = maxI;//记录棋子坐标
  lastJ = maxJ;
}

bool Check(char *board)//用于判断是否连成五子√
{
  int num=0;
  int i, j;

  for(i = lastI - 1, j = lastJ; i > 0; i--)//以当前落子位置为起点向上搜索
  {
    if(board[i * N + j] == board[lastI * N + lastJ])
      num++;
    else
      break;
  }
  for(i = lastI + 1, j = lastJ; i < 20; i++)//下
  {
    if(board[i * N + j] == board[lastI * N + lastJ])
      num++;
    else
      break;
  }
  if(num >= 4)//上下位置4+1->结束
    return 1;
  num = 0;
  for(i = lastI, j = lastJ - 1; j > 0; j--)//左
  {
    if(board[i * N + j] == board[lastI * N + lastJ])
      num++;
    else break;
  }
  for(i = lastI, j = lastJ + 1; j < 20; j++)//右
  {
    if(board[i * N + j] == board[lastI * N + lastJ])
      num++;
    else break;
  }
  if(num >= 4)
    return 1;
  num = 0;
  for(i = lastI - 1, j = lastJ + 1; i > 0 && j < 20; i--, j++)//对角线
  {
    if(board[i * N + j] == board[lastI * N + lastJ])
      num++;
    else break;
  }
  for(i = lastI + 1, j = lastJ - 1; i < 20 && j > 0; i++, j--)
  {
     if(board[i * N + j] == board[lastI * N + lastJ])
      num++;
    else break;
  }
  if(num >= 4)
    return 1;
  num = 0;
  for(i = lastI - 1, j = lastJ - 1; i > 0 && j > 0; i--, j--)
  {
    if(board[i * N + j] == board[lastI * N + lastJ])
      num++;
    else break;
  }
  for(i = lastI + 1, j = lastJ + 1; i < 20 && j < 20; i++, j++)
  {
    if(board[i * N + j] == board[lastI * N + lastJ])
      num++;
    else break;
  }
  if(num >= 4)
    return 1;
  else
    return 0;
}
void Play(char * board)    //游戏函数
{
  while(1)
  {
    Player(board, 0);

    if (SystemError)
      return;
    system("cls");//清屏
    PrintChess(board);

    if(Check(board))
    {
      cout << cout << endl << endl <<"玩家获胜,游戏结束"<<endl;
      break;
    }

    Computer(board, 1);
    system("cls");
    PrintChess(board);

    if(Check(board))
    {
      cout << endl << endl << "电脑获胜,游戏结束" << endl;
      break;
    }
  }
}
int main()         //主函数
{
  char board[400];
  while(1)
  {
    InitChess(board);
    PrintChess(board);
    Play(board);
  }
  return 0;
}