提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、三子棋的游戏规则?
  • 二、三子棋的游戏设计的大概思路?
  • 三、设计详细思路加代码
    • 1.首先定义一个菜单menu函数
    • 2.在test函数中调用menu函数
    • 3.在main函数中在调用test函数
    • 4.以上均在text.c中进行,然后我们需要在text.c文件中调用game函数,然后在game.c的源文件实现其功能,实现game函数的具体思路和代码如下
      • 1.创造一个二维数组,用来打印棋盘
      • 2.实现棋盘的初始化
      • 3.将棋盘初始化后就是打印棋盘了
      • 4.接下来就是玩家和电脑分别进行下棋了
      • 5.最后是判断输赢了
  • 四.总结
  • 此外

前言

提示:这里可以添加本文要记录的大概内容:

三子棋写成的效果如下

写成N子棋 效果如下(其中拿五子棋做示范)


提示:以下是本篇文章正文内容,下面案例可供参考

一、三子棋的游戏规则?

游戏规则要求:电脑(随机)和玩家一次下一子,双方轮流交替下子,直到电脑和玩家任意一方获胜,或者棋盘满了,结束游戏。

获胜判定:只要电脑或者玩家任意一方的棋子有三子连在一起,可以为横连、纵连、斜连,则该方获胜,游戏结束。若棋盘满了,则判定为平局。

二、三子棋的游戏设计的大概思路?

实现程序的思路:首先我们需要定义游戏菜单和游戏规则。

游戏菜单:选择是否开始玩儿游戏,1:玩儿,0:退出游戏;

游戏规则:电脑先走,玩家后走,一方棋子有三子连在一起即为赢,否则棋盘满还未有一方赢判定为平局。

接下来就是开始玩儿游戏了(游戏过程):打印棋盘 → 电脑走一步 → 玩家走一步 → 判定输赢 or 平局 。(为了最后的显示效果,任意一方走一步就打印一次棋盘)。

棋盘初始化 → 打印棋盘 → 设定棋盘的行列数 → 打印盘的样式;

电脑走 → 设定电脑走的随机坐标(棋盘上有空位才能走);

玩家走 → 输入家走的坐标 → 有空位就打印出棋子(还需要考虑坐标被占用和输入坐标不合法两种情况);

判断输赢 → 棋盘上的横连、纵连、斜连有三子一样的即为该方赢 → 棋盘满了即为平局。

三、设计详细思路加代码

为了确保程序的独立性
我们创造两个源文件game.c和text.c,一个头文件game.h实现程序的模块化进行
其中game.c用来实现整个游戏的具体操作
text.c用来最终调用game.c来实现运行
这就需要创造一个头文件game.h来实现上述的调用

1.首先定义一个菜单menu函数

代码如下(示例):

//游戏菜单:选择是否开始玩儿游戏,1:玩儿,0:退出游戏;
void menu()
{printf("*************************\n");printf("******** 1.play  ********\n");printf("******** 0.exit  ********\n");printf("*************************\n");
}

2.在test函数中调用menu函数

使用函数调用的方式实现

void test()
{//srand((unsigned int)time(NULL));int input = 0;do{menu();printf("请选择:>");scanf("%d", &input);switch (input)//采用switch函数实现选择,选择1就进行game,选择0就退出,其他就重新选择{case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误\n");break;}} while (input);
}

3.在main函数中在调用test函数

int main()
{test();return 0;
}

4.以上均在text.c中进行,然后我们需要在text.c文件中调用game函数,然后在game.c的源文件实现其功能,实现game函数的具体思路和代码如下

1.创造一个二维数组,用来打印棋盘

void game()
{char board[3][3];
}

为避免创造棋盘的维数受到限制,我们在头文件game.h中定义两个define定义的常变量ROW(行)和COL(列)(column)来表示打印棋盘的行和列
这样我们仅需要该其后面的数字就可以玩我们想玩的维数棋盘了

#define ROW 3
#define COL 3

然后将数组后的行列改为ROW,COL就可以在只改变头文件中ROW,COL后定义的数字控制需要打印的棋盘维数了

void game()
{char board[ROW][COL];
}

2.实现棋盘的初始化

将棋盘全部初始化为空格
在text.c中game函数中调用init_board(board, ROW, COL)函数,并传入行和列
并将其放在头文件game.h中定义

void game()
{char board[ROW][COL];//初始化一下棋盘为全空格init_board(board, ROW, COL);
}

在game.h中声明

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);

并在game.c中文件中实现

void init_board(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] = ' ';}}
}

3.将棋盘初始化后就是打印棋盘了

因此在text.c中game函数中调用print_board(board, ROW, COL);函数并传入行和列
同样的头文件game.h中进行声明
在到game.c文件中进行实现

void game()
{char board[ROW][COL];//初始化一下棋盘为全空格init_board(board, ROW, COL);//打印棋盘print_board(board, ROW, COL);
}

在game.h中定义

//打印棋盘
void print_board(char board[ROW][COL], int row, int col)

并在game.c中文件中实现

//打印棋盘(只能打印三子棋)
void print_board(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);if(i<row-1)printf("---|---|---\n");}
}

这中打印方式是固定打印三子棋3x3的棋盘了,相当于把代码写死了,接下来的另一种代码只要在以上代码的基础上进行修改即可

N子棋棋盘打印

//打印棋盘(优化:可以打印任意维数棋盘)
void print_board(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){//printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);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){//printf("---|---|---\n");for (j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");}printf("\n");}}

4.接下来就是玩家和电脑分别进行下棋了

同样也是以上思路
在text.c文件中game函数中先调用且传入行和列
并在头文件game.h中声明
在game.c中实现
代码如下

void game()
{//存放玩家或者电脑的落子情况char board[ROW][COL];char ret = 0;//初始化一下棋盘为全空格init_board(board, ROW, COL);//打印棋盘print_board(board, ROW, COL);while (1){//玩家下棋player_move(board, ROW, COL);print_board(board, ROW, COL);//电脑下棋computer_move(board, ROW, COL);print_board(board, ROW, COL);}
}

在game.h中声明

//玩家下棋
void player_move(char board[ROW][COL], int row, int col);//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);

并在game.c文件中实现

//玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{printf("玩家下棋");while (1){printf("请输入要下的坐标");int x = 0;int y = 0;scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (board[x - 1][y - 1] == ' ')//由于玩家不会考虑到数组下标是从0开始,故要按玩家输入的坐标减一放入{board[x - 1][y - 1] = '*';break;}else{printf("该坐标以输入,请重新输入\n");}}else{printf("坐标非法\n");}}
}//电脑下棋
void computer_move(char board[ROW][COL], int row, int col)
{printf("电脑下棋\n");while (1){int x = rand() % row;//产生随机坐标int y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}
}

而电脑是用rand函数实现随机数需要test.c文件中的主函数main中使用srand((unsigned int)time(NULL));来实现随机数自由

int main()
{srand((unsigned int)time(NULL));test();return 0;
}

当然在使用库函数srand,rand,time时是也要在头文件game.h进行声明

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

5.最后是判断输赢了

我们规定:
判断输赢的代码要告诉我:电脑赢了?玩家赢了?玩家赢?游戏继续?
//电脑赢:#
//玩家赢:*
//平局:Q
//游戏继续:C

思路同样如上
我们先在text.c文件中game函数调用is_win(board, ROW, COL);来判断胜负,并传入行和列,其中is-win函数返回值用ret接收
同时在头文件game.h中声明
最后在game.c文件中实现
代码如下

void game()
{//存放玩家或者电脑的落子情况char board[ROW][COL];char ret = 0;//初始化一下棋盘为全空格init_board(board, ROW, COL);//打印棋盘print_board(board, ROW, COL);while (1){player_move(board, ROW, COL);print_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}computer_move(board, ROW, COL);print_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}}if (ret == '#')printf("电脑赢了\n");else if (ret == '*')printf("玩家赢了\n");else if (ret == 'Q')printf("平局\n");
}

在头文件game.h中声明

//判断输赢
char is_win(char board[ROW][COL], int row, int col);

在到game.c文件中实现

//只能判断三子棋输赢
char is_win(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][1] == board[i][2] && board[i][0] != ' '){return board[i][0];}}for (i = 0;  i< col; i++){if (board[0][i] == board[1][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[1][1] != ' '){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 (is_full(board, row, col) == 1)//判断平局,代码在下{return 'Q';}return 'C';

同样的和上面打印棋盘时相似,该种判断方式只能判断三子棋的输赢,相当于把代码写死了
对其进行优化,使其能不受限制,在任意N子棋都能判断输赢

N子棋棋盘判断输赢

//判断输赢(优化版:可判断任意维数棋局的输赢)
char is_win(char board[ROW][COL], int row, int col)
{//行判断int i = 0;for (i = 0; i < row; i++){int j = 0;int count = 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];}}//列判断for (i = 0; i < col; i++){int j = 0;int count = 0;for (j = 0; j < row - 1; j++){if (board[j][i] == board[j + 1][i] && board[j][i] != ' '){count++;}if (count == row - 1)return board[j][i];}}// '/'判断for (i = 0; i < row - 1; i++){if (board[i][row - 1 - i] == board[i + 1][row - 2 - i] && board[i][row - 1 - i] != ' '){if (row - 2 - i == 0)return board[i][row - 1 - i];}}// '\' 判断for (i = 0; i < row - 1; i++){if (board[i][i] == board[i + 1][i + 1] && board[i][i] != ' '){if (i == row - 2)return board[i][i];}}if (is_full(board, row, col) == 1){return 'Q';}return 'C';
}

当棋盘下满了,出现平局,此时就需要在is_win函数中调用is_ful函数来判断
假如全部满了返回1,没满返回0

int is_full(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;
}

至此三子棋(N子棋)基本完成了
所以总的代码如下
text.c

#include "game.h"//打印菜单
void menu()
{printf("*************************\n");printf("******** 1.play  ********\n");printf("******** 0.exit  ********\n");printf("*************************\n");
}void game()
{//存放玩家或者电脑的落子情况char board[ROW][COL];char ret = 0;//初始化一下棋盘为全空格init_board(board, ROW, COL);//打印棋盘print_board(board, ROW, COL);while (1){player_move(board, ROW, COL);print_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}computer_move(board, ROW, COL);print_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}}if (ret == '#')printf("电脑赢了\n");else if (ret == '*')printf("玩家赢了\n");else if (ret == 'Q')printf("平局\n");
}void test()
{int input = 0;do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误\n");break;}} while (input);
}int main()
{srand((unsigned int)time(NULL));test();return 0;
}

game.h

#define ROW 3
#define COL 3#include <stdio.h>
#include <stdlib.h>
#include <time.h>//头文件中声明函数//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);//打印棋盘
void print_board(char board[ROW][COL], int row, int col);//玩家下棋
void player_move(char board[ROW][COL], int row, int col);//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);//判断输赢
char is_win(char board[ROW][COL], int row, int col);

game.c

#include "game.h"//初始化棋盘
void init_board(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 print_board(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);if(i<row-1)printf("---|---|---\n");}
}//代码优化
//打印棋盘(优化:可以打印任意维数棋盘)
//void print_board(char board[ROW][COL], int row, int col)
//{//  int i = 0;
//  for (i = 0; i < row; i++)
//  {//      //printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
//      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)
//      {//          //printf("---|---|---\n");
//          for (j = 0; j < col; j++)
//          {//              printf("---");
//              if (j < col - 1)
//                  printf("|");
//          }
//          printf("\n");
//      }
//  }
//}//玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{printf("玩家下棋");while (1){printf("请输入要下的坐标");int x = 0;int y = 0;scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else{printf("该坐标以输入,请重新输入\n");}}else{printf("坐标非法\n");}}
}//电脑下棋
void computer_move(char board[ROW][COL], int row, int col)
{printf("电脑下棋\n");while (1){int x = rand() % row;int y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#'; break;}}
}//判断是否平局
int is_full(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 is_win(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][1] == board[i][2] && board[i][0] != ' '){return board[i][0];}}for (i = 0;  i< col; i++){if (board[0][i] == board[1][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[1][1] != ' '){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 (is_full(board, row, col) == 1){return 'Q';}return 'C';
}//代码优化
//判断输赢(优化版:可判断任意维数棋局的输赢)
//char is_win(char board[ROW][COL], int row, int col)
//{//  //行判断
//  int i = 0;
//  for (i = 0; i < row; i++)
//  {//      int j = 0;
//      int count = 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];
//      }
//
//  }
//  //列判断
//  for (i = 0; i < col; i++)
//  {//      int j = 0;
//      int count = 0;
//      for (j = 0; j < row - 1; j++)
//      {//          if (board[j][i] == board[j + 1][i] && board[j][i] != ' ')
//          {//              count++;
//          }
//          if (count == row - 1)
//              return board[j][i];
//      }
//  }
//  // '/'判断
//  for (i = 0; i < row - 1; i++)
//  {//      if (board[i][row - 1 - i] == board[i + 1][row - 2 - i] && board[i][row - 1 - i] != ' ')
//      {//          if (row - 2 - i == 0)
//              return board[i][row - 1 - i];
//      }
//
//  }
//  // '\' 判断
//  for (i = 0; i < row - 1; i++)
//  {//      if (board[i][i] == board[i + 1][i + 1] && board[i][i] != ' ')
//      {//          if (i == row - 2)
//              return board[i][i];
//      }
//  }
//  if (is_full(board, row, col) == 1)
//  {//      return 'Q';
//  }
//  return 'C';
//}

四.总结

我的第一篇博客大功告成,花费的时间和精力总会获得回报
还是小有成就感呢!
继续努力!加油,奥里给!
有不对的请及时指正我!谢谢读者

此外

对于三子棋还可以继续完善
比如:让电脑智能下棋,学会堵棋
或者是电脑有套路化的下棋等等

时间精力充裕的话可以试着去想想此类代码
我们不急慢慢来

三子棋(N子棋)小游戏超详解相关推荐

  1. 【牛客刷题】上手用C语言写一个三子棋小游戏超详解哦(电脑优化)

    作者:[南航科院小张 南航科院小张的博客 专栏:从c语言的入门到进阶 学习知识不只是要懂,还要会用:想要找到好的工作,这里给大家介绍一件可以斩获诸多大厂offer的利器–牛客网 点击免费注册和我一起开 ...

  2. python小游戏代码大全-20行python代码的入门级小游戏的详解

    背景: 作为一个python小白,今天从菜鸟教程上看了一些python的教程,看到了python的一些语法,对比起来(有其他语言功底),感觉还是非常有趣,就随手添了一点内容,改了一个小例程,当着练练手 ...

  3. python小项目——2048小游戏(详解)

    2048游戏 原版游戏地址 第一部分 导入所需要的库 第二部分 确认游戏键位设置,并和对应的操作关联 第三部分 获取用户输入的值,并直到有效键位 第四部分 对矩阵的应用,减少代码量 第五部分 创建棋盘 ...

  4. Python实现飞机大战小游戏,详解每一行代码【不收藏都对不起我】

    一.模块 1. 利用 pip 安装 pygame 模块 Windows系统下的安装参考如下文章: https://blog.csdn.net/qq_38721302/article/details/8 ...

  5. python必备入门代码-20行python代码的入门级小游戏的详解

    背景: 作为一个python小白,今天从菜鸟教程上看了一些python的教程,看到了python的一些语法,对比起来(有其他语言功底),感觉还是非常有趣,就随手添了一点内容,改了一个小例程,当着练练手 ...

  6. 10款Java小游戏(详解+源码)

    开源Java小游戏 前言 下面就给大家介绍十几个开源的Java小游戏,供大家学习交流.资源都下载好共享到我的交流群了,需要的在群内自取853665602不收取任何资源费,毕竟开源才是我们的宗旨. [群 ...

  7. Unity 之 发布WebGL转微信小游戏过程详解

    Unity 之 发布WebGL转微信小游戏 前言 一,准备工作 1.1 下载插件 1.2 下载Unity 1.3 安装微信开发者工具 1.4 创建小程序 二,开始转换 2.1 创建项目 2.2 Mac ...

  8. Python实现飞机大战小游戏,详解每一行代码!

    一.模块 1. 利用 pip 安装 pygame 模块 Windows系统下的安装参考如下文章: https://blog.csdn.net/qq_38721302/article/details/8 ...

  9. C语言实现贪吃蛇小游戏(详解)

    目录 一.程序实现的原理: 二.预备知识 1.控制台窗口 2.通过代码将光标移动到控制台指定位置 三. 程序框架 四.具体操作 1.定义相关头文件 2.定义函数结构以及相关属性 五.完成各代码块 1. ...

最新文章

  1. 【Java例题】4.3 3. 使用Gauss消元法求解n元一次方程组的根,
  2. Spring boot 启动后执行特定的操作
  3. php 删除 r n,PHP去除换行符'/r/n'回车换行与PHP_EOL变量的使用
  4. matlab教程点语言,编程语言 / Matlab教程_电脑教程学习网( 5 )
  5. 敏捷方法开发总结的点评记录
  6. 信号量内核对象 semaphore
  7. python中比较重要的几个函数_python几个重要的内置函数
  8. EXCEL保存“加载宏”
  9. 笔记本电脑如何查看wifi密码
  10. 11.2 注解的使用示例1 select insert update和delete操作
  11. 3dmax给模型添加渐变背景有哪些方法
  12. 适合开发人员看的鸿蒙OS介绍~
  13. 南卡和Snowkids电容笔哪款更值得入手?口碑最佳的国产电容笔
  14. 同步六进制加法计数电路(D触发器)
  15. 新仙剑奇侠传H5上线测试了
  16. lol登入服务器显示证书,登录LOL提示安全证书不可用怎么办
  17. python 福利_python 处理json
  18. MPCS-314 3A 光电耦合器 用于IGBT/MOSFET隔离栅极驱动 完美代替TLP5701
  19. jdbc不能识别别名_生命离开氧气就不能活了吗? 氢气告诉你,No~
  20. 结合opencv学习DIP

热门文章

  1. qq2007登陆协议分析
  2. 2022仿拼多多拼团PHP系统源码+可封装APP/多商家入驻
  3. wordnet java_Java中使用Wordnet
  4. Cocos Creator TypeScript 套牛游戏(可微信小游戏)
  5. Linux使用mutt发送邮件
  6. 利用PYHTON爬虫爬取恋家网房价
  7. java pipeline模式_NIO系列-4: 彻底搞明白Pipeline和Handler
  8. python爬取网上租房信息_用python爬取租房网站信息的代码
  9. 教你如何构建 Linux 内核
  10. java中写入文件_java中创建、写入文件的5种方式