时间:2022-03-13 12:55:40 | 栏目:C代码 | 点击:次
本文实例为大家分享了C语言实现三子棋(井字棋)小游戏的具体代码,供大家参考,具体内容如下
推荐阅读顺序(不建议跳过)
先看实现之后的界面 ―― 然后看分析程序要实现的步骤 ―― 之后在看翻到test.c部分 ―― 在test.c中找到main()函数 ―― 从main函数的第一步开始看 ―― 遇到自定义函数请到game.h源文件中找到相应函数的详情
辅助阅读:
game.h文件中放的是函数的声明(引用头文件)
game.c文件中放的是函数的详情(怎么用代码实现相应步骤的)
test.c文件中放的是整体的大致思路
用不同文件分装代码是为了:能够让自己的代码更有条理,思路更加的清晰,别人也更容易看懂
如果觉得翻来翻去太过于麻烦:请登录自己现在所用的编译器 ―― 把代码先拷贝一份(按照不同的文件分装) ―― 遇到自定义函数(把鼠标放在函数名上面、右击、转到定义)(这样编译器可以直接转到game.c文件中的函数详情)
实现之后的的界面
分析程序要实现的步骤
1、在屏幕上打印菜单(提示你要选择的内容)
2、定义数组,初始化数组(把数组中的元素全替换成空格)
3、把数组打印出来
4、玩家下棋
5、判断输赢(四种情况:玩家赢、玩家输、平局、游戏未结束,继续)
6、电脑下棋
7、判断输赢(四种情况:玩家赢、玩家输、平局、游戏未结束,继续)
8、可以多次玩这个游戏
test.c(源文件)
用于放整体的大致思路,自定义函数放在game.h文件中
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void menu() { printf("+-------------------------------------+\n"); printf("| 1.玩游戏 |\n"); printf("| 0.退出游戏 |\n"); printf("+-------------------------------------+\n"); } void game() { //定义棋盘数组 //其中 Hang和Lie 是define定义的标识符常量 ―― 在game.h文件中可以找到 //Hang表示有几行 ―― Lie表示有几列 char board[Hang][Lie]; char ret = ' '; //初始化棋盘数组 //传入三个变量,数组首元素地址,行,列 //在game.h中声明这个函数,在game.c中实现这个函数,完成以上两步在这里直接使用就可以了 init_board(board, Hang, Lie); //进入这个函数――跳转到game.c文件,代码上方注释有1的部分 //打印棋盘的界面 ―― 把棋盘显示出来 ―― 进入这个函数――跳转到game.c文件,代码上方注释有2的部分 checker_board(board, Hang, Lie); while (1) { //玩家走―― 进入这个函数――跳转到game.c文件,代码上方注释有3的部分 player_move(board, Hang, Lie); checker_board(board, Hang, Lie); //判断输赢 ―― 进入这个函数――跳转到game.c文件,代码上方注释有5的部分 ret = win_or_lose(board, Hang, Lie); if (ret != 'C') { break; } //电脑走 ―― 进入这个函数――跳转到game.c文件,代码上方注释有4的部分 computer_move(board, Hang, Lie); checker_board(board, Hang, Lie); //判断输赢 ret = win_or_lose(board, Hang, Lie); if (ret != 'C') { break; } } if (ret == 'Q') { printf("平局\n"); } if (ret == '*') { printf("恭喜你:赢\n"); } if (ret == '#') { printf("很遗憾:你输了\n"); } } int main() { int input = 0; srand((unsigned int)time(NULL)); //生成随机数要用到rand() //用rand()要调用srand() //srand()其中()中要用到不断变化的量 ―― 用时间戳来做不断变化的量 ―― 时间戳可以用time()函数来实现 //(unsigned int) ―― 是强制类型转换 //srand()函数不用引用多次,所以放在循环的前面就可以了 //这个生成随机数我在前面一篇博文中也讲了,如果不明白也可以去上篇博文看一下 do { menu(); //打印简单的菜单界面(这个函数不用去game.c文件中去找,就在这个文件的上方) printf("请输入选项前面的序号>:"); scanf("%d", &input); switch (input) //switch选择语句是实现:输入1玩游戏,输入0退出游戏,输入其他数提示输入错误。 { case 1: //game()自定义函数 --- 在这个函数里面实现三子棋游戏 ―― 主要的设计思路都在这个函数中 //这个函数也在这个文件的上方,不用去game.c文件中找 game(); //进入函数 break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); return 0; }
game.h(头文件)
放函数的声明(引用头文件)
#pragma once #include<stdio.h> #include<time.h> #include<stdlib.h> #define Hang 3 #define Lie 3 //初始化棋盘,把棋盘中的数变成空格; void init_board(char board[Hang][Lie], int hang, int lie); //打印期棋盘,显示棋盘状态; void checker_board(char board[Hang][Lie], int hang, int lie); //玩家走 void player_move(char board[Hang][Lie], int hang, int lie); //电脑走 void computer_move(char board[Hang][Lie], int hang, int lie); //判断输赢 char win_or_lose(char board[Hang][Lie], int hang, int lie);
game.c (源文件)
放函数详情(怎么用代码实现相应步骤的)
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" //1111111111 //把数组中的数初始化成空格 void init_board(char board[Hang][Lie], int hang, int lie) { int i = 0; for (i = 0; i < hang; i++) { int j = 0; for (j = 0; j < lie; j++) { board[i][j] = ' '; } } } //2222222222 //打印棋盘 void checker_board(char board[Hang][Lie], int hang, int lie) { int i = 0; for (i = 0; i < hang; i++) { int j = 0; for (j = 0; j < lie; j++) //打印第一行棋盘 { printf(" %c ", board[i][j]); if (j < lie - 1) { printf("|"); } } printf("\n"); if (i < hang - 1) { for (j = 0; j < lie; j++) { printf("---"); if (j < lie - 1) { printf("|"); } } } printf("\n"); } } //3333333333 //玩家输入 ―― 判断玩家输入的坐标 //如果超过数组范围,显示输入错误,请重新输入 //如果下棋的位置已经被占用,显示坐标错误 void player_move(char board[Hang][Lie], int hang, int lie) { int x = 0; int y = 0; printf("请输入你所要下的位置坐标:"); while (1) //这个循环结束的条件是:玩家输入正确的 { scanf("%d %d", &x, &y); //玩家输入坐标 if (x > 0 && x <= hang && y > 0 && y <= lie) { if (board[x - 1][y - 1] == ' ') //输入数正确 { board[x - 1][y - 1] = '*'; break; } else //输入数对应的坐标已被占用 { printf("坐标错误:"); } } else //输入数超出数组范 { printf("输入错误请重新输入:"); } } } //4444444444 //电脑走 void computer_move(char board[Hang][Lie], int hang, int lie) { int hangs = 0; int lies = 0; printf("电脑走:\n"); while(1) //这个循环结束的条件是:直到执行随机坐标正确(没有被占用) { //生产随机坐标 int hangs = rand() % hang; int lies = rand() % lie; if (board[hangs][lies] == ' ') //判断坐标是否被占用 { board[hangs][lies] = '#'; break; } } } //5555555555 //判断4种状态; //1、玩家赢,返回* //2、电脑赢, 返回# //3、平局 返回Q //4、继续 返回C char win_or_lose(char board[Hang][Lie], int hang, int lie) { int i = 0; int j = 0; int count = 0; //以下判断是电脑赢还是玩家赢 //赢(8中情况)得条件:一行三个都相同 或者 一列三个都相同 或者 对角线相同 for (i = 0; i < hang; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ') { return board[i][0]; } 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]; } //以下是判断是不是平局 //平局条件:数组中没有空格(都被占满了) 并且 已经判断出来玩家电脑都没赢 for (i = 0; i < hang; i++) { for (j = 0; j < lie; j++) { if (board[i][j] == ' ') { count++; } } } if (count == 0) { return 'Q'; } //不是平局,不是电脑赢,不是玩家赢,剩下的就是继续玩 return 'C'; }