手把手教你用C语言实现三子棋
目录
- 1.设计简单菜单
- 2.创建棋盘
- 3.下棋过程的实现
- 3.1玩家下棋
- 3.2电脑下棋
- 3.3判断输赢
- 4.游戏源码
- 总结
1.设计简单菜单 相信大家在玩游戏时会发现,进入游戏前会有菜单拱你选择,你可以选择你想要的模式,三子棋也是同样的。
void menu(){ printf("******************************\n"); printf("*********0.play*********\n"); printf("*********1.exit*********\n"); printf("******************************\n"); }int main(){ srand((unsigned)time(NULL)); int input = 0; do {menu(); printf("请选择:\n"); scanf("%d", &input); switch (input){case 0: game(); break; //game()函数是后续用来实现游戏过程的一个函数case 1:printf("退出游戏\n"); break; default:printf("选择错误,请重新选择\n"); break; } } while (input); //while(input)相当于while(input!=0)只要没进入游戏就会一直循环到进入为止 return 0; }
2.创建棋盘 在C语言中我们把下棋的棋子存在二维数组里
char board[ROW][COL];
在下棋前,我们应该保证棋盘上是没有棋子的,所以我们得先初始化棋盘。
void InitBoard(char board[ROW][COL], int row, int col){ int i, j; for (i = 0; i < row; i++) {for (j = 0; j < col; j++){board[i][j] = ' '; } }}
接下来我们要把棋盘打印出来我们才能下
void DisplayBoard(char board[ROW][COL], int row, int col){ int i, j; //打印棋盘 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"); }}
文章图片
这样一个简易的棋盘就打印出来了。(确实简易)
3.下棋过程的实现
3.1玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col){ printf("玩家走:>\n"); int x, y; while (1) {printf("请输入坐标:>\n"); 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"); } }}
3.2电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col){ printf("电脑走:>\n"); while (1) {int x = rand() % row; //0~2 注意放在循环里,保证每一次进来都会产生一个随机数int y = rand() % col; //0~2if (board[x][y] == ' '){board[x][y] = '#'; break; } }}
电脑下棋我就要在这边说明一下了,电脑是通过产生随机数来进行下棋的,那这个随机数怎么产生呢?C语言作为历史比较久的一门语言,早期并没有设计出太多函数,像现在的Python是自带有随机函数的,直接调用就可以产生随机值的,而C语言实现随机数的方式就是时间戳。
那什么是时间戳呢?
时间戳是从1970年1月1日(UTC/GMT的午夜)开始到现在所经过的秒数。当你单独使用rand函数的时候你会发现产生的数确实是随机的,但这个随机是伪随机,即每次随机都是一样的数,而当你用了时间戳就能实现真正的随机,因为时间是时时刻刻在发生变化的。
那应该怎么使用呢?
首先在主函数里你需要这样
srand((unsigned)time(NULL));
这样你的rand函数就变成了真正的随机函数了,这边要注意一点,rand函数一定要放在循环里,保证每次循环都能产生一个随机数,若放在循环外面,则每进一次函数才会产生一次随机值。
到这里整个游戏的实现就圆满完成了。
文章图片
文章图片
真以为这就结束了?想想也没毛病,菜单也设计了,棋盘也打印了,玩家和电脑也实现了,还有什么吗?
文章图片
想不到吧,游戏输赢你还没判断吧。
3.3判断输赢
在判断游戏输赢前还有一个小细节,我们玩家和电脑在下棋时如果棋盘上有子是不是不能下,所以还需要一个判断棋盘是否满了的函数。
int IsFull(char board[ROW][COL], int row, int col){ int i, j; for (i = 0; i < row; i++) {for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0; //棋盘还没满} } return 1; //棋盘满了}
然后就可以进行判断输赢的实现了
char IsWin(char board[ROW][COL], int row, int col){ //行 int i, j; 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 (j = 0; j < col; j++) {if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')return board[0][j]; } //对角线 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')return board[0][0]; else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')return board[0][2]; //平局 if (IsFull(board, ROW, COL))return 'd'; //游戏继续 return 't'; }
到这里整个游戏的逻辑就完美了。(别慌,这次是真的结束了,没有骗你们)
文章图片
接下来附上整个游戏的源码
4.游戏源码 test.c文件
#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"void game(){ //三子棋的过程 char board[ROW][COL]; //初始化棋盘 InitBoard(board, ROW, COL); //打印棋盘 DisplayBoard(board, ROW, COL); //下棋 char ret = IsWin(board, ROW, COL); while (1) {PlayerMove(board, ROW, COL); DisplayBoard(board, ROW, COL); //打印棋盘ret = IsWin(board, ROW, COL); if (ret != 't')break; ComputerMove(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = IsWin(board, ROW, COL); if (ret != 't')break; } if (ret == 'd')printf("平局"); else if (ret == '*')printf("玩家赢"); else if (ret == '*')printf("电脑赢"); }void menu(){ printf("******************************\n"); printf("*********0.play*********\n"); printf("*********1.exit*********\n"); printf("******************************\n"); }int main(){ srand((unsigned)time(NULL)); int input = 0; do {menu(); printf("请选择:\n"); scanf("%d", &input); switch (input){case 0: game(); break; case 1:printf("退出游戏\n"); break; default:printf("选择错误,请重新选择\n"); break; } } while (input); return 0; }
game.c文件
#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"void InitBoard(char board[ROW][COL], int row, int col){ int i, j; for (i = 0; i < row; i++) {for (j = 0; j < col; j++){board[i][j] = ' '; } }}void DisplayBoard(char board[ROW][COL], int row, int col){ int i, j; //打印棋盘 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 PlayerMove(char board[ROW][COL], int row, int col){ printf("玩家走:>\n"); int x, y; while (1) {printf("请输入坐标:>\n"); 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 ComputerMove(char board[ROW][COL], int row, int col){ printf("电脑走:>\n"); while (1) {int x = rand() % row; //0~2 注意放在循环里,保证每一次进来都会产生一个随机数int y = rand() % col; //0~2if (board[x][y] == ' '){board[x][y] = '#'; break; } }}int IsFull(char board[ROW][COL], int row, int col){ int i, j; for (i = 0; i < row; i++) {for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0; //棋盘还没满} } return 1; //棋盘满了}char IsWin(char board[ROW][COL], int row, int col){ //行 int i, j; 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 (j = 0; j < col; j++) {if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')return board[0][j]; } //对角线 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')return board[0][0]; else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')return board[0][2]; //平局 if (IsFull(board, ROW, COL))return 'd'; //游戏继续 return 't'; }
game.h
#pragma once#include#include#include#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);
总结 【手把手教你用C语言实现三子棋】本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- 慢慢的美丽
- 遇到一哭二闹三打滚的孩子,怎么办┃山伯教育
- 2.6|2.6 Photoshop操作步骤的撤消和重做 [Ps教程]
- “成长”读书社群招募
- 石头巷;名垂青史的廉政教材
- 每日一话(49)——一位清华教授在朋友圈给大学生的9条建议
- 历史教学书籍
- 二十年后的家乡
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 唱歌教学(导致嗓音损坏的几个常见的错误唱歌方法!)