天生棋局(指针)

题目描述

中国传统文化源远流长,博大精深,包含着华夏先哲的无穷智慧,也是历朝历代炎黄子孙生活的缩影。围棋作为中华民族流传已久的一种策略性棋牌游戏,蕴含着丰富的汉民族文化内涵,是中国文明与中华文化的体现。本案例要求创建一个棋盘,在棋盘生成的同时初始化棋盘,根据初始化后棋盘中棋子的位置来判断此时的棋局是否是一局好棋。具体要求如下:**

1)棋盘的大小根据用户的指令确定;

2)棋盘中棋子的数量也由用户设定;

3)棋子的位置由随机数函数随机确定,若生成的棋盘中有两颗棋子落在同一行或同一列,则判定为“好棋”,否则判定为“不是好棋”。

#注释

天生棋局指针类型的和上次数组类型的大体思路是一样的,在这里主要不同的,在于用calloc()函数申请一个动态的存储空间,因为calloc()函数成功生成动态存储空间会返回储存空间的首地址,所以在这里用指针类型的变量来实现对动态存储空间的操作。

这里主要用二维指针,二维指针储存一维指针的地址,二维指针可以看做二维数组,而二维数组可以看做由一维数组组生成,这样理解起来比较简单些

附上关键自定义生成动态存储函数

 int ** board(int n)
{
    int ** p = (int **)calloc(sizeof(int*), n);//calloc在内存中分配n*size大小的动态存储空间,返回一个起始地址的一个指针 
    for (int i = 0; i < n; i++)
    {
        p[i] = (int *)calloc(sizeof(int), n);
    }
    return p;
}

代码实现

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int ** board(int n);      //申请动态存储空间 
void inkey(int **p,int n,int m);//用随机数下棋 
void printboard(int **p,int n);//打印棋格 
int check(int **p,int n);//检查好/坏棋 
void freespace(int **p,int n);//释放动态空间 
int main()
{
    int n,m,con;
    printf("请输入棋盘大小:n");
    scanf("%d",&n);
    printf("请输入棋子数量:n");
    scanf("%d",&m);
    int **p=board(n);
    inkey( p ,n, m );
    printboard(p,n);
    con=check(p,n);
    freespace(p,n);
    if(con)
        printf("好棋!");
    else
        printf("不是好棋!"); 
    return 0;

 } 
 int ** board(int n)
{
    int ** p = (int **)calloc(sizeof(int*), n);//calloc在内存中分配n*size大小的动态存储空间,返回一个起始地址的一个指针 
    for (int i = 0; i < n; i++)
    {
        p[i] = (int *)calloc(sizeof(int), n);
    }
    return p;
}
void inkey(int **p,int n,int m)
{
    srand((unsigned int)time(NULL));  //随机数种子   生成伪随机数,每次的随机数都不一样 
    while(m--)
    {
        int a=rand()%n,b=rand()%n;
        p[a][b]=1;
    }
}
void printboard(int **p,int n)
{
    for(int i=0;i<n;i++)                //  生  成  棋  盘 
    {
        for(int j =0;j<n;j++)        //   ┏ ┓┗ ┛┠ ┷ ┨ ┯ ┼ ●
            {
                if(p[i][j]==1)
                    printf("●");
                else
                {
                    if (i == 0 && j == 0)    
                        printf("┏");
                    else if (i == 0 && j == n - 1)
                        printf("┓");
                    else if (i == n - 1 && j == 0)
                        printf("┗");
                    else if (i == n - 1 && j == n - 1)
                        printf("┛");
                    else if (j == 0)
                        printf("┠");
                    else if (i == n - 1)
                        printf("┷");
                    else if (j == n - 1)
                        printf("┨");
                    else if (i == 0)
                        printf("┯");
                    else
                        printf("┼");
                }
            }
            putchar('n');
        } 
}
int check(int **p,int n)
{
    int flag = 0;    //   默认不是好棋。 
    for(int i=0;i<n;i++)                        // 判断 好棋 坏棋 
    {
        for(int j=0;j<n;j++)
        {
            if (p[i][j] == 1)
            {
                if (j>0 && p[i][j-1] == 1)        //判断同一行有无相邻棋子
                {
                    flag = 1;     
                }
                if (i >0 && p[i-1][j] == 1)    //判断同一列有无相邻棋子
                {
                    flag = 1;
                }
            }    
        } 
    }
    return flag;
}
void freespace(int **p,int n)
{

    for (int i= 0; i < n; i++)
    {
        free(p[i]);                        //释放一级指针指向的空间
    }
    free(p);                            //释放二级指针指向的空间
}