[人工智能]五子棋

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Pecony/article/details/83041370
#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;
}






猜你喜欢

转载自blog.csdn.net/Pecony/article/details/83041370
今日推荐