C语言三子棋小游戏--数组的应用

简介: 三子棋,顾名思义,就是三个子连在一起就可以胜出。在本节我们要介绍的三子棋模式是这样子的:在键盘输入坐标(表示落子),和电脑对下(当前电脑设计为随机下)

注:在最后面,完整源码会以两种形式展现。在讲解时,以三个源文件的形式。


前言:三子棋,顾名思义,就是三个子连在一起就可以胜出。在本节我们要介绍的三子棋模式是这样子的:在键盘输入坐标(表示落子),和电脑对下(当前电脑设计为随机下)。

我们先看游戏执行起来的样子:

image.png

全局思路:下棋肯定需要一个棋盘,不然会显得杂乱无章;当有了棋盘之后,就需要落子,落子需要双方,一个是我们自己(手动下),另一个就是电脑(设置自动下);当每一次落子,都需要判断是否输赢,否则重复落子步骤(循环);而判断输赢也作为一块内容。因为作为小游戏,肯定需要一个游戏菜单。


思路简图:设置菜单------>设置棋盘------->(玩家落子--->电脑落子)------>判断输赢


三子棋流程图:

image.png

上面是铺垫,接下来才是重头戏,该上强度了。


一、准备工作和游戏菜单

在第一个源文件(test.c)和头文件(game.h)中实现

1.准备工作

(1)建立两个源文件和一个头文件

image.png

目的:方便观察和日后的工作(不展开)

(2)建立三个文件的联系(大致雏形)

image.png

上面的信息大致可以让我们知道每个文件大致要存放的内容,关于引用头文件这些知识不是我们现阶段需要明白的,只需记住这样用就行。

2.游戏菜单

(1)菜单的模板

void menu()//菜单函数
{
  printf("####################\n");
  printf("###### 1.play ######\n");
  printf("###### 0.exit ######\n");
  printf("####################\n");
}
int main()
{
  int input = 0;
  do//循环菜单
  {
    menu();
    printf("请选择>:");
    scanf("%d",&input);
  } while (input);
  return 0;
}

运行结果:

image.png

1.我们把菜单封装成一个函数,放在第一个源文件中。


2.当调用完菜单之后,会有两个选择,这个时候就需要输入数据,这就需要用到scanf函数。


3.因为当结束一局游戏后,会再次出现菜单让我们选择继续与否,所以要用到do…while循环,因为这样至少会执行一次菜单。


(2)输入数据后的选择与判断


   当我们用scanf函数输入数据后,就需要根据输入的数据选择不同的路径。

void menu()//菜单函数
{
  printf("####################\n");
  printf("###### 1.play ######\n");
  printf("###### 0.exit ######\n");
  printf("####################\n");
}
int main()
{
  int input = 0;
  do//循环菜单
  {
    menu();
    printf("请选择>:");
    scanf("%d",&input);
    switch (input)//用switch来判断选择
    {
    case 1:printf("你已选择继续游戏\n");
      break;
    case 0:printf("你已选择退出游戏\n");
      break;
    default:printf("选择错误,重新选择\n");//防止乱选
    }
  } while (input);
  return 0;
}

运行结果:

选择1:

image.png

选择0:

image.png

选择其他:

image.png

根据输入数据的选择,我们就需要用到switch函数来判断。

(3)继续游戏后的选择

为了选择1之后就直接可以进入游戏,所以我们在后面直接跟上game函数,然后在game中函数调用各种函数接口。

void menu()//菜单函数
{
  printf("####################\n");
  printf("###### 1.play ######\n");
  printf("###### 0.exit ######\n");
  printf("####################\n");
}
void game()
{
  char board[ROW][COL];
  InitBoard(board,ROW,COL);//初始化棋盘
  DisplayBoard(board,ROW,COL);//打印棋盘
  //落子循环
}
int main()
{
  int input = 0;
  do//循环菜单
  {
    menu();
    printf("请选择>:");
    scanf("%d",&input);
    switch (input)
    {
    case 1:printf("你已选择继续游戏\n");
      game();
      break;
    case 0:printf("你已选择退出游戏\n");
      break;
    default:printf("选择错误,重新选择\n");
    }
  } while (input);
  return 0;
}
#include<stdio.h>
#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);

在我们的game函数内,放的是一些接口,功能暂未实现。


我们需要用到二维数组,然后它的行和列需要用到宏定义的常量。如果后续需要更改棋盘的大小也会很方便。


接下来我们再一一实现每个函数的功能吧


二、初始化和打印棋盘

在第二个源文件(game.c)中实现函数体内部的功能。


1.初始化棋盘

//初始化函数
InitBoard(board,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] = ' ';//全部初始化成空格
    }
  }
}

我们可以通过调试窗口中的监视观察数组是否被成功赋值。

image.png

知识点:二维数组赋值

2.打印棋盘

//打印棋盘函数
DisplayBoard(board,ROW,COL);

如果直接将初始化好的字符数组打印出来,是看不见的,但是呢,我们可以先将空格换成其他可以看见的符号,从而可以检验我们的“打印棋盘函数”是否写对了。

要想打印出下面的这个棋盘该怎么做呢?

image.png

这是一个九宫格,其实这个棋盘有五行五列。第一行是空格和竖线组成,第二行是横线和竖线组成组成,后面同理。


我们可以有很多种方式打印,我们列举一种


1.我们可以一行一行的打印出来,打印完一行就换行。


2.竖线有两行,横线也只有两行,他们只能打印两次。


3.数组打印三行三列,横线打印两行,竖线打印两行。


打印棋盘函数:

//打印棋盘
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("\n");//打印完换行
    //打印横线(用减号代替)和竖线
    if (i < row - 1)
    {
      for (j = 0; j < col; j++)
      {
        printf("---");
        if (j < col - 1)
          printf("|");
      }
    }
    printf("\n");
  }
}

运行结果:

image.png

第一层循环,控制行;那不是五行吗?为什么这里只循环三次,因为有第二层循环的控制。


总结:第一次循环(第一层):打印三次空格和两个竖线(第二层循环),第二层循环没有结束,继续换行打印横线和竖线;这里需要注意:每一行需要打印三次横线(第二次循环必须循环三次),但是只打印两横(第一层循环只能打印两次);而每一行只打印两次竖线,并且只打印两行。


三、玩家与电脑的落子

1.玩家落子(*)

因为我们所输入的坐标是从1开始,而数组的下标是从0开始,所以需要区别

void PlayerMove(char board[ROW][COL], int row, int col)
{
  int x = 0;
  int y = 0;
  printf("请输入要落子的位置:\n");
  while (1)
  {
    printf("玩家下>:");
    scanf("%d%d", &x, &y);//输入下棋的坐标
    //判断落子位置是否合法
    if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
    {
      //判断落子位置是否被占用
      if (board[x - 1][y - 1] == ' ')
      {
        board[x - 1][y - 1] = '*';
        break;
      }
      else
        printf("该位置已被占用,请重新输入\n");
    }
    else
      printf("落子位置非法\n");
  }
}

总结:落子时,考虑位置是否合法,坐标是否被占,否则重新循环,最后再落子,落子完成再退出循环。

知识点:选择语句的条件判断与数字下标的运用

2.电脑落子(#)

电脑落子,则是需要随机产生数字作为坐标再落子,所以我们需要用到产生随机数的知识点。

生成随机数:

#include<stdlib.h>//srand所需头文件
#include<time.h>//time所需头文件
srand((unsigned)time(NULL));
int x=rand();//此时,x中的值就是随机值

其中srand函数和rand函数是配合使用的。


srand函数只需要在主函数中提到一次,srand函数中的参数设为时间,返回一个NULL,并强制类型转化。我们当前只需要计熟这句话就行。


然后我们就可以使用rand函数来产生随机数了,只需要用变量来接收即可。


当前头文件:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#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);

当前源文件(test.c):

#include"game.h"
void menu()//菜单函数
{
  printf("####################\n");
  printf("###### 1.play ######\n");
  printf("###### 0.exit ######\n");
  printf("####################\n");
}
void game()
{
  char ret = 0;
  char board[ROW][COL];
  InitBoard(board,ROW,COL);//初始化棋盘
  DisplayBoard(board,ROW,COL);//打印棋盘
  PlayerMove(board, ROW, COL);
  DisplayBoard(board, ROW, COL);//打印棋盘
  ComputerMove(board,ROW,COL);
  DisplayBoard(board, ROW, COL);//打印棋盘
}
int main()
{
  int input = 0;
  srand((unsigned)time(NULL));
  do//循环菜单
  {
    menu();
    printf("请选择>:");
    scanf("%d",&input);
    switch (input)
    {
    case 1:printf("你已选择继续游戏\n");
      game();
      break;
    case 0:printf("你已选择退出游戏\n");
      break;
    default:printf("选择错误,重新选择\n");
    }
  } while (input);
  return 0;
}

电脑落子函数:

//电脑落子
void ComputerMove(char board[ROW][COL], int row, int col)
{
  printf("电脑落子:\n");
  int x = 0;
  int y = 0;
  while (1)
  {
    x = rand() % row;
    y = rand() % col;//范围0-2
    if (board[x][y] == ' ')
    {
      board[x][y] = '#';//满足就落子,否则继续循环
        break;
    }
  }
}

上面的落子函数虽然已经写完,但是运行起来还是很不完整的,接下来的判赢才是重头戏。

四、判断输赢与循环落子

1.判赢

游戏的大致走向有四种:继续游戏、玩家赢、电脑赢和平局。其中,继续游戏就是循环落子的原因,知道出现一个结局。

判赢函数:

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

我们这里规定一下,根据该函数的返回值来决定四种结果:

//*--玩家赢    #----电脑赢   P----平局    C-----游戏继续

判赢:

三子棋游戏胜利的结果就是三个子连成一条线。三子连成线的结果无非就是三种:横、竖和斜的。

//*--玩家赢    #----电脑赢   P----平局    C-----继续
char Iswin(char board[ROW][COL], int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)//三列相等的
  {
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
      return board[0][i];
  }
  for (i = 0; i < col; i++)//三列相等的
  {
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
      return board[i][0];
  }
  //判断\相等
  if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
      return board[1][1];
  //判断/相等
  if (board[2][2] == board[1][1] && board[1][1] == board[0][0] && board[1][1] != ' ')
      return board[1][1];
  return 'C';
}

1.前面两个for循环判断横与列是否相等,如果相等就返回某一个坐标的值。


2.后面两个if语句同样的效果,满足条件就返回某个坐标。


3.如果上面的都不满足,则会返回'C',也就是游戏继续


上面的代码还差一种结局,那就是平局。平局的条件莫非就是棋盘满了,但是还没有分出胜负,所以我们另外封装一个判满的函数即可。(在上面的代码基础上改进)

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;
}
//*--玩家赢    #----电脑赢   P----平局    C-----继续
char Iswin(char board[ROW][COL], int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)//三列相等的
  {
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
      return board[0][i];
  }
  for (i = 0; i < col; i++)//三列相等的
  {
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
      return board[i][0];
  }
  //判断\相等
  if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
      return board[1][1];
  //判断/相等
  if (board[2][2] == board[1][1] && board[1][1] == board[0][0] && board[1][1] != ' ')
      return board[1][1];
  //判断平局
  if (IsFull(board, row, col))
    return 'P';
  return 'C';
}

现在代码完整了,只要不满足输赢或者平局,游戏就会继续。

现在函数体的内容都已经完成,接下来需要在主函数实现接收其返回值并实现循环落子。

2.用循环实现游戏继续

其实就是每下一次,就打印一次棋盘,并且判断一次游戏是否继续

char ret=0;
while (1)
  {
    //玩家下棋
    PlayerMove(board, ROW, COL);
    DisplayBoard(board, ROW, COL);//打印棋盘
    //每走一步棋就判断一次
    ret = Iswin(board,ROW,COL);
    if (ret != 'C')//C!=C为假,不会跳出循环
      break;
    //电脑下棋
    ComputerMove(board, ROW, COL);
    DisplayBoard(board, ROW, COL);//打印棋盘
    //判断电脑输赢
    ret = Iswin(board,ROW,COL);
    if (ret != 'C')
      break;
  }
  //跳出循环,表示博弈结束,并判断结局
  if (ret == '*')
    printf("恭喜玩家获胜,再来一局吧\n");
  if (ret == '#')
    printf("电脑获胜,再来一局吧\n");
  if (ret == 'P')
    printf("恭喜平局,谁也没有获胜\n");

到这里每个阶段的内容就完成了,接下来是总体的代码。

五、完整源码

1.分装成三个文件的源码

(1)头文件(game.h)

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#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);

(2)源文件(game.c)

#include"game.h"
//初始化棋盘
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("\n");//打印完换行
    //打印横线(用减号代替)和竖线
    if (i < row - 1)
    {
      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 x = 0;
  int y = 0;
  printf("请输入要落子的位置:\n");
  while (1)
  {
    printf("玩家下>:");
    scanf("%d%d", &x, &y);//输入下棋的坐标
    //判断落子位置是否合法
    if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
    {
      //判断落子位置是否被占用
      if (board[x - 1][y - 1] == ' ')
      {
        board[x - 1][y - 1] = '*';
        break;
      }
      else
        printf("该位置已被占用,请重新输入\n");
    }
    else
      printf("落子位置非法\n");
  }
}
//电脑落子
void ComputerMove(char board[ROW][COL], int row, int col)
{
  printf("电脑落子:\n");
  int x = 0;
  int y = 0;
  while (1)
  {
    x = rand() % row;
    y = rand() % col;//范围0-2
    if (board[x][y] == ' ')
    {
      board[x][y] = '#';//满足就落子,否则继续循环
        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;
}//*--玩家赢    #----电脑赢   P----平局    C-----继续
char Iswin(char board[ROW][COL], int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)//三列相等的
  {
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
      return board[0][i];
  }
  for (i = 0; i < col; i++)//三列相等的
  {
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
      return board[i][0];
  }
  //判断\相等
  if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
    return board[1][1];
  //判断/相等
  if (board[2][2] == board[1][1] && board[1][1] == board[0][0] && board[1][1] != ' ')
    return board[1][1];
  //判断平局
  if (IsFull(board, row, col))
    return 'P';
  return 'C';
}

(3)源文件(test.c)

#include"game.h"
void menu()//菜单函数
{
  printf("####################\n");
  printf("###### 1.play ######\n");
  printf("###### 0.exit ######\n");
  printf("####################\n");
}
void game()
{
  char ret = 0;
  char board[ROW][COL];
  InitBoard(board,ROW,COL);//初始化棋盘
  DisplayBoard(board,ROW,COL);//打印棋盘
  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");
  if (ret == '#')
    printf("电脑获胜,再来一局吧\n");
  if (ret == 'P')
    printf("恭喜平局,谁也没有获胜\n");
}
int main()
{
  int input = 0;
  srand((unsigned)time(NULL));
  do//循环菜单
  {
    menu();
    printf("请选择>:");
    scanf("%d",&input);
    switch (input)
    {
    case 1:printf("你已选择继续游戏\n");
      game();
      break;
    case 0:printf("你已选择退出游戏\n");
      break;
    default:printf("选择错误,重新选择\n");
    }
  } while (input);
  return 0;
}

2.一个文件的源码

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#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);
//初始化棋盘
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("\n");//打印完换行
    //打印横线(用减号代替)和竖线
    if (i < row - 1)
    {
      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 x = 0;
  int y = 0;
  printf("请输入要落子的位置:\n");
  while (1)
  {
    printf("玩家下>:");
    scanf("%d%d", &x, &y);//输入下棋的坐标
    //判断落子位置是否合法
    if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
    {
      //判断落子位置是否被占用
      if (board[x - 1][y - 1] == ' ')
      {
        board[x - 1][y - 1] = '*';
        break;
      }
      else
        printf("该位置已被占用,请重新输入\n");
    }
    else
      printf("落子位置非法\n");
  }
}
//电脑落子
void ComputerMove(char board[ROW][COL], int row, int col)
{
  printf("电脑落子:\n");
  int x = 0;
  int y = 0;
  while (1)
  {
    x = rand() % row;
    y = rand() % col;//范围0-2
    if (board[x][y] == ' ')
    {
      board[x][y] = '#';//满足就落子,否则继续循环
        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;
}//*--玩家赢    #----电脑赢   P----平局    C-----继续
char Iswin(char board[ROW][COL], int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)//三列相等的
  {
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
      return board[0][i];
  }
  for (i = 0; i < col; i++)//三列相等的
  {
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
      return board[i][0];
  }
  //判断\相等
  if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
    return board[1][1];
  //判断/相等
  if (board[2][2] == board[1][1] && board[1][1] == board[0][0] && board[1][1] != ' ')
    return board[1][1];
  //判断平局
  if (IsFull(board, row, col))
    return 'P';
  return 'C';
}
void menu()//菜单函数
{
  printf("####################\n");
  printf("###### 1.play ######\n");
  printf("###### 0.exit ######\n");
  printf("####################\n");
}
void game()
{
  char ret = 0;
  char board[ROW][COL];
  InitBoard(board,ROW,COL);//初始化棋盘
  DisplayBoard(board,ROW,COL);//打印棋盘
  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");
  if (ret == '#')
    printf("电脑获胜,再来一局吧\n");
  if (ret == 'P')
    printf("恭喜平局,谁也没有获胜\n");
}
int main()
{
  int input = 0;
  srand((unsigned)time(NULL));
  do//循环菜单
  {
    menu();
    printf("请选择>:");
    scanf("%d",&input);
    switch (input)
    {
    case 1:printf("你已选择继续游戏\n");
      game();
      break;
    case 0:printf("你已选择退出游戏\n");
      break;
    default:printf("选择错误,重新选择\n");
    }
  } while (input);
  return 0;
}

六、总结

1.需要掌握产生随机数的方法。

2.游戏总的是采用二维数组实现,其中包括了二维数组的赋值和打印数据。

3.函数的返回值和各种循环结果、选择结构。

相关文章
|
25天前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
78 6
|
28天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
54 5
|
28天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
27天前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
44 1
|
27天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
61 1
|
28天前
|
网络协议 物联网 数据处理
C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势
本文探讨了C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势。文章详细讲解了使用C语言实现网络通信程序的基本步骤,包括TCP和UDP通信程序的实现,并讨论了关键技术、优化方法及未来发展趋势,旨在帮助读者掌握C语言在网络通信中的应用技巧。
42 2
|
1月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
1月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
58 4
|
2月前
|
存储 编译器 C语言
【c语言】数组
本文介绍了数组的基本概念及一维和二维数组的创建、初始化、使用方法及其在内存中的存储形式。一维数组通过下标访问元素,支持初始化和动态输入输出。二维数组则通过行和列的下标访问元素,同样支持初始化和动态输入输出。此外,还简要介绍了C99标准中的变长数组,允许在运行时根据变量创建数组,但不能初始化。
59 6