三子棋、五子棋自定义棋盘的C代码实现

分析:

整体思路如下:


这里写图片描述


头文件

#define __GAME_H__

#define ROW 9//棋盘行数
#define COL 9//棋盘列数
#define NUM 5//五子棋

void InitBoard(char board[ROW][COL],int row,int col);
void PrintBoard(char board[ROW][COL],int row,int col);
void Player(char board[ROW][COL],int row,int col);
void Computer(char board[ROW][COL],int row,int col,int num);
char Judge(char board[ROW][COL],int row,int col,int num);

#endif

上述代码中,ROW、COL用来修改棋盘的大小,NUM用来修改要玩的是三子棋还是五子棋还是其它,InitBoard函数用来对棋盘初始化,PrintBoard函数用来打印棋盘,Player函数用来实现玩家选择坐标,Computer函数用来实现电脑选择坐标,Judge函数用来判断输赢情况。


测试程序

void test()
{
    int n = 0;
    srand((unsigned)time(NULL));
    do
    {
        memu();
        printf("请选择:\n");
        scanf("%d",&n);
        if(n==1)
        {
            game();
        }
        else if(n==0)
        {
            printf("退出游戏\n");
            break;
        }
        else 
        {
            printf("输入错误,请重输:\n");
        }
    }while(n);
}
 int main()
 {
     test();
     return 0;
 }

游戏菜单

void memu()
{
    printf("********************\n");
    printf("****   1.play   ****\n");
    printf("****   0.exit   ****\n");
    printf("********************\n");
}

游戏执行程序

void game()
{
    char c = 0;
    char board[ROW][COL];
    InitBoard(board,ROW,COL);
    PrintBoard(board,ROW,COL);

    while(1)
    {
        printf("玩家走:>\n");
        Player(board,ROW,COL);
        PrintBoard(board,ROW,COL);
        c = Judge(board,ROW,COL,NUM);
        if(c!='+')
        {
            break;
        }

        printf("电脑走:>\n");
        Computer(board,ROW,COL,NUM);
        PrintBoard(board,ROW,COL);
        c = Judge(board,ROW,COL,NUM);
        if(c!='+')
        {
            break;
        }
    }
    PrintBoard(board,ROW,COL);
    if(c=='@')
    {
        printf("玩家赢\n");
    }
    else if(c=='O')
    {
        printf("电脑赢\n");
    }
    else if(c=='I')
    {
        printf("平局\n");
    }   
}

棋盘初始化

void InitBoard(char board[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            board[i][j]='+';
        }
    }
}

打印棋盘

void PrintBoard(char board[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            printf(" |");
        }
        printf("\n");
        for(j=0; j<row; j++)
        {
            printf("-%c",board[i][j]);
        }
        printf("-\n");
    }
    for(j=0; j<col; j++)
    {
        printf(" |");
    }
    printf("\n");
}

玩家坐标选择

int now_row = 0;//记录当前位置行值
int now_col = 0;//记录当前位置列值
void Player(char board[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    while(1)
    {
        scanf("%d %d",&i,&j);
        now_row = i-1;
        now_col = j-1;
        if(now_row<row && now_col<col)
        {
            if(board[now_row][now_col]=='+')
            {
                board[now_row][now_col]='@';
                break;
            }
            else
            {
                printf("坐标无效,请重新输入:\n");
            }
        }
        else
        {
            printf("坐标无效,请重新输入:\n");
        }
    }
}

电脑坐标

void Computer(char board[ROW][COL],int row,int col,int num)
{
    int i = 0;
    int j = 0;
    int count = 0;
    char c = board[now_row][now_col];
    int a = 0;
    int b = 0;
    int ret = num-2;
    while(1)
    {
        //当前位置行的右判断
        if((now_col<col-ret)&&(now_col >=1))
        {
            for(a= now_row,b= now_col; b<now_col+ret; b++)
            {
                if(board[a][b] != c)
                {
                    break;
                }
            }
            if(b == now_col+ret)
            {
                if(board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if(board[a][b-ret-1] == '+')
                {
                    board[a][b-ret-1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置行的左判断
        if((now_col >= ret) && (now_col < col-1))
        {
            for(a = now_row, b = now_col; b > now_col-ret; b--)
            {
                if(board[a][b] != c)
                {
                    break;
                }
            }
            if(b == now_col-ret)
            {
                if(board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if(board[a][b+ret+1] == '+')
                {
                    board[a][b+ret+1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置列的上判断
        if ((now_row >= ret) && (now_row < col - 1))
        {
            for (a = now_row, b = now_col; a > now_row-ret; a--)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if (a == now_row-ret)
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a+ret+1][b] == '+')
                {
                    board[a+ret+1][b] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置列的下判断
        if ((now_row<col - ret) && (now_row >= 1))
        {
            for (a = now_row, b = now_col; a < now_col+ret; a++)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if (a == now_row + ret)
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a-ret-1][b] == '+')
                {
                    board[a-ret-1][b] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置右下对角线的判断
        if ((now_row < row-ret) && (now_col < col-ret) && (now_row >= 1) && (now_col >= 1))
        {
            for (a = now_row, b = now_col; a<now_row+ret && b<now_col+ret; a++, b++)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if ((a == now_row+ret) && (b == now_col+ret))
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = '0';
                    goto exit;
                }
                else if (board[a-ret-1][b-ret-1] == '+')
                {
                    board[a-ret-1][b-ret-1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置左下对角线的判断
        if ((now_row < row-ret) && (now_col >= ret) && (now_row >= 1) && (now_col < col-1))
        {
            for (a = now_row, b = now_col; a<now_row+ret && b>now_col-ret; a++, b--)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if ((a == now_row+ret) && (b == now_col-ret))
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a-ret-1][b+ret+1] == '+')
                {
                    board[a-ret-1][b+ret+1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置右上对角线的判断
        if ((now_row >= ret) && (now_col < row-ret) && (now_row < row-1) && (now_col >= 1))
        {
            for (a = now_row, b = now_col; a > now_row-ret && b < now_col+ret; a--, b++)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if ((a == now_row-ret) && (b == now_col+ret))
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a+ret+1][b-ret-1] == '+')
                {
                    board[a+ret+1][b-ret-1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置左上对角线的判断
        if ((now_row >= ret) && (now_col >= ret) && (now_row < row-1) && (now_col < col-1))
        {
            for (a = now_row, b = now_col; a > now_row-ret && b > now_col-ret; a--, b--)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if ((a == now_row-ret) && (b == now_col-ret))
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a+ret+1][b+ret+1] == '+')
                {
                    board[a+ret+1][b+ret+1] = 'O';
                    goto exit;
                }
            }
        }

            i = rand() % row;
            j = rand() % row;
            if (board[i][j] == '+')
            {
                board[i][j] = 'O';
                goto exit;
                //break;
            }
    }
    exit:;
}

在此函数中,对电脑所走位置的选择稍微进行了优化,拿一个9行9列棋盘的五子棋来举例,它在内存中的存储如下图所示:
这里写图片描述
通过记录玩家所走的当前位置,在此函数中用当前位置来确定电脑要走的位置。
1、首先要对当前位置的右侧进行判断,若当前位置的右侧两位和当前位置的字符相同,应将三个位置的左侧或右侧堵上。(当前位置应在合理范围内)如下图所示:当前位置在15处,判断15右侧的16和17是否与15相等,若相等,若14处没有放子,放置14处,若18没有放子,放置18处。
这里写图片描述
2、用同上方法对当前位置的左侧进行判断。
3、其次判断当前位置的上方。(当前位置应在合理范围内)如下图所示:当前位置在32处,判断32上方的12和22是否与32相等,若相等,若02处没有放子,放置02处,若42处没有放子,放置42处。
这里写图片描述
4、用同上方法对当前位置的下方进行判断。
5、最后分别对当前位置的对角线右下、左下、右上、左上方进行判断。(当前位置应在合理范围内)如下图所示:当前位置在55处,判断55右下方对角线的66和77是否与55相等,若相等,若88处没有放子,放置88处,若44处没有放子,放置44处。
这里写图片描述


判断输赢结果

char Judge(char board[ROW][COL],int row,int col,int num)
{
    int i = 0;
    int j = 0;
    char ret = 0;
    char c = 0;
    int a = 0;
    int b = 0;
    int n = num-1;
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            if(board[i][j]!='+')
            {
                c = board[i][j];
                //判断行
                if(j<col-n)
                {
                        for(a=i,b=j; b<=j+n; b++)
                        {
                            if(board[a][b]!=c)
                            {
                                break;
                            }
                        }
                        if((b>j+n))
                        {
                            return c;
                        }
                }
                //判断列
                if(i<row-n)
                {
                        for(a=i,b=j; a<=i+n; a++)
                        {
                            if(board[a][b]!=c)
                            {
                                break;
                            }
                        }
                        if((a>i+n))
                        {
                            return c;
                        }
                }
                //判断对角线
                //判断右下对角线
                if((i<row-n)&&(j<col-n))
                {
                    for(a=i,b=j; (a<=i+n) && (b<=j+n);a++,b++)
                    {
                        if(board[a][b]!=c)
                        {
                            break;
                        }
                        if((a>i+n)&&(b>j+n))
                        {
                            return c;
                        }
                    }
                }
                //判断左下对角线
                if((i<row-n)&&(j>=n))
                {
                    for(a=i,b=j; (a<=i+n) && (b>=j-n); a++,b--)
                    {
                        if(board[a][b]!=c)
                        {
                            break;
                        }
                    }
                    if((a>i+n)&&(b<j-n))
                    {
                        return c;
                    }
                }
                //判断右上对角线
                if((i>=n)&&(j<col-n))
                {
                    for(a=i,b=j; (a>=i-n) && (b<=j+n); a--,b++)
                    {
                        if(board[a][b]!=c)
                        {
                            break;
                        }
                    }
                    if((a<i-n)&&(b>j+n))
                    {
                        return c;
                    }
                }
                //判断左上对角线
                if((i>=n)&&(j>=n))
                {
                    for(a=i,b=j; (a>=i-n) && (b>=j-n); a--,b--)
                    {
                        if(board[a][b]!=c)
                        {
                            break;
                        }
                    }
                    if((a<i-n)&&(b<j-n))
                    {
                        return c;
                    }
                }
            }
        }
    }
    //判断是否平局
    ret = Isfull(board,ROW,COL);
    if(ret=='I')
    {
        return 'I';
    }
    return '+';
}

char Isfull(char board[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            if(board[i][j]=='+')
            {
                return '+';
            }
        }
    }
    if(i==row && j==col)
    {
        return 'I';
    }
}

在此函数中,如果这个位置不与初始值相等,则判断它的行、列、对角线来确定是否达到五子连珠要求,如果达到,返回当前位置的字符,判断输赢,如果都不满足,则应通过棋盘是否满子来确定是否平局。


整体代码

game.h

#ifndef __GAME_H__
#define __GAME_H__

#define ROW 9
#define COL 9
#define NUM 5

void InitBoard(char board[ROW][COL],int row,int col);
void PrintBoard(char board[ROW][COL],int row,int col);
void Player(char board[ROW][COL],int row,int col);
void Computer(char board[ROW][COL],int row,int col,int num);
char Judge(char board[ROW][COL],int row,int col,int num);

#endif

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include "sanziqi.h"
#include <time.h>
#include <stdlib.h>

void game()
{
    char c = 0;
    char board[ROW][COL];
    InitBoard(board,ROW,COL);
    PrintBoard(board,ROW,COL);

    while(1)
    {
        printf("玩家走:>\n");
        Player(board,ROW,COL);
        PrintBoard(board,ROW,COL);
        c = Judge(board,ROW,COL,NUM);
        if(c!='+')
        {
            break;
        }
        printf("电脑走:>\n");
        Computer(board,ROW,COL,NUM);
        PrintBoard(board,ROW,COL);
        c = Judge(board,ROW,COL,NUM);
        if(c!='+')
        {
            break;
        }
    }
    PrintBoard(board,ROW,COL);
    if(c=='@')
    {
        printf("玩家赢\n");
    }
    else if(c=='O')
    {
        printf("电脑赢\n");
    }
    else if(c=='I')
    {
        printf("平局\n");
    }
}

void memu()
{
    printf("********************\n");
    printf("****   1.play   ****\n");
    printf("****   0.exit   ****\n");
    printf("********************\n");

}

void test()
{
    int n = 0;
    srand((unsigned)time(NULL));
    do
    {
        memu();
        printf("请选择:\n");
        scanf("%d",&n);
        if(n==1)
        {
            game();
        }
        else if(n==0)
        {
            printf("退出游戏\n");
            break;
        }
        else 
        {
            printf("输入错误,请重输:\n");
        }
    }while(n);
}
 int main()
 {
     test();
     return 0;
 }

game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
#include "sanziqi.h"

char Isfull(char board[ROW][COL],int row,int col);

void InitBoard(char board[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            board[i][j]='+';
        }
    }

}

void PrintBoard(char board[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            printf(" |");
        }
        printf("\n");
        for(j=0; j<row; j++)
        {
            printf("-%c",board[i][j]);
        }
        printf("-\n");
    }
    for(j=0; j<col; j++)
    {
        printf(" |");
    }
    printf("\n");
}
int now_row = 0;
int now_col = 0;
void Player(char board[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    while(1)
    {
        scanf("%d %d",&i,&j);
        now_row = i-1;
        now_col = j-1;
        if(now_row<row && now_col<col)
        {
            if(board[now_row][now_col]=='+')
            {
                board[now_row][now_col]='@';
                break;
            }
            else
            {
                printf("坐标无效,请重新输入:\n");
            }
        }
        else
        {
            printf("坐标无效,请重新输入:\n");
        }
    }
}

void Computer(char board[ROW][COL],int row,int col,int num)
{
    int i = 0;
    int j = 0;
    int count = 0;
    char c = board[now_row][now_col];
    int a = 0;
    int b = 0;
    int ret = num-2;
    while(1)
    {
        //当前位置行的右判断
        if((now_col<col-ret)&&(now_col >=1))
        {
            for(a= now_row,b= now_col; b<now_col+ret; b++)
            {
                if(board[a][b] != c)
                {
                    break;
                }
            }
            if(b == now_col+ret)
            {
                if(board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if(board[a][b-ret-1] == '+')
                {
                    board[a][b-ret-1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置行的左判断
        if((now_col >= ret) && (now_col < col-1))
        {
            for(a = now_row, b = now_col; b > now_col-ret; b--)
            {
                if(board[a][b] != c)
                {
                    break;
                }
            }
            if(b == now_col-ret)
            {
                if(board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if(board[a][b+ret+1] == '+')
                {
                    board[a][b+ret+1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置列的上判断
        if ((now_row >= ret) && (now_row < col - 1))
        {
            for (a = now_row, b = now_col; a > now_row-ret; a--)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if (a == now_row-ret)
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a+ret+1][b] == '+')
                {
                    board[a+ret+1][b] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置列的下判断
        if ((now_row<col - ret) && (now_row >= 1))
        {
            for (a = now_row, b = now_col; a < now_col+ret; a++)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if (a == now_row + ret)
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a-ret-1][b] == '+')
                {
                    board[a-ret-1][b] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置右下对角线的判断
        if ((now_row < row-ret) && (now_col < col-ret) && (now_row >= 1) && (now_col >= 1))
        {
            for (a = now_row, b = now_col; a<now_row+ret && b<now_col+ret; a++, b++)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if ((a == now_row+ret) && (b == now_col+ret))
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = '0';
                    goto exit;
                }
                else if (board[a-ret-1][b-ret-1] == '+')
                {
                    board[a-ret-1][b-ret-1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置左下对角线的判断
        if ((now_row < row-ret) && (now_col >= ret) && (now_row >= 1) && (now_col < col-1))
        {
            for (a = now_row, b = now_col; a<now_row+ret && b>now_col-ret; a++, b--)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if ((a == now_row+ret) && (b == now_col-ret))
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a-ret-1][b+ret+1] == '+')
                {
                    board[a-ret-1][b+ret+1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置右上对角线的判断
        if ((now_row >= ret) && (now_col < row-ret) && (now_row < row-1) && (now_col >= 1))
        {
            for (a = now_row, b = now_col; a > now_row-ret && b < now_col+ret; a--, b++)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if ((a == now_row-ret) && (b == now_col+ret))
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a+ret+1][b-ret-1] == '+')
                {
                    board[a+ret+1][b-ret-1] = 'O';
                    goto exit;
                }
            }
        }
        //当前位置左上对角线的判断
        if ((now_row >= ret) && (now_col >= ret) && (now_row < row-1) && (now_col < col-1))
        {
            for (a = now_row, b = now_col; a > now_row-ret && b > now_col-ret; a--, b--)
            {
                if (board[a][b] != c)
                {
                    break;
                }
            }
            if ((a == now_row-ret) && (b == now_col-ret))
            {
                if (board[a][b] == '+')
                {
                    board[a][b] = 'O';
                    goto exit;
                }
                else if (board[a+ret+1][b+ret+1] == '+')
                {
                    board[a+ret+1][b+ret+1] = 'O';
                    goto exit;
                }
            }
        }

            i = rand() % row;
            j = rand() % row;
            if (board[i][j] == '+')
            {
                board[i][j] = 'O';
                goto exit;
                //break;
            }
    }
    exit:;
}

char Judge(char board[ROW][COL],int row,int col,int num)
{
    int i = 0;
    int j = 0;
    char ret = 0;
    char c = 0;
    int a = 0;
    int b = 0;
    int n = num-1;
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            if(board[i][j]!='+')
            {
                c = board[i][j];
                //判断行
                if(j<col-n)
                {
                        for(a=i,b=j; b<=j+n; b++)
                        {
                            if(board[a][b]!=c)
                            {
                                break;
                            }
                        }
                        if((b>j+n))
                        {
                            return c;
                        }
                }
                //判断列
                if(i<row-n)
                {
                        for(a=i,b=j; a<=i+n; a++)
                        {
                            if(board[a][b]!=c)
                            {
                                break;
                            }
                        }
                        if((a>i+n))
                        {
                            return c;
                        }
                }
                //判断对角线
                //判断右下对角线
                if((i<row-n)&&(j<col-n))
                {
                    for(a=i,b=j; (a<=i+n) && (b<=j+n);a++,b++)
                    {
                        if(board[a][b]!=c)
                        {
                            break;
                        }
                        if((a>i+n)&&(b>j+n))
                        {
                            return c;
                        }
                    }
                }
                //判断左下对角线
                if((i<row-n)&&(j>=n))
                {
                    for(a=i,b=j; (a<=i+n) && (b>=j-n); a++,b--)
                    {
                        if(board[a][b]!=c)
                        {
                            break;
                        }
                    }
                    if((a>i+n)&&(b<j-n))
                    {
                        return c;
                    }
                }
                //判断右上对角线
                if((i>=n)&&(j<col-n))
                {
                    for(a=i,b=j; (a>=i-n) && (b<=j+n); a--,b++)
                    {
                        if(board[a][b]!=c)
                        {
                            break;
                        }
                    }
                    if((a<i-n)&&(b>j+n))
                    {
                        return c;
                    }
                }
                //判断左上对角线
                if((i>=n)&&(j>=n))
                {
                    for(a=i,b=j; (a>=i-n) && (b>=j-n); a--,b--)
                    {
                        if(board[a][b]!=c)
                        {
                            break;
                        }
                    }
                    if((a<i-n)&&(b<j-n))
                    {
                        return c;
                    }
                }
            }
        }
    }
    //判断是否平局
    ret = Isfull(board,ROW,COL);
    if(ret=='I')
    {
        return 'I';
    }
    return '+';
}

char Isfull(char board[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            if(board[i][j]=='+')
            {
                return '+';
            }
        }
    }
    if(i==row && j==col)
    {
        return 'I';
    }
}


运行结果

玩家赢

这里写图片描述

电脑赢

这里写图片描述

猜你喜欢

转载自blog.csdn.net/cottonrose_orange/article/details/81008671
今日推荐