C语言·三子棋(具体步骤和代码)
2022/1/30 23:05:54
本文主要是介绍C语言·三子棋(具体步骤和代码),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录
前言
一、文件分配
二、菜单界面
三、棋盘初始化
四、打印棋盘
样子
五、玩家落子
下棋
六、电脑下棋
七、判断胜负
八、核心代码
总代码
game.h
game.c
text.c
游戏的结果
玩家赢
电脑赢
平局
前言
利用函数,分支和循环语句,数组,多文件实现。
棋盘:使用3行3列的二维数组以(" ")来表示;
玩家:利用填写行列实现以(" * ")下棋;
电脑:利用时间挫产生随机值实现以(" # ")下棋;
一、文件分配
game.c 用于游戏的实现
text.c 用于游戏的检测
game.h 用于游戏的函数引用,库函数的引用(将库函数的引用都放于头文件之中,这样可以使得代码不至于过于臃肿)
(介于game.h是作为引用,主要实现游戏以及检测游戏。text.c是用于游戏的检测;所以,必要时才展示)
二、菜单界面
使用do while循环的原因:
- 提高简洁性,我们所需要的,只是当不玩时即退出,输入错误即重新输入,而利用非0即对,0即错的性质,可简洁实现。
//游戏目录 void text() { int input = 0; do { mune(); printf("请选择->"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); } //执行入口 int main() { text(); return 0; }
//游戏首页 void mune() { printf("************************************\n"); printf("********** 1 play **********\n"); printf("************************************\n"); printf("********** 0 exit **********\n"); printf("************************************\n"); }
三、棋盘初始化
//初始化棋盘 char board[ROW][COL] = { 0 }; int i = 0, j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { board[i][j] = ' '; } }
四、打印棋盘
使用define定义常量的原因:
- 提高扩展性,如果将来要修改棋盘尺寸,代码修改会很方便,只需修改此一处。
#define ROW 3 //行 #define COL 3 //列
最直接的方法,可以实现,但是不够好。
//打印棋盘 void dis_printf(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"); } }
使用逐一打印的原因:
- 提高扩展性,当更改define定义常量后,正确的打印出棋盘。
- 提高实用性,使其不仅仅只能适用于三子棋,代码就要越完美越好,可实现多条件下的执行,不是仅仅满足当前。
//打印棋盘 void dis_printf(char board[ROW][COL],int row,int col) { int j = 0; int i = 0; for (i = 0; i < row; i++) { 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"); } } }
样子
五、玩家落子
注意:玩家不是程序员,我们不能要求别人会C语言的数组,玩家只会以1起数而不是0,所以我们需要对,行列皆减1。
//玩家下棋(*) void play_game(char board[ROW][COL],int row,int col) { int x = 0; int y = 0; while (1) { printf("请下棋->"); scanf("%d %d", &x, &y); x--; y--; if (x >= 0 && x <= row && y >= 0 && y <= col) { if (board[x][y] == ' ') { board[x][y] = '*'; break; } else { printf("已经有棋,请重新下载\n"); } } else { printf("输入错误请重新输入\n"); } } }
下棋
六、电脑下棋
需注意:我们的棋盘是由限制的,所以随机生成的数值需要利用 " %行列 "以规定范围。
//电脑下棋(#) void computer_printf(char board[ROW][COL],int row, int col) { int x = 0; int y = 0; srand((unsigned int)time(NULL)); while(1) { x = rand() % row;//0~2 y = rand() % col;//0~2 if (board[x][y] == ' ') { board[x][y] = '#'; break; } } }
七、判断胜负
此处约定返回结果的含义:
(1)‘*’ 表示玩家获胜
(2)‘#’ 表示电脑获胜
(3)0表示胜负未分
(4) 1 表示和棋
此处的小聪明:我们让玩家赢与电脑赢都是返回其棋子的样子,这是便于返回,可以显得代码不会过于臃肿。
//判断结果 //如果,继续就返回0,平局就返回1,如果电脑赢就返回#,如果玩家赢就返回*. int end_game(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; //判断行 for (i = 0; i < row; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ') { return board[i][1]; } } //判断列 for (i = 0; i < col; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ') { return board[1][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]; } //判断是否继续或平局 for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ')//判断是否棋局是否还有空格 return 0; } } return 1; }
八、核心代码
我们知道,下棋是玩家与电脑回合制,不达到一家赢或平局,是不会停止的,所以我们需要创建几个一直正确的循环,然后,利用break语句跳出循环!
所以就有了以下的代码组合。
void game() { //初始化棋盘 char board[ROW][COL] = { 0 }; int i = 0, j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { board[i][j] = ' '; } } //打印棋盘 dis_printf(board, ROW, COL); int ret = 0; while (1) { //玩家下棋 printf("玩家下棋\n"); play_game(board, ROW, COL); //判断结果 ret = end_game(board, ROW, COL); if (ret != 0) { break; } //打印棋盘 dis_printf(board, ROW, COL); //电脑下棋 printf("电脑下棋\n"); computer_printf(board, ROW, COL); //判断结果 ret = end_game(board, ROW, COL); if (ret != 0) { break; } //打印棋盘 dis_printf(board, ROW, COL); } ret = end_game(board, ROW, COL); if (ret == '*') { printf("玩家赢\n"); } if (ret == '#') { printf("电脑赢\n"); } if (ret == 1) { printf("平局\n"); } }
只需要在玩家与电脑后放上一个if语句,判断只要不是继续游戏,就跳出循环,然后,在循环外判断谁赢,是否平局,这样只需要写这一次判断的代码,这样可以避免代码的臃肿。
总代码
game.h
#pragma once //用于游戏的函数引用,头文件的说明 #include <stdio.h> #include <stdlib.h> #include <time.h> #define ROW 3 //行 #define COL 3 //列 //首页 void mune(); //游戏 void game(); //打印棋盘 void dis_printf(char board[ROW][COL],int row,int col); //玩家下棋 void play_game(char board[ROW][COL], int row, int col); //电脑下棋 void computer_printf(char board[ROW][COL], int row, int col); //判断结果 int end_game(char board[ROW][COL], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" //用于游戏的实现 //游戏首页 void mune() { printf("************************************\n"); printf("********** 1 play **********\n"); printf("************************************\n"); printf("********** 0 exit **********\n"); printf("************************************\n"); } //打印棋盘 void dis_printf(char board[ROW][COL],int row,int col) { int j = 0; int i = 0; for (i = 0; i < row; i++) { 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 play_game(char board[ROW][COL],int row,int col) { int x = 0; int y = 0; while (1) { printf("请下棋->"); scanf("%d %d", &x, &y); x--; y--; if (x >= 0 && x <= row && y >= 0 && y <= col) { if (board[x][y] == ' ') { board[x][y] = '*'; break; } else { printf("已经有棋,请重新下载\n"); } } else { printf("输入错误请重新输入\n"); } } } //电脑下棋(#) void computer_printf(char board[ROW][COL],int row, int col) { int x = 0; int y = 0; srand((unsigned int)time(NULL)); while(1) { x = rand() % row;//0~2 y = rand() % col;//0~2 if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } //判断结果 //如果,继续就返回0,平局就返回1,如果电脑赢就返回#,如果玩家赢就返回*. int end_game(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; //判断行 for (i = 0; i < row; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ') { return board[i][1]; } } //判断列 for (i = 0; i < col; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ') { return board[1][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]; } //判断是否继续或平局 for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ')//判断是否棋局是否还有空格 return 0; } } return 1; }
text.c
#define _CRT_SECURE_NO_WARNINGS 1 //用于游戏的检测 #include "game.h" void game() { //初始化棋盘 char board[ROW][COL] = { 0 }; int i = 0, j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { board[i][j] = ' '; } } //打印棋盘 dis_printf(board, ROW, COL); int ret = 0; while (1) { //玩家下棋 printf("玩家下棋\n"); play_game(board, ROW, COL); //判断结果 ret = end_game(board, ROW, COL); if (ret != 0) { break; } //打印棋盘 dis_printf(board, ROW, COL); //电脑下棋 printf("电脑下棋\n"); computer_printf(board, ROW, COL); //判断结果 ret = end_game(board, ROW, COL); if (ret != 0) { break; } //打印棋盘 dis_printf(board, ROW, COL); } ret = end_game(board, ROW, COL); if (ret == '*') { printf("玩家赢\n"); } if (ret == '#') { printf("电脑赢\n"); } if (ret == 1) { printf("平局\n"); } } void text() { int input = 0; do { mune(); printf("请选择->"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); } int main() { text(); return 0; }
游戏的结果
(可惜就是因为电脑随机下,就显得电脑特别特别笨……,所以电脑赢难,平局更难……)
玩家赢
电脑赢
平局
这篇关于C语言·三子棋(具体步骤和代码)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享
- 2024-11-22ansible 的archive 参数是什么意思?-icode9专业技术文章分享
- 2024-11-22ansible 中怎么只用archive 排除某个目录?-icode9专业技术文章分享
- 2024-11-22exclude_path参数是什么作用?-icode9专业技术文章分享
- 2024-11-22微信开放平台第三方平台什么时候调用数据预拉取和数据周期性更新接口?-icode9专业技术文章分享
- 2024-11-22uniapp 实现聊天消息会话的列表功能怎么实现?-icode9专业技术文章分享
- 2024-11-22在Mac系统上将图片中的文字提取出来有哪些方法?-icode9专业技术文章分享
- 2024-11-22excel 表格中怎么固定一行显示不滚动?-icode9专业技术文章分享
- 2024-11-22怎么将 -rwxr-xr-x 修改为 drwxr-xr-x?-icode9专业技术文章分享
- 2024-11-22在Excel中怎么将小数向上取整到最接近的整数?-icode9专业技术文章分享