鱼C论坛

 找回密码
 立即注册
查看: 3617|回复: 3

[原创] 五子棋-人机对战源码-(C语言+api完成)

[复制链接]
发表于 2017-8-22 20:00:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
//最近又修改了一下,目前电脑的“智力”比较低,因为觉得麻烦,评分值都是随便写的,大家可以改改评分机制,让电脑更“聪明”一些,还有就是可以加个随机数,让每次走棋都出其不意
#include <windows.h>
#include <winuser.h>
#define bool unsigned short//由于C语言没有bool类型  所以这里把它定义为unsigned short
#define true 1
#define false 0
#define CHESSBOARD_NUMBER 15//棋盘规格,注棋盘中黑点不随规格改变而改变
#define BLACK_CHESS_PIECES 1//定义黑色棋子 值为1
#define WHITE_CHESS_PIECES 2  //定义白色棋子  值为2
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int pr_chess_color;//待下棋子颜色
int z_DrawChessMap(HDC hdc,int extent,int cxClient,int cyClient);//绘制棋盘(设备环境句柄,棋盘规格extent*extent,客户区宽度,客户区高度)
int z_initialise_chessboard(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], int cxClient, int cyClient, bool is_initialise); // 初始化棋盘, 更新棋盘坐标, 需提供客户区大小, 如果is_initialise值为true, 则初始化棋盘颜色
int z_Draw_chesspieces(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], HDC hdc,HWND hwnd);//绘制棋子
int z_xiaqi(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], int x, int y, HWND hwnd);//下棋
int z_is_ok(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER]);//判断是否赢棋,黑子赢返回1,白棋赢返回2
int z_calc_score(struct st_value_tab value_tab_st[26], struct st_value_tab point_tab);//计算指定表分值,须传入评分表,点表
POINT computerAI(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], int  pr_chess_color);//电脑智能走棋算法,传入棋盘数组及要落子颜色,返回落子坐标
struct st_chess_pieces
{
        int extra;//预留
        int chess_color;//棋子颜色(RGB)
        POINT x_y;//棋子坐标(x,y)
};
struct st_value_tab
{
        char x1[7];
        int score;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
        static TCHAR szAppName[] = TEXT("MyWindows");//窗口类名
        HWND hwnd;//窗口句柄
        MSG msg;//消息
        WNDCLASS wndclass;//窗口类

        wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;//窗口风格
        wndclass.lpfnWndProc = WndProc;//消息处理函数
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = hInstance;//程序实例句柄
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//背景
        wndclass.lpszMenuName = NULL;//菜单句柄
        wndclass.lpszClassName = szAppName;//窗口类名

        if (!RegisterClass(&wndclass))//注册窗口类
        {
                MessageBox(NULL, TEXT("这个程序需要在 Windows NT 才能执行!"), szAppName, MB_ICONERROR);
                return 0;
        }

        hwnd = CreateWindow(szAppName,
                TEXT("人执白子,电脑执黑子     五子棋-AI算法"), //标题
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                600, //窗口大小
                600,
                NULL,
                NULL,
                hInstance,
                NULL);
       
        ShowWindow(hwnd, iCmdShow);//显示窗口
        UpdateWindow(hwnd);//更新窗口

        while (GetMessage(&msg, NULL, 0, 0))//消息循环
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }

        return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)//处理消息
{
        static HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;
        POINT cursor_point;
        int iGainer;//胜棋者
        static cx_Client;
        static cy_Client;
        static bool bChessBoard_invalidate;//表示棋盘是否能下棋,true不能下,false能下
        static struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER];//棋盘数组
        POINT ai_xiaqi;//ai下棋坐标

        switch (message)
        {
        case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
                GetClientRect(hwnd, &rect);
                z_DrawChessMap(hdc, CHESSBOARD_NUMBER, rect.right, rect.bottom);//绘制棋盘
                z_Draw_chesspieces(arr_chessboard, hdc,hwnd);//绘制棋子
                EndPaint(hwnd, &ps);
                return 0;
        case WM_SIZE:
                cx_Client = LOWORD(lParam);
                cy_Client = HIWORD(lParam);
                z_initialise_chessboard(arr_chessboard, cx_Client ,cy_Client, false);
                return 0;
        case WM_CREATE:
                pr_chess_color=WHITE_CHESS_PIECES;//初始化白棋
                return 0;
        case WM_LBUTTONUP://下棋
                if (bChessBoard_invalidate == true)//棋盘不能下棋,直接返回
                {
                        return 0;
                }
                GetCursorPos(&cursor_point);//获取鼠标在屏幕内坐标
                ScreenToClient(hwnd, &cursor_point);//将鼠标在屏幕内坐标转换为窗口客户区坐标
                z_xiaqi(arr_chessboard, cursor_point.x, cursor_point.y, hwnd);//将鼠标坐标传入下棋函数
                InvalidateRect(hwnd, NULL, true);//发送客户区失效,重绘客户区
                iGainer = z_is_ok(arr_chessboard);
                if (iGainer == 1)//黑子胜
                {
                        MessageBox(hwnd, TEXT("黑子胜!\n双击鼠标左键重新开盘!"), TEXT("提示:"), MB_OK);
                        bChessBoard_invalidate = true;
                        return 0;
                }else if(iGainer ==2 )//白子胜
                {
                        MessageBox(hwnd,TEXT("白子胜!\n双击鼠标左键重新开盘!"),TEXT("提示:"),MB_OK);
                        bChessBoard_invalidate = true;
                        return 0;
                }
                if (pr_chess_color != BLACK_CHESS_PIECES)//当前落子不是黑色,结束不继续向下
                {
                        return 0;
                }
                //以下代码为计算机走棋
                Sleep(1500);
                ai_xiaqi = computerAI(arr_chessboard, pr_chess_color);
                z_xiaqi(arr_chessboard, ai_xiaqi.x, ai_xiaqi.y, hwnd);//将鼠标坐标传入下棋函数
                InvalidateRect(hwnd, NULL, true);//发送客户区失效,重绘客户区
                iGainer = z_is_ok(arr_chessboard);
                if (iGainer == 1)//黑子胜
                {
                        MessageBox(hwnd, TEXT("黑子胜!\n双击鼠标左键重新开盘!"), TEXT("提示:"), MB_OK);
                        bChessBoard_invalidate = true;
                }else if(iGainer ==2 )//白子胜
                {
                        MessageBox(hwnd,TEXT("白子胜!\n双击鼠标左键重新开盘!"),TEXT("提示:"),MB_OK);
                        bChessBoard_invalidate = true;
                }

                return 0;
        case WM_LBUTTONDBLCLK://鼠标左键双击
                if (MessageBox(hwnd, TEXT("是否重新开局!"), TEXT("提示:"), MB_YESNO) == IDYES)
                {
                        z_initialise_chessboard(arr_chessboard, cx_Client, cy_Client, true);//初始化棋盘
                        InvalidateRect(hwnd, NULL, true);//发送客户区失效,重绘客户区
                        bChessBoard_invalidate = false;//
                        pr_chess_color = WHITE_CHESS_PIECES;
                }
                return 0;
        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
               
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}


int z_DrawChessMap(HDC hdc,int extent,int cxClient,int cyClient)//绘制棋盘(设备环境句柄,棋盘规格extent*extent,客户区宽度,客户区高度)
{
        int start_x, start_y,end_x,end_y,i;
        POINT rect_x_y[4];//棋盘矩形坐标
        rect_x_y[0].x = cxClient / (extent + 1) - 2;
        rect_x_y[0].y = cyClient / (extent + 1) - 2;
        rect_x_y[1].x = ((cxClient / (extent + 1))*extent) + 2;
        rect_x_y[1].y = cyClient / (extent + 1) - 2;
        rect_x_y[2].x = ((cxClient / (extent + 1))*extent) + 2;
        rect_x_y[2].y = ((cyClient / (extent + 1))*extent) + 2;
        rect_x_y[3].x = cxClient / (extent + 1) - 2;
        rect_x_y[3].y = ((cyClient / (extent + 1))*extent) + 2;
        Polygon(hdc, rect_x_y, 4);//绘制棋盘边框
        //画横线
        for (i = 0; i < extent; i++)
        {
                start_x = cxClient / (extent+1);
                start_y =i*(cyClient / (extent + 1)) + (cyClient / (extent + 1));
                end_x = (cxClient / (extent + 1))*extent;
                end_y= i*(cyClient / (extent + 1)) + (cyClient / (extent + 1));
                MoveToEx(hdc, start_x, start_y, NULL);
                LineTo(hdc, end_x, end_y);
        }
        //画竖线
        for (i = 0; i < extent; i++)
        {
                start_x = i*(cxClient / (extent + 1))+ (cxClient / (extent + 1));
                start_y = cyClient / (extent + 1);
                end_x = (cxClient / (extent + 1))*i+ (cxClient / (extent + 1));
                end_y =( cyClient / (extent + 1))*extent;
                MoveToEx(hdc, start_x, start_y, NULL);
                LineTo(hdc, end_x, end_y);
        }
       
        return 0;
}

int z_initialise_chessboard(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER],int cxClient,int cyClient,bool is_initialise)//初始化棋盘,更新棋盘坐标,需提供客户区大小,如果is_initialise值为true,则初始化棋盘颜色
{
        int i, j;
        int x,y;
        for (i = 0; i < CHESSBOARD_NUMBER; i++)
        {
                for (j = 0; j < CHESSBOARD_NUMBER; j++)
                {
                       
                        x = j*(cxClient / (CHESSBOARD_NUMBER+1)) + (cxClient / (CHESSBOARD_NUMBER+1));
                        y = i*(cyClient / (CHESSBOARD_NUMBER+1)) + (cyClient / (CHESSBOARD_NUMBER+1));
                        arr_chessboard[i][j].x_y.x = x;
                        arr_chessboard[i][j].x_y.y = y;
                        if (is_initialise == true)
                        {
                                arr_chessboard[i][j].chess_color = (int)NULL;
                                //以下为实验代码
                                //arr_chessboard[i][j].chess_color = WHITE_CHESS_PIECES;
                        }
                }
        }
        return 0;
}

int z_Draw_chesspieces(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], HDC hdc,HWND hwnd)//绘制棋子
{
        int i, j;
        RECT rect;
        int chess_pieces_width;//棋子宽度
        int chess_pieces_height;//棋子高度
        HBRUSH white_brush, black_brush, Old_brush;
        HPEN black_pen, white_pen, Old_pen;
        white_brush = CreateSolidBrush(RGB(255, 255,255));//创建白色画刷
        black_brush = CreateSolidBrush(RGB(64, 25, 43));//创建黑色画刷
        black_pen = CreatePen(PS_SOLID, 1, RGB(34, 14, 23));//创建黑色画笔
        white_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));//创建黑白色画笔
        GetClientRect(hwnd, &rect);//获取客户矩形
        chess_pieces_width = (int)(rect.right / (CHESSBOARD_NUMBER + 1))*(double)(1.2 / 3.0);//计算棋子宽度半径
        chess_pieces_height = (int)(rect.bottom / (CHESSBOARD_NUMBER + 1))*(double)(1.2 / 3.0);//计算棋子高度半径
         //绘制棋盘加粗点
        Old_brush = SelectObject(hdc, black_brush);
        Old_pen = SelectObject(hdc, white_pen);
        Ellipse(hdc, arr_chessboard[3][3].x_y.x -5, arr_chessboard[3][3].x_y.y - 5, \
                arr_chessboard[3][3].x_y.x + 5, arr_chessboard[3][3].x_y.y + 5);
        Ellipse(hdc, arr_chessboard[3][11].x_y.x - 5, arr_chessboard[3][11].x_y.y - 5, \
                arr_chessboard[3][11].x_y.x + 5, arr_chessboard[3][11].x_y.y + 5);
        Ellipse(hdc, arr_chessboard[11][3].x_y.x - 5, arr_chessboard[11][3].x_y.y - 5, \
                arr_chessboard[11][3].x_y.x + 5, arr_chessboard[11][3].x_y.y + 5);
        Ellipse(hdc, arr_chessboard[11][11].x_y.x -5, arr_chessboard[11][11].x_y.y - 5, \
                arr_chessboard[11][11].x_y.x + 5, arr_chessboard[11][11].x_y.y + 5);
        Ellipse(hdc, arr_chessboard[7][7].x_y.x - 5, arr_chessboard[7][7].x_y.y - 5, \
                arr_chessboard[7][7].x_y.x + 5, arr_chessboard[7][7].x_y.y + 5);
        ////绘制待下棋子
        if (pr_chess_color == WHITE_CHESS_PIECES)//绘制白棋
        {
                Old_brush = SelectObject(hdc, white_brush);
                Old_pen = SelectObject(hdc, black_pen);
                Ellipse(hdc, arr_chessboard[0][0].x_y.x, \
                        arr_chessboard[0][0].x_y.y - (chess_pieces_height * 2), \
                        arr_chessboard[0][0].x_y.x + (chess_pieces_width * 2)-3, \
                        arr_chessboard[0][0].x_y.y -3);
                SelectObject(hdc, Old_brush);
                SelectObject(hdc, Old_pen);
        }
        else//绘制黑棋
        {
                Old_brush = SelectObject(hdc, black_brush);
                Old_pen = SelectObject(hdc, white_pen);
                Ellipse(hdc, arr_chessboard[0][0].x_y.x, \
                        arr_chessboard[0][0].x_y.y - (chess_pieces_height*2), \
                        arr_chessboard[0][0].x_y.x + (chess_pieces_width*2)-3, \
                        arr_chessboard[0][0].x_y.y -3);
                SelectObject(hdc, Old_brush);
                SelectObject(hdc, Old_pen);
        }
        //绘制待下棋子end
        SelectObject(hdc, Old_brush);
        SelectObject(hdc, Old_pen);

        for (i = 0; i < CHESSBOARD_NUMBER; i++)
        {
                for (j = 0; j < CHESSBOARD_NUMBER; j++)
                {
                        if (arr_chessboard[i][j].chess_color == WHITE_CHESS_PIECES)//绘制白棋
                        {
                                //MessageBox(0, TEXT("hellow"), TEXT("Hi"), MB_OK);
                                Old_brush = SelectObject(hdc, white_brush);
                                Old_pen = SelectObject(hdc, black_pen);
                                Ellipse(hdc, arr_chessboard[i][j].x_y.x - chess_pieces_width, \
                                        arr_chessboard[i][j].x_y.y - chess_pieces_height, \
                                        arr_chessboard[i][j].x_y.x + chess_pieces_width, \
                                        arr_chessboard[i][j].x_y.y + chess_pieces_height);
                                SelectObject(hdc, Old_brush);
                                SelectObject(hdc, Old_pen);
                        }
                        else if (arr_chessboard[i][j].chess_color == BLACK_CHESS_PIECES)//绘制黑棋
                        {
                               
                                Old_brush = SelectObject(hdc, black_brush);
                                Old_pen = SelectObject(hdc, white_pen);
                                Ellipse(hdc, arr_chessboard[i][j].x_y.x - chess_pieces_width, \
                                        arr_chessboard[i][j].x_y.y - chess_pieces_height, \
                                        arr_chessboard[i][j].x_y.x + chess_pieces_width, \
                                        arr_chessboard[i][j].x_y.y + chess_pieces_height);
                                SelectObject(hdc, Old_brush);
                                SelectObject(hdc, Old_pen);
                        }

                }
               
        }
       
        DeleteObject(white_pen);
        DeleteObject(white_brush);
        DeleteObject(black_pen);
        DeleteObject(black_brush);
        return 0;
}

int z_xiaqi(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], int x, int y,HWND hwnd)//下棋
{
        int i, j;
        RECT rect;
        int chess_pieces_width;//棋子宽度
        int chess_pieces_height;//棋子高度
        GetClientRect(hwnd, &rect);//获取客户矩形
        chess_pieces_width = (int)(rect.right / (CHESSBOARD_NUMBER + 1))*(double)(1 / 3.0);//计算棋子宽度
        chess_pieces_height = (int)(rect.bottom / (CHESSBOARD_NUMBER + 1))*(double)(1 / 3.0);//计算棋子高度
        for (i = 0; i < CHESSBOARD_NUMBER; i++)
        {
                for (j = 0; j < CHESSBOARD_NUMBER; j++)
                {
                        if ((arr_chessboard[i][j].x_y.x - chess_pieces_width<x) &\
                                (arr_chessboard[i][j].x_y.y - chess_pieces_height<y) &\
                                (arr_chessboard[i][j].x_y.x + chess_pieces_width>x) &\
                                (arr_chessboard[i][j].x_y.y + chess_pieces_height>y) & \
                                ((arr_chessboard[i][j].chess_color!= WHITE_CHESS_PIECES) \
                                        & (arr_chessboard[i][j].chess_color != BLACK_CHESS_PIECES)))
                        {
                               
                               
                                        arr_chessboard[i][j].chess_color = pr_chess_color;
                                        if (pr_chess_color == WHITE_CHESS_PIECES)
                                        {
                                                pr_chess_color = BLACK_CHESS_PIECES;
                                        }
                                        else if (pr_chess_color == BLACK_CHESS_PIECES)
                                        {
                                                pr_chess_color = WHITE_CHESS_PIECES;
                                        }
                               

                        }
                       
                }
        }
        return 0;
}

int z_is_ok(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER])//判断是否赢棋,黑子赢返回1,白棋赢返回2
{
        int x, y=0, old_x,old_y=0;//
        int black_pieces_count=0;//黑子连子数量
        int white_pieces_count=0;//白子连子数量
        for (x = 0; x <= CHESSBOARD_NUMBER; x++)//左上到右下扫描
        {
                if (x == CHESSBOARD_NUMBER)
                {
                        x = CHESSBOARD_NUMBER - 1;
                }
                old_x = x;//保存x值,因为while循环中需要改变x值
                //初始化棋子连子数量为0
                white_pieces_count = 0;
                black_pieces_count = 0;
                while (1)
                {
                        if (arr_chessboard[x][y].chess_color == WHITE_CHESS_PIECES)//白子连子
                        {
                                white_pieces_count++;
                                black_pieces_count = 0;
                        }
                        if (arr_chessboard[x][y].chess_color == BLACK_CHESS_PIECES)//黑子连子
                        {
                                black_pieces_count++;
                                white_pieces_count = 0;
                        }
                        else if ((arr_chessboard[x][y].chess_color != WHITE_CHESS_PIECES) & (arr_chessboard[x][y].chess_color != BLACK_CHESS_PIECES))
                         { black_pieces_count = 0; white_pieces_count = 0; }//既不是白子连子也不是黑子连子

                        if (black_pieces_count == 5)//黑子胜,返回1
                        {
                                return 1;
                        }

                        if(white_pieces_count == 5)//白子胜,返回2
                        {
                                return 2;
                        }
                        if ((y == (CHESSBOARD_NUMBER - 1)) & (x == (CHESSBOARD_NUMBER - 1)))//判断已寻找到最右下角坐标,结束循环
                        {
                                goto one;
                        }

                        if((++y>(CHESSBOARD_NUMBER-1)) | (--x<0))//x轴或y轴超出范围,结束当前扫描
                        {
                                break;
                        }
                       
                }
                x = old_x;//还原x进while循环前的值
                if (x == CHESSBOARD_NUMBER-1)
                {
                        old_y++;
                        y = old_y;
                }
                else
                {
                        y = 0;
                }
        }
        one:old_x = 0;
        y = CHESSBOARD_NUMBER-1;
        x = 0;
        while (1)//左下到右上扫描
        {
                if (y == 0)
                {
                        y = 0;
                }
                white_pieces_count = 0;
                black_pieces_count = 0;
                old_y = y;
                while (1)
                {
                        if (arr_chessboard[x][y].chess_color == WHITE_CHESS_PIECES)//白子连子
                        {
                                white_pieces_count++;
                                black_pieces_count = 0;
                        }
                        if (arr_chessboard[x][y].chess_color == BLACK_CHESS_PIECES)//黑子连子
                        {
                                black_pieces_count++;
                                white_pieces_count = 0;
                        }
                        else if ((arr_chessboard[x][y].chess_color != WHITE_CHESS_PIECES) & (arr_chessboard[x][y].chess_color != BLACK_CHESS_PIECES))
                        {
                                black_pieces_count = 0; white_pieces_count = 0;
                        }//既不是白子连子也不是黑子连子

                        if (black_pieces_count == 5)//黑子胜,返回1
                        {
                                return 1;
                        }

                        if (white_pieces_count == 5)//白子胜,返回2
                        {
                                return 2;
                        }
                        if ((y == 0) & (x == (CHESSBOARD_NUMBER - 1)))//判断已寻找到最右上角坐标,结束循环
                        {
                                goto two;
                        }

                        if ((++y > (CHESSBOARD_NUMBER - 1)) | (++x >(CHESSBOARD_NUMBER - 1)))//x轴或y轴超出范围,结束当前扫描
                        {
                                break;
                        }

                }
                if (old_y == 0)
                {
                        old_x++;
                        x = old_x;
                        y = 0;
                }
                else
                {
                        x = 0;
                        y = --old_y;
                }
               
        }
two:       
        for (y = 0; y <= (CHESSBOARD_NUMBER - 1); y++)//横向扫描
        {
                white_pieces_count = 0;
                black_pieces_count = 0;
                for(x=0;x<=(CHESSBOARD_NUMBER-1);x++)
                {
                        if (arr_chessboard[x][y].chess_color == WHITE_CHESS_PIECES)//白子连子
                        {
                                white_pieces_count++;
                                black_pieces_count = 0;
                        }
                        if (arr_chessboard[x][y].chess_color == BLACK_CHESS_PIECES)//黑子连子
                        {
                                black_pieces_count++;
                                white_pieces_count = 0;
                        }
                        else if ((arr_chessboard[x][y].chess_color != WHITE_CHESS_PIECES) & (arr_chessboard[x][y].chess_color != BLACK_CHESS_PIECES))
                        {
                                black_pieces_count = 0; white_pieces_count = 0;
                        }//既不是白子连子也不是黑子连子

                        if (black_pieces_count == 5)//黑子胜,返回1
                        {
                                return 1;
                        }

                        if (white_pieces_count == 5)//白子胜,返回2
                        {
                                return 2;
                        }
                }
        }
        for (x = 0; x <= (CHESSBOARD_NUMBER - 1); x++)//竖向扫描
        {
                white_pieces_count = 0;
                black_pieces_count = 0;
                for (y = 0; y <= (CHESSBOARD_NUMBER - 1); y++)
                {
                        if (arr_chessboard[x][y].chess_color == WHITE_CHESS_PIECES)//白子连子
                        {
                                white_pieces_count++;
                                black_pieces_count = 0;
                        }
                        if (arr_chessboard[x][y].chess_color == BLACK_CHESS_PIECES)//黑子连子
                        {
                                black_pieces_count++;
                                white_pieces_count = 0;
                        }
                        else if ((arr_chessboard[x][y].chess_color != WHITE_CHESS_PIECES) & (arr_chessboard[x][y].chess_color != BLACK_CHESS_PIECES))
                        {
                                black_pieces_count = 0; white_pieces_count = 0;
                        }//既不是白子连子也不是黑子连子

                        if (black_pieces_count == 5)//黑子胜,返回1
                        {
                                return 1;
                        }

                        if (white_pieces_count == 5)//白子胜,返回2
                        {
                                return 2;
                        }
                }
        }
        return 0;
}
/*
评分值表  +:空位,用0表示     O:已方,即电脑落子棋子颜色,用1表示     *:对方,用2表示
1、OOOOO+->500000    2、OOOOO*->50000    3、OOOOOO->50000    4、+OOOOO->50000    5、*OOOOO->50000
6、++OOOO->3500    7、OOOO++->3500    8、+OOOO+->8000    9、*OOOO+->4000    10、+OOOO*->4000
11、+OOO++->720     12、++OOO+->720     13、+OO+O+->720     14、+O+OO+->720   15、*OOO++->1000
16、+OOO*+->120     17、+OOO+*->120     18、*OOO+*->20      19、*OOOO*->20    20、*000**->20
21、*OOO*+->20      22、*+OOO+->120     23、+*OOO+-120      24、**OOO+->20    25、**OOO*->10
26、++OOO*->120     27、+OO+OO->720     28、OOO+OO->720     29、OO+OO+->720   30、OO+OO*->720
31、OO+OOO->720     32、+O+OOO->720     33、*O+OOO->720     34、OO+OOO->720   35、+O+OOO->720
36、OOO+O->720      37、++OO++->120     38、+***O+->30000   39、+O***+->30000 40、O****O->3500
41、+**O*+->30000   42、+*O**+->30000   43、+***O*->35000   44、*O***+->35000 45、+**O**->35000
46、**O**+->35000   47、***O**->35000   48、**O***->35000   49、*O****->35000 50、****O*->35000
50、O****O->35000

*/
#if(1)

POINT computerAI(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], int  pr_chess_color)//电脑智能走棋算法,传入棋盘数组及要落子颜色,返回落子坐标
{
        int max_value = 0;//最大分值
        POINT max_point;//最大点坐标
        int value = 0;//单个点总分值
        int x, y;
        int i, j, k, n;
        int oldcolor;
        struct st_value_tab initialise = { "000000",0 };
        struct st_value_tab point_tab;//点表
        struct st_value_tab value_tab_st[50] = { {"OOOOO+",500000},{"OOOOO*",50000},{"OOOOOO",50000},{"+OOOOO",50000},{"*OOOOO",50000},
        {"++OOOO",3500},{"OOOO++",3500},{"+OOOO+",8000},{"*OOOO+",4000},{"+OOOO*",4000},
        {"+OOO++",720},{"++OOO+",720},{"+OO+O+",720},{"+O+OO+",720},{"*OOO++",1000},
        {"+OOO*+",120},{"+OOO+*",120},{"*OOO+*",20},{"*OOOO*",20},{"*000**",20},
        {"*OOO*+",20},{"*+OOO+",120},{"+*OOO+",120},{"**OOO+",20},{"**OOO*",10},
        {"++OOO*",120},{"+OO+OO",720 }, { "OOO+OO",720 }, { "OO+OO+", 720 }, { "OO+OO*",720 },
        { "OO+OOO",720 }, { "+O+OOO",720 }, { "*O+OOO",720 },{"OO+OOO",720}, { "+O+OOO",720 },
        { "OOO+O",720 }, { "++OO++",120 },{"+***O+",30000},{"+O***+",30000},{"O****O",35000},
        {"+**O*+",30000},{"+*O**+",30000 },{"+***O*",35000},{"*O***+",35000},{"+**O**",35000},
        {"**O**+",35000},{"***O**",35000},{"**O***",35000},{"*O****",35000},{"****O*",35000},
               
        };//评分表
       
        for (y = 0; y < CHESSBOARD_NUMBER; y++)
        {
                for (x = 0; x < CHESSBOARD_NUMBER; x++)
                {
                        //横向
                        value = 0;
                        if(arr_chessboard[x][y].chess_color > 0)//当前棋位有棋,忽略该棋位
                        {
                                continue;
                        }//有棋子位不能下棋
                        oldcolor = arr_chessboard[x][y].chess_color;//
                        arr_chessboard[x][y].chess_color = pr_chess_color;
                        for (k = 5; k >= 0; k--)//首层循环,从-5位置找棋位
                        {
                                point_tab = initialise;//初始化点表
                                n = 0;
                                for (i = x-k; i <= x-k+5; i++)//第二层循环找棋位
                                {
                                        if (i < 0 || i > CHESSBOARD_NUMBER)//当前棋位超出棋盘范围,跳过
                                        {
                                                break;
                                        }
                                        if (arr_chessboard[i][y].chess_color == pr_chess_color)//棋位等于当前落子颜色,用‘O’表示
                                        {
                                                point_tab.x1[n++] = 'O';
                                        }
                                        else if(arr_chessboard[i][y].chess_color > 0)//棋位等于对方棋子颜色,用‘*’表示
                                        {
                                                point_tab.x1[n++] = '*';
                                        }
                                        else { point_tab.x1[n++] = '+'; }//棋位等于无子,用‘+’表示

                                        if (point_tab.x1[5] != '0' )//棋位表填充完毕
                                        {
                                                value = value + z_calc_score(value_tab_st,point_tab);
                                        }
                                       
                                }
                        }
                       
                        //竖向
                        for (k = 5; k >= 0; k--)//首层循环,从-5位置找棋位
                        {
                                point_tab = initialise;//初始化点表
                                n = 0;
                                for (i = y-k; i <= y-k+5; i++)//第二层循环找棋位
                                {
                                        if (i < 0 || i > CHESSBOARD_NUMBER)//当前棋位超出棋盘范围,跳过
                                        {
                                                break;
                                        }
                                        if (arr_chessboard[x][i].chess_color == pr_chess_color)//棋位等于当前落子颜色,用‘O’表示
                                        {
                                                point_tab.x1[n++] = 'O';
                                        }
                                        else if(arr_chessboard[x][i].chess_color > 0)//棋位等于对方棋子颜色,用‘*’表示
                                        {
                                                point_tab.x1[n++] = '*';
                                        }
                                        else { point_tab.x1[n++] = '+'; }//棋位等于无子,用‘+’表示

                                        if (point_tab.x1[5] != '0')//棋位表填充完毕
                                        {
                                                value = value +  z_calc_score(value_tab_st,point_tab);
                                        }
                                }
                        }

                        //左上到右下判断↘
                        for (k = 5; k >= 0; k--)//首层循环,从-5位置找棋位
                        {
                                point_tab = initialise;//初始化点表
                                n = 0;
                                for (i = x-k,j=y-k; i <= x-k+5 && j<=y-k+5; i++,j++)//第二层循环找棋位
                                {
                                        if (i < 0 || j < 0 || i > CHESSBOARD_NUMBER || y > CHESSBOARD_NUMBER)//当前棋位超出棋盘范围,跳过
                                        {
                                                break;
                                        }
                                        if (arr_chessboard[i][j].chess_color == pr_chess_color)//棋位等于当前落子颜色,用‘O’表示
                                        {
                                                point_tab.x1[n++] = 'O';
                                        }
                                        else if(arr_chessboard[i][j].chess_color > 0)//棋位等于对方棋子颜色,用‘*’表示
                                        {
                                                point_tab.x1[n++] = '*';
                                        }
                                        else { point_tab.x1[n++] = '+'; }//棋位等于无子,用‘+’表示

                                        if (point_tab.x1[5] != '0')//棋位表填充完毕
                                        {
                                                value = value +  z_calc_score(value_tab_st,point_tab);
                                        }
                                }
                        }
                       
                        //右上到左下判断↙
                        for (k = 5; k >= 0; k--)//首层循环,从-5位置找棋位
                        {
                                point_tab = initialise;//初始化点表
                                n = 0;
                                for (i = x+k,j=y-k; i >= x+k-5 && j<=y-k+5; i--,j++)//第二层循环找棋位
                                {
                                        if (i < 0 || j < 0 || i > CHESSBOARD_NUMBER || y > CHESSBOARD_NUMBER)//当前棋位超出棋盘范围,跳过
                                        {
                                                break;
                                        }
                                        if (arr_chessboard[i][j].chess_color == pr_chess_color)//棋位等于当前落子颜色,用‘O’表示
                                        {
                                                point_tab.x1[n++] = 'O';
                                        }
                                        else if(arr_chessboard[i][j].chess_color > 0)//棋位等于对方棋子颜色,用‘*’表示
                                        {
                                                point_tab.x1[n++] = '*';
                                        }
                                        else { point_tab.x1[n++] = '+'; }//棋位等于无子,用‘+’表示

                                        if (point_tab.x1[5] != '0')//棋位表填充完毕
                                        {
                                                value = value +  z_calc_score(value_tab_st,point_tab);
                                        }
                                }
                        }

                        if (value > max_value)
                        {
                                max_value = value;
                                max_point.x = arr_chessboard[x][y].x_y.x ;
                                max_point.y = arr_chessboard[x][y].x_y.y;
                        }
                        arr_chessboard[x][y].chess_color = oldcolor;
                }
        }
       
        return max_point;
}
int z_calc_score(struct st_value_tab value_tab_st[50] , struct st_value_tab point_tab)//计算指定表分值,须传入评分表,点表
{
        int ret_value;
        int i;
        for (i = 0; i < 50; i++)
        {
                if (strstr(&point_tab.x1, &value_tab_st[i].x1) != NULL)
                {
                        ret_value = value_tab_st[i].score;
                        return ret_value;
                }
        }
        ret_value = 0;
        return ret_value;
}
#endif
114813vbojv0waavvzaj0q.gif

五子棋-人机对战源码.zip

5.71 KB, 下载次数: 54

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-8-27 23:07:25 | 显示全部楼层
支持一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-31 09:13:46 | 显示全部楼层
谢谢分享,支持下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-17 00:00:57 | 显示全部楼层
这个真心不错!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-5 11:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表