​​​

  1. 想必大家都玩过三子棋,话不多说,解释一下游戏规则,在九宫格中,每一行或每一列中出现三个相同的棋子,或者正对角线,逆对角线出现相同的棋子,则获胜,如下图


下面对代码进行实现:

文章目录

#1.打印一个菜单栏
#2.对棋盘进行初始化
#3.打印棋盘
#4.玩家开始下棋
#5.电脑开始下棋
#6.判断胜负或平局
#7.整个游戏代码的实现

#define ROW 3
#define COL 3#define chessman1 '*'  //玩家下的棋子
#define chessman2 '#'  //电脑下的棋子
1.打印一个菜单栏
void menu()
{printf("************************************\n");printf("******1.play******0.exit************\n");printf("************************************\n");}
2.对棋盘进行初始化

//先对数组进行初始化,然后打印棋盘//初始化数据为空格
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.打印上面的棋盘出来

void print_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++){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");}/*printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);if (i < row - 1){printf("---|---|---");}printf("\n");}*///这段代码只能打印出三子棋盘,其他棋盘无法打印出来
}
4.玩家开始下棋

void player_move(char board[ROW][COL], int row, int col)
{printf("玩家下棋:\n");while (1){printf("请输入要下棋的坐标:");int x = 0;int y = 0;scanf("%d%d", &x, &y);//某行某列if ( (x >= 1 && x <= row) && (y >= 1 && y <= col) )//一般来说,玩家是不知道数组下标从0开始,所以这里从1开始//满足玩家的需求{if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = chessman1 ;  //'*'//如果玩家下的是1 1,我们找数组的元素就是board[0][0],以此类推break;}else{printf("该位置已经被占用,请重新输入\n");}}else{printf("坐标非法,请重新输入\n");}}
}
5.轮到电脑开始下棋

void computer_move(char board[ROW][COL], int row, int col)
{printf("电脑下棋\n");//不用判断坐标是否合法,但是要判断是否被占用while (1){//此时行和列就可以从0开始了,电脑会识别int x = rand() % row;int y = rand() % col;if (board[x][y] == ' '){board[x][y] = chessman2; //'#'break;}}
}//判断棋盘(数组)是否满了
//这里只希望这个函数为了支持is_win函数,没有必要在头文件中声明int is_full(char board[ROW][COL], int row, int col)
{//加了static,失去了外部链接属性,无法在其他文件中查看int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;//如果没找到空格,就返回0}}}return 1;
}```
6.判断输赢的函数

char is_win(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;int count1 = 0;//玩家int  count2 = 0;//电脑//判断每行是否满足一整行都是同一个棋子for (i = 0; i < row; i++){count1 = 0;count2 = 0;for (j = 0; j < col ; j++){if (board[i][j] == chessman1 )  //'*'{count1++;}else if (board[i][j] == chessman2) //'#'{count2++;}}if (count1 == row){return chessman1;}else if (count2 == col){return chessman2;}}//判断每列是否满足一整列都是同一个棋子for (j = 0; j < col; j++){count1 = 0;count2 = 0;for (i = 0; i < row ; i++){if (board[i][j] == chessman1 ){count1++;}else if (board[i][j] == chessman2){count2++;}}if (count1 == row){return chessman1;}else if (count2 == col){return chessman2;}}//判断正对角线坐标count1 = 0;count2 = 0;for (i = 0; i < row; i++){if (board[i][i] == chessman1){count1++;}else if (board[i][i] == chessman2){count2++;}}if (count1 == row){return chessman1;}else if (count2 == col){return chessman2;}//判断逆对角线坐标count1 = 0;count2 = 0;for (i = 0; i < row; i++){if (board[i][row - 1 - i] == chessman1){count1++;}else if (board[i][row - 1 - i] == chessman2){count2++;}}if (count1 == row){return chessman1;}else if (count2 == col){return chessman2;}//判断是否平局if (is_full(board, row, col) == 1){return 'Q';}//没人赢,也没平局,继续return 'C';
}
7.整个游戏代码的实现

game.h

#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//在qi.h头文件中引用了库函数,在其他文件引用了这个头文件,就可以不用引用库函数了
#define ROW 3
#define COL 3#define chessman1 '*'  //玩家下的棋子
#define chessman2 '#'  //电脑下的棋子//头文件中声明函数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);
//电脑下棋
void print_board(char board[ROW][COL],int row,int col);
//下完棋子后打印出来棋盘char is_win(char board[ROW][COL], int row, int col);
//判断输赢的函数

test.game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{printf("************************************\n");printf("******1.play******0.exit************\n");printf("************************************\n");}void game()//只是声明这个game,具体的代码是在game.c实现
{char board[ROW][COL];char ret = 0;//相当于一个二维数组//这里初始化棋盘init_board(board, ROW, COL);//这里已经在qi.h头文件中声明过了// 所以调用的时候是qi.c通过头文件找到这个函数的//数组传参,只需写数组名,但最好写行数和列数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 == chessman2 ){printf("电脑赢了!\n");}else if (ret == chessman1 ){printf("玩家赢了!\n");}else if (ret == 'Q'){printf("平局\n");}}
//电脑赢:#---chessman2
//玩家赢:*---chessman1
//平局:Q
//游戏继续:Cvoid test()
{srand((unsigned int)time(NULL));int input = 0;do{menu();printf("请选择:");scanf("%d", &input);//不要输入其他非整型的东西,别为难scanfswitch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入错误,请重新输入\n");break;}} while (input);//input为0,判断为假,退出循环,input为非0,判断为真,重新循环}
int main()
{test();return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#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++){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");}/*printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);if (i < row - 1){printf("---|---|---");}printf("\n");}*///这段代码只能打印出三子棋盘,其他棋盘无法打印出来
}//把棋盘的打印理解了,下面就好办了//玩家开始下棋
void player_move(char board[ROW][COL], int row, int col)
{printf("玩家下棋:\n");while (1){printf("请输入要下棋的坐标:");int x = 0;int y = 0;scanf("%d%d", &x, &y);//某行某列if ( (x >= 1 && x <= row) && (y >= 1 && y <= col) )//一般来说,玩家是不知道数组下标从0开始,所以这里从1开始//满足玩家的需求{if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = chessman1 ;  //'*'//如果玩家下的是1 1,我们找数组的元素就是board[0][0],以此类推break;}else{printf("该位置已经被占用,请重新输入\n");}}else{printf("坐标非法,请重新输入\n");}}
}//轮到电脑开始下棋
void computer_move(char board[ROW][COL], int row, int col)
{printf("电脑下棋\n");//不用判断坐标是否合法,但是要判断是否被占用while (1){//此时行和列就可以从0开始了,电脑会识别int x = rand() % row;int y = rand() % col;if (board[x][y] == ' '){board[x][y] = chessman2; //'#'break;}}
}//判断棋盘(数组)是否满了
//这里只希望这个函数为了支持is_win函数,没有必要在头文件中声明int is_full(char board[ROW][COL], int row, int col)
{//加了static,失去了外部链接属性,无法在其他文件中查看int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;//如果没找到空格,就返回0}}}return 1;
}//判断输赢的函数
char is_win(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;int count1 = 0;//玩家int  count2 = 0;//电脑//判断每行是否满足一整行都是同一个棋子for (i = 0; i < row; i++){count1 = 0;count2 = 0;for (j = 0; j < col ; j++){if (board[i][j] == chessman1 )  //'*'{count1++;}else if (board[i][j] == chessman2) //'#'{count2++;}}if (count1 == row){return chessman1;}else if (count2 == col){return chessman2;}}//判断每列是否满足一整列都是同一个棋子for (j = 0; j < col; j++){count1 = 0;count2 = 0;for (i = 0; i < row ; i++){if (board[i][j] == chessman1 ){count1++;}else if (board[i][j] == chessman2){count2++;}}if (count1 == row){return chessman1;}else if (count2 == col){return chessman2;}}//判断正对角线坐标count1 = 0;count2 = 0;for (i = 0; i < row; i++){if (board[i][i] == chessman1){count1++;}else if (board[i][i] == chessman2){count2++;}}if (count1 == row){return chessman1;}else if (count2 == col){return chessman2;}//判断逆对角线坐标count1 = 0;count2 = 0;for (i = 0; i < row; i++){if (board[i][row - 1 - i] == chessman1){count1++;}else if (board[i][row - 1 - i] == chessman2){count2++;}}if (count1 == row){return chessman1;}else if (count2 == col){return chessman2;}//判断是否平局if (is_full(board, row, col) == 1){return 'Q';}//没人赢,也没平局,继续return 'C';
}

看到这里,制作五子棋或多子棋只需更改棋盘大小即可

三子棋(五子棋,多子棋)的实现:c语言相关推荐

  1. 三子棋实现(多子棋实现)

    整体思路: 首先,因为三子棋实现较为复杂,因此需要分模块编写,分为game.c,gsme.h和text.c模块.game.c中存放游戏实现的代码,game.h中存放有关游戏实现的函数声明,text.c ...

  2. 我看你骨骼惊奇,送你本武林秘籍--《三子棋至多子棋的扩展》

    前言: 这篇文章将会手把手带你从程序设计需求出发,用代码思维来实现三子棋游戏. 每一步都会按照这个流程进行 1.要实现什么(程序设计需求) 例如:三子棋的游戏规则 用户的游玩方式 2.怎么实现 代码设 ...

  3. 【C/C++】题解:从三子棋到多子棋

    [C/C++]题解:三子棋延伸为多子棋 导读 该篇文章将会从三子棋延伸到多子棋,介绍如何实现一个多子棋程序,并希望可以体会到如何去设计一个简单的程序,如何去抽象出每个函数模块,掌握编写函数的方法论: ...

  4. C语言实现三子棋及多子棋的制作(初学者)

    游戏的逻辑: 1,首先打印一个菜单供给用户使用,这里使用一个do while循环,通过返回的值来分析玩家玩游戏或者退出. 2,玩家如果选择开始游戏,则进入游戏函数,反之,则退出或者报错. 3,,首先要 ...

  5. c语言实现简单的多子棋游戏

    c语言实现简单的多子棋游戏# 系列文章目录 c语言实现简单的多子棋游戏 前言 *大家好呀!今天我们要探究怎么用c语言实现以三子棋为基础的五子棋.十子棋等等多子棋游戏.游戏对代码的要求不高,只需要学习c ...

  6. 三子棋游戏(支持多子棋)

    目录 前言 一.创建三子棋的思路过程? 二.游戏模块 1.棋盘初始化 2.开始下棋 3.判断输赢 三.测试模块 四.源码 总结 前言 用c语言实现一个三子棋的游戏,当然也可以实现多子棋,修改一点参数即 ...

  7. 三子棋——可修改为多子棋

    三子棋:是一种民间传统游戏,又叫九宫棋.圈圈叉叉.一条龙等.将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了. 本程序可修改为多子棋,只需要修改#def ...

  8. C语言三子棋游戏进阶版详解(包括多子棋)

    目录 一,总体思路介绍 二,具体思路的实现 1.初始化游戏界面 2.初始化棋盘 3.打印棋盘 4.玩家移动 5.电脑移动 6.判断输赢 三,源码展示 game.h game.c test.c 一,总体 ...

  9. 趣味益智小游戏 三子棋+五子棋 优化版(可任意选择棋盘大小)

    前言 今天牛牛给大家分享的是c语言实现三子棋和五子棋游戏,初学者可能有些不理解的地方,记得私信提问哦,牛牛会一 一回答的. 目录 前言 一.游戏介绍 二.游戏设计思路 2.1 主函数测试区(test. ...

最新文章

  1. 文件打包成zip类型文件
  2. 不定长参数的装包与拆包
  3. java长宽_Java:如何控制JPanel长宽比?
  4. 圣剑神域单机版服务器维护,圣剑神域单机版
  5. 统计“3_人民日报语料”文本中的字符数和词数,把文件分别保存为 ansi, UTF8,UTF16,unicode 格式
  6. 什么时候才能都及格呢?
  7. 【CodeForces - 289C】Polo the Penguin and Strings (水题,字符串,思维构造,有坑)
  8. php node.js django,Vue.js和Django搭建前后端分离项目示例详解
  9. html自动年份版权,如何将html5日期输入限制在合理的年份
  10. python 7-24 sdut-array2-2-局部峰值 (10 分)
  11. 如何决定何时使用Node.js?
  12. 中国省级行政区划变动情况
  13. c语言中结构体习题,C语言之结构体练习题
  14. 前端布局 flex布局
  15. javascript nonono
  16. 邓奶奶坐轮椅泪别袁爷爷
  17. 如何理解「朝闻道,夕死可矣」?
  18. J2EE总体的学习计划(百搜技术)
  19. [办公应用]让WORD自动显示到四级目录
  20. 英文歌曲:What I Have Done(变形金刚第一部主题曲)

热门文章

  1. Java对于时间的处理,计算时间差,比较时间,计算时间前后,时间相加
  2. 用Visual C# 2005创建快捷方式
  3. HTTP Host 字段作用
  4. wx引入音频audio组件
  5. 深度学习Week7-好莱坞明星识别(Pytorch)
  6. 计算机设计原理教学反思,教学反思——我是电脑小医生
  7. 基于TI TMS320F2837x系列的单/双核32位浮点MCU控制器+ Xilinx Spartan-6低功耗FPGA核心板
  8. [实战] 朴素贝叶斯分类器进行垃圾邮件过滤
  9. 2021域名争议怎么解决?域名争议由哪个法院管辖?
  10. Sublime Text配置及运行