三子棋游戏-创新互联

简要介绍

制作一个三子棋游戏,我们需要有以下的要素

在卓尼等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站制作、网站建设 网站设计制作按需求定制制作,公司网站建设,企业网站建设,品牌网站制作,营销型网站建设,成都外贸网站建设,卓尼网站建设费用合理。
  1. 菜单

  1. 游戏界面

  1. 玩家下棋、电脑下棋

  1. 判断胜负并且输出

菜单

首先,我们需要有一个菜单,我们可以先将'菜单'封装成一个函数

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

然后,我们应该输入一个数字,来进行选择,因此这里需要用到条件语句

int main()
{
  int input;
  menu();
  printf("请输入你的选择");
  scanf("%d",&input);
  switch(input)
  case 1:
      printf("三子棋游戏");
      game();//这里进行游戏
      break;
  case 0:
      printf("退出游戏");
      break;
  default:
      break;
  return 0;
}
游戏 游戏的界面

我们知道,三子棋应当是有一个类似“棋盘”的东西,而且玩家要下棋——怎么下棋?

我们用一个3*3的二维数组来读取玩家/电脑的输入

char board[3][3]={0};

然后我们需要将这个棋盘都初始化,最初显示出的棋盘应该是没有落子的

且为了避免麻烦,我们用一个函数封装起来,且用循环来初始化棋盘

InitBoard(board,3,3);

void InitBoard(char *board[3][3],int x,int y)
{
  int i;
  for(i=0;i<3;i++)//控制行
  {
     int j;//在循环里定义,若放在循环外面,j的值会在循环后保留不变,就无法实现循环
     for(j=0;j<3;j++)//控制列
     {
          board[i][j] = ' ';//将该个元素初始化为' '
     }   
  }
}

初始化后,我们需要显示一下棋盘,让玩家知道当前棋盘的状况

显示棋盘

首先,可以看一下简要的棋盘模样

实则就是一个“井”字

DisplayBoard(board, 3, 3);

void DisplayBoard(char board[3][3], int x, int y)
{
    int i = 0;
    for (i = 0; i< x; i++)//首先,同初始化一般,i控制行数
    {
        int j = 0;
        for (j = 0; j< y; j++)//j控制列数
        {
            printf(" %c ", board[i][j]);//按照元素+符号的形式打印出一个棋盘
            //printf("  ");为什么不用这个?而是用数组打印?不都是空格吗?——>C语言里用数组元素打印的话,
            //同时就会给数组元素'安定'下位置,那么每次改变就会在该处地方改变,若没有打印数组元素
            //那么数组中的元素会被随机存放,甚至在运行框内看不到        
            if (j< col - 1)
                printf("|");//第三列右侧不需要打印边界
        }
        if (i< x - 1)//最后一行不打印边框
        {
            int j = 0;
            for (j = 0; j< y; j++)
            {
                printf("---");//打印连接的符号
                if (j< y - 1)
                    printf("|");
            }
            printf("\n");
        }
    }
}

显示完棋盘,我们需要玩家来下棋

如何下棋?——>输入坐标

下棋 玩家

玩家的下棋封装成一个函数

PlayerMove(board, 3, 3);

void PlayerMove(char board[3][3],int x,int y)
{
   int a,b;
   printf("玩家下棋");
   printf("请输入你要走的坐标:>");
   scanf("%d %d",&a,&b);
}

接着要进入判断,下棋的地方是否能下,若不能,则需要重新下,那怎么重新下呢?——用循环

输入成功则跳出这个循环。

且因为是重复下棋,所以需要输入a,b语句放置在循环内,实现多次输入

while(1)
{  
  printf("请输入你要走的坐标:>");
  scanf("%d %d",&a,&b);
  if(board[a-1][b-1]==' ')//因为是数组,所以要对输入的坐标减1
   {
    board[a-1][b-1]=='*';//玩家的子定义成'*'
    break;//输入成功就跳出这个循环
   }
   else 
   {
    printf("你输入的坐标有误!请重新输入!")
   }
}

但是,若有重复输入的情况怎么办?——要保证落子的时候,该区域没有棋子

那么代码就会变为

while (1)
    {
        printf("请输入要下棋的坐标:>");
        scanf("%d %d", &x, &y);
        if (a >= 1 && a<= x && b >= 1 && b<= y)//没有棋子才能进入这个语句进行下棋
        {
            if (board[a - 1][b - 1] == ' ')//因为是数组,所以要对输入的坐标减1
            {
                board[a - 1][b - 1] = '*';//玩家的子定义成'*'
                break;
            }
            else
            {
                printf("坐标被占用,重新输入");//输入成功就跳出这个循环
            }
        }
        else
        {
            printf("坐标非法,请重新输入\n");
        }
    }
}
总和
void PlayerMove(char board[3][3], int x, int y)
{
    int a = 0;
    int b = 0;

    printf("玩家下棋\n");

    while (1)
    {
        printf("请输入要下棋的坐标:>");
        scanf("%d %d", &a, &b);
        if (a >= 1 && a<= x && b >= 1 && b<= y)
        {
            if (board[a - 1][b - 1] == ' ')
            {
                board[a - 1][b - 1] = '*';
                break;
            }
            else
            {
                printf("坐标被占用,重新输入");
            }
        }
        else
        {
            printf("坐标非法,请重新输入\n");
        }
    }
}
电脑

电脑输入坐标,和玩家一样也要先进行判断,下棋的位置是否有棋子,若有则重新输入,否则就落子并且退出循环

ComputerMove(board, 3, 3);

void ComputerMove(char board[3][3], int x, int y)
{
  int a,b;
  while(1)
  {
       
  }
}

不一样的是,这里的坐标是随机数,随机数就要用到rand函数,具体可以百度或者看csdn上其他大佬的详细介绍,这里仅用作一个工具来实现随机数的设置

void ComputerMove(char board[3][3], int x, int y)
{
  int a,b;
  while(1)//若落子失败就会无限进行循环数的设置
  {
       a = rand() % 3;//膜上3,结果恰好为0-2
       b = rand() % 3;
        if (board[a][b] == ' ')//判断是否有空位
        {
            board[a][b] == '#';
            break;//落子结束,就跳出循环
        }
  }
}
判断胜负

三子棋游戏,应该是在每次玩家/电脑下棋后会有一次判断胜负的功能

且会有四种情况——1.玩家胜 2.电脑胜 3.胜负未分,继续游戏 4.平局

这里同样封装成一个函数

Iswin(board, 3, 3);

Iswin(char board[3][3], 3, 3)
{
   //先判断行
   int i = 0;
   for (i = 0; i< 3; i++) 
   
}

到这里,我们需要思考,如果玩家胜,会实现什么程序,电脑胜会实现什么程序,平局?继续?

我们可以用函数来返回字符来实现以上的程序

前面我们提到 玩家的落子是字符'*',电脑落子是'#',那么我们可以用其落子作为返回值进行条件语句的判断,平局和继续游戏的情况也可以各自返回一个值来决定游戏的进行

玩家胜和电脑胜可以用同一个函数,不用分开

Iswin(char board[3][3], 3, 3)
{
   //先判断行
   int i = 0;
   for (i = 0; i< 3; i++) //判断一行相同
   {
        if (board[i][0] == board[i][1] == board[i][2] && board[i][0] != ' ')
        {
            return board[i][1];
        }
    }
    for (i = 0; i< 3; i++)//判断一列
    {
        if (board[0][i] == board[1][i] == board[2][i] && board[0][i] != ' ')
        {
            return board[0][i];
        }
    }
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == board[3][3])//判断正对角线
    {
        return board[1][1];
    }
    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')//判断逆对角线
    {
        return board[1][1];
    }
}

然后,我们需要判断平局

平局

平局的时候就是不满足胜负的情况,且棋盘满了,这时候我们需要返回一个值来判断是否是平局

IsFull(board, 3, 3);

int IsFull(char board[ROW][COL], int row, int col)
{
    int i = 0;
    int j = 0;
    for (i = 0; i< 3; i++)
    {
        for (j = 0; j< 3; j++)
        {
            if (board[i][j] == ' ')
            {
                return 0;//没满
            }
        }
    }
    return 1;//满了
}

排除了以上三种可能,那我们最后就继续游戏

代码汇总如下:

汇总:

int IsFull(char board[3][3], int x, int y)
{
    int i = 0;
    int j = 0;
    for (i = 0; i< 3; i++)
    {
        for (j = 0; j< 3; j++)
        {
            if (board[i][j] == ' ')
            {
                return 0;//没满
            }
        }
    }
    return 1;//满了
}


char Iswin(char board[3][3], int x, int y)
{
    int i = 0;
    for (i = 0; i< x; i++)
    {
        if (board[i][0] == board[i][1] == board[i][2] && board[i][0] != ' ')
        {
            return board[i][1];
        }
    }
    for (i = 0; i< y; i++)
    {
        if (board[0][i] == board[1][i] == board[2][i] && board[0][i] != ' ')
        {
            return board[0][i];
        }
    }
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == board[3][3])
    {
        return board[1][1];
    }
    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    {
        return board[1][1];
    }
    //判断是否平局
    if (IsFull(board, ROW, COL))
    {
        return 'Q';
    }
    //游戏继续
    return 'C';
}

现在有了以上的函数后,我们要凑成一个游戏game()函数

三子棋代码大汇总
void game()
{
    //存放数据需要一个3*3的二维数组
    char board[3][3] = { 0 };
    //最开始数组放的应该都是空格
    //初始化棋盘
    InitBoard(board, 3, 3);
    //但是如果想随时改变行列数的话,该怎么办?——宏定义

    //显示棋盘
    DisplayBoard(board, 3, 3);
    char ret = 0;//定义放在外边,若在循环里定义的话,仅能存在于循环里
    while (1)
    {
        //玩家下棋
        PlayerMove(board, 3, 3);
        DisplayBoard(board, 3, 3);
        //判断输赢,用返回值来判定
        ret = Iswin(board, 3, 3);
        if (ret!='C')//游戏若不进行,则说明游戏结束,就跳出循环
        {
            break;
        }
        //电脑下棋
        ComputerMove(board, 3, 3);
        DisplayBoard(board, 3, 3);
        ret = Iswin(board, 3, 3);
        if (ret != 'C')//游戏若不进行,则说明游戏结束,就跳出循环
        {
            break;
        }
        //判断输赢
    }
    if (ret == '*')
    {
        printf("玩家赢\n");
    }
    else if ('#' == ret)
    {
        printf("电脑赢\n");
    }
    else if ('Q' == ret)
    {
        printf("平局\n");
    }
    DisplayBoard(board, 3, 3);
}

对于主函数,由于我们要多次进行游戏,所以要将game()函数放在循环里

int main()
{
    int input;//input放在外边,这样就可以实现整个主函数都能调用
    srand((unsigned int)time(NULL));//随机数的设置,放在循环数里
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("三子棋\n");
            game();
            break;
        case 0:
            printf("退出游戏");
            break;
        default:
            printf("选择错误,重新选择\n");
            break;
        }
    } while (input);
    return 0;
}

综上就是三子棋的全部代码

值得一提

但是,若是想实现四子棋,五子棋,六子棋...怎么办?,难道要一个一个去修改?

这时候我们就可以用宏定义 ,此外,我们需要再设置两个头文件

game.h——作为声明文件 game.c——函数定义的文件

那我们在声明文件里进行声明

//game.h
#define _CRT_SECURE_NO_WARNINGS 1

#include#define ROW 3
#define COL 3

//函数的声明
void InitBoard(char* board[ROW][COL], int row, int col);

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

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

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

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

那我们可以改变ROW和COL的值来实现不同的m子棋

与此同时,代码里的一些参数也需要改变,为了读者方便,我直接放出来

万能代码
//game.h
#define _CRT_SECURE_NO_WARNINGS 1

#include#define ROW 3
#define COL 3

//函数的声明
void InitBoard(char* board[ROW][COL], int row, int col);

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

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

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

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

//game.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"//包含头文件,这样子可以用ROW和COL

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

void DisplayBoard(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i< row; i++)
    {
        int j = 0;
        for (j = 0; j< col; j++)
        {
            printf(" %c ", board[i][j]);
            if (j< col - 1)
                printf("|");
        }
        //printf("%c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
        if (i< row - 1)//最后一组不打印边框
        {
            int j = 0;
            for (j = 0; j< col; j++)
            {
                printf("---");
                if (j< col - 1)
                    printf("|");
            }
            printf("\n");
        }
    }
}


void PlayerMove(char board[ROW][COL], int row, int col)
{
    int a = 0;
    int b = 0;

    printf("玩家下棋:>\n");

    while (1)
    {
        printf("请输入要下棋的坐标:>");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x<= row && y >= 1 && y<= col)
        {
            if (board[a - 1][b - 1] == ' ')
            {
                board[a - 1][b - 1] = '*';
                break;
            }
            else
            {
                printf("坐标被占用,重新输入");
            }
        }
        else
        {
            printf("坐标非法,请重新输入\n");
        }
    }
}

//电脑随机下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
    int a = 0;
    int b = 0;
    printf("电脑下棋>:\n");
    while (1)//若电脑生成的重复了,则重新生成数字,进行一个循环
    {
        a = rand() % row;
        b = rand() % col;
        if (board[a][b] == ' ')
        {
            board[a][b] == '#';
            break;
        }
    }

}

int 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 0;//没满
            }
        }
    }
    return 1;//满了
}


char Iswin(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i< row; i++)
    {
        if (board[i][0] == board[i][1] == board[i][2] && board[i][0] != ' ')
        {
            return board[i][1];
        }
    }
    for (i = 0; i< col; i++)
    {
        if (board[0][i] == board[1][i] == board[2][i] && board[0][i] != ' ')
        {
            return board[0][i];
        }
    }
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == board[3][3])
    {
        return board[1][1];
    }
    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    {
        return board[1][1];
    }
    //判断是否平局
    if (IsFull(board, ROW, COL))
    {
        return 'Q';
    }
    //游戏继续
    return 'C';
}

//主函数
#define _CRT_SECURE_NO_WARNINGS 1

#include#include#include#include "game.h"//声明,这样子可以用ROW和COL
//三子棋小游戏
void  menu()
{
    printf("*********************\n");
    printf("**    1.play   ******\n");
    printf("**    0.exit   ******\n");
    printf("*********************\n");
}

void game()
{
    //存放数据需要一个3*3的二维数组
    char board[ROW][COL] = { 0 };
    //最开始数组放的应该都是空格
    //初始化棋盘
    InitBoard(board, ROW, COL);
    //但是如果想随时改变行列数的话,该怎么办?——宏定义

    //显示棋盘
    DisplayBoard(board, ROW, COL);
    char ret = 0;//定义放在外边,若在循环里定义的话,仅能存在于循环里
    while (1)
    {
        //玩家下棋
        PlayerMove(board, ROW, COL);
        DisplayBoard(board, ROW, COL);
        //判断输赢,用返回值来判定
        ret = Iswin(board, ROW, COL);
        if (ret!='C')
        {
            break;
        }
        //电脑下棋
        ComputerMove(board, ROW, COL);
        DisplayBoard(board, ROW, COL);
        ret = Iswin(board, ROW, COL);
        if (ret != 'C')
        {
            break;
        }
        //判断输赢
    }
    if (ret == '*')
    {
        printf("玩家赢\n");
    }
    else if ('#' == ret)
    {
        printf("电脑赢\n");
    }
    else if ('Q' == ret)
    {
        printf("平局\n");
    }
    DisplayBoard(board, ROW, COL);
}


int main()
{
    int input;//input放在外边,这样就可以实现整个主函数都能调用
    srand((unsigned int)time(NULL));//记得引用库函数

    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);//输入放在循环里,可以实现多次输入
        switch (input)
        {
        case 1:
            printf("三子棋\n");
            game();
            break;
        case 0:
            printf("退出游戏");
            break;
        default:
            printf("选择错误,重新选择\n");
            break;
        }
    } while (input);
    return 0;
}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧

本文标题:三子棋游戏-创新互联
文章起源:https://www.cdcxhl.com/article34/dphhpe.html

成都网站建设公司_创新互联,为您提供网站维护网站设计动态网站关键词优化移动网站建设网站排名

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都做网站