三子棋(超详细)

简介: 三子棋(超详细)

引言:

完成一个三子棋游戏,这其实也算一个小项目。因此需要分文件书写。

test.c用于测试

game.c用于实现游戏里面的函数。

game.h用于包含所有的头文件。

其余test.c和game.c只需要引用 #include "game.h"  一步到位即可。


一、大致的游戏框架

先是一个菜单,输入1/0,1表示开始游戏,0表示结束游戏。

1/0表达式不仅方便我们等会在switch 语句中放入整数,也便于我们跳出循环while()的判断。

int main()
{
  int input = 0;
  srand((unsigned int)time(NULL));
  do
  {
    menu();
    printf("请输入\n");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      printf("开始游戏\n");
      game();
      break;
    case 0:
      printf("结束游戏\n");
      break;
    default:
      printf("输入错误,请重新输入\n");
      break;
    }
  } while (input);
  return 0;
}

二、接着最主要的就是实现game()函数。

我们做的游戏是一个三子棋。所以肯定先有一个空白的棋盘。

1、第一步就是如何实现空白的棋盘

image.png

这是我们目标的棋盘。

第一行循环打印空格、字符、空格、|,然后循环最后一下条件判断,不打印 | 即可。

第二行循环打印---|,然后循环最后一下条件判断,不打印 | 即可

最后把这两行放到一个循环里面,最后循环条件判断不打印第二行。

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

2、实现玩家落子

考虑到玩家不是程序员,所以不能用数组的下标去要求,数组就是从0开始。

玩家落子也要防止下标不合法,或者被占用的情况

void PlayerMove(char board[ROW][COL])
{
  int x = 0;
  int y = 0;
  while (1)
  {
    printf("请玩家落子,中间以空格区分\n");
    scanf("%d %d", &x, &y);
    if (x >= 1 && x <= ROW && y >= 1 && y <= ROW)
    {
      board[x - 1][y - 1] = '#';
      break;
    }
    else
      printf("输入非法,请重新输入\n");
  }
}

3、实现电脑落子

电脑落子就是一个随机值的体现。注意srand((unsigned int) time(NULL))放到主函数里面,只需要调用一次。

然后在电脑落子里面调用rand()函数即可。

void ComputerMove(char board[ROW][COL])
{
  int x = 0;
  int y = 0;
  printf("电脑落子\n");
  while (1)
  {
    x = rand() % ROW;//x就属于0~ROW-1
    y = rand() % COL;
    if (board[x][y] == ' ')
    {
      board[x][y] = '*';
      break;
    }
  }
}

4、判断输赢

判断输赢主要含有是否连成3个(包含横行、竖行、对角线),然后就是平局,如果都不满足,那就是游戏继续。

注意判断赢时,采用通解的方法,即适用任何棋盘,不仅仅适用于三子。

因为判断输赢,所以需要一个返回值,方便主函数进行判断。

char IsWin(char board[ROW][COL])
{
  //判断行
  for (int i=0;i<ROW;i++)
  {
    int count = 0;
    int j = 0;
    for (j=0;j<COL-1;j++)
    {
      if (board[i][j] == board[i][j + 1] && board[i][j] != ' ')
        count++;
    }
    if (count==COL-1)
      return board[i][j-1];//这个返回值非常巧妙
  }
  //判断列
  for (int j=0;j<COL;j++)
  {
    int count = 0;
    int i = 0;
    for (i=0;i<ROW-1;i++)
    {
      if (board[i][j] == board[i + 1][j] && board[i][j] != ' ')
        count++;
    }
    if (count==ROW-1)
      return board[i-1][j];
  }
  //判断正对角线
  int x = 0;
  int y = 0;
  int cnt1 = 0;
  while (x<ROW-1 && y<COL-1)
  {
    if (board[x][y] == board[x + 1][y + 1] && board[x][y] != ' ')
    {
      cnt1++;
    }
    x++;
    y++;
  }
  if (cnt1 == ROW - 1)
    return board[x][y];
  //判断反对角线
  int x_ = 0;
  int y_ = COL - 1;
  int cnt2 = 0;
  while (x_<ROW - 1 && y_>0)
  {
    if (board[x_][y_] == board[x_ + 1][y_ - 1] && board[x_][y_] != ' ')
      cnt2++;
    x_++;
    y_--;
  }
  if (cnt2 == ROW - 1)
    return board[x_][y_];
  //判断是否平局
  int flag = 0;
  for (int i=0;i<ROW;i++)
  {
    for (int j=0;j<COL;j++)
    {
      if (board[i][j] == ' ')
        flag = 1;
    }
  }
  if (flag == 0)
    return 'T';
  return 'C';
}

game1/game1 · 可涵/C语言练习 - 码云 - 开源中国 (gitee.com)

源码已经保存到仓库

相关文章
|
7月前
|
C语言
简易三子棋的实现
简易三子棋的实现
|
7月前
|
存储
三子棋游戏的实现
三子棋游戏的实现
62 0
三子棋的创建
三子棋的创建
87 0
简单三子棋的实现
简单三子棋的实现
68 0
|
C语言
【小朋友的三子棋】
【小朋友的三子棋】
73 0
|
C语言
C/【三子棋】
C/【三子棋】
三子棋的实现有这么简单吗?
三子棋的实现有这么简单吗?
55 0