c语言小项目 三子棋
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:C语言学习,记录自己学习的过程,感谢批评指正
一、整体思路
首先我的目标是设计一个 三子棋游戏,其中包含棋盘打印、人机对战、结果判断这三个基础功能,整体用字符数组进行数据承载。 然后对目标进行拆分实现: 棋盘打印,利用循环输出九宫格输出的九宫格 人机对战,玩家输入坐标,程序进行判断,是否合法,是否被占用,随后进行赋值。 电脑利用 srand((unsigned int)time(NULL)); 生成随机坐标,这里利用取模来限制随机数范围x = rand() % row; ,合理判断后,进行赋值。 结果判断,电脑和玩家每下一次进行一次判断,实质是判断数组内容,横行,竖列,对角线。产生四种判断结果,玩家赢、电脑赢、平局、继续。根据不同的情况返回特定的符号,进行输出。
二、具体实现
项目创建,利用多文件。当程序代码较长时,利用多文件写的时候思路会更清晰,方便之后的维护。 通常我分为: 测试文件test.c ,函数声明game.h ,函数实现game.c 。
1.整体代码及分析
首先是测试文件的书写,这是函数的整体架构,直接出在屏幕上,和用户直接进行接触的代码。
test.c
引入头文件
#include"game.h"
菜单导航void menu()
void menu()
{
printf("**************************\n");
printf("****1. play 0. exit****\n");
printf("**************************\n");
}
游戏实现void game()
void game()
{
char ret = 0;
char board [row][col] = { 0 };
InitBoard(board, row, col);
DisplayBoard(board, row, col);
while (1)
{
PlayerMove(board, row, col);
DisplayBoard(board, row, col);
ret=IsWin(board, row, col);
if (ret != 'C')
{
break;
}
ComputerMove(board, row, col);
DisplayBoard(board, row, col);
ret=IsWin(board, row, col);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("玩家赢\n");
}
if (ret == '@')
{
printf("电脑赢\n");
}
if(ret=="Q")
{
printf("平局\n");
}
}
整体测试void test() 根据用户的选择,执行菜单里的功能
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
printf("三子棋游戏\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
}
整体测试(主函数)int main()
int main()
{
test();
return 0;
}
其次书写函数声明:
game.h
引入头文件
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
函数声明
void InitBoard(char board[row][col], int r, int c);
void DisplayBoard(char board[row][col], int r, int c);
void PlayerMove(char board[row][col], int r,int c);
void ComputerMove(char board[row][col], int r, int c);
char IsWin(char board[row][col], int r, int c);
函数实现
game.c
头文件引入
#include"game.h"
棋盘创建函数
void InitBoard(char board[row][col], int r, int c)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
棋盘打印函数
void DisplayBoard(char board[row][col], int r, int c)
{
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");
}
}
玩家回合 获取俩个坐标,进入while循环,如果出现 坐标下数组为空的情况,下棋,跳出循环。否者继续。
void PlayerMove(char board[row][col], int r, int c)
{
int x = 0;
int y = 0;
printf("玩家回合:>\n");
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");
}
}
}
电脑回合 声明srnad()函数,用time(NULL)为参数,强转成 unsingend int 。 随机生成两个数,运用取余,使随机数落入限定范围。 While循环 ,判断生成的坐标是否已被占用,若没有,下棋,跳出循环。
void ComputerMove(char board[row][col], int r, int c)
{
int x = 0;
int y = 0;
printf("电脑回合:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '@';
break;
}
}
}
判断棋盘是否满了 0-没满 1-满了
int IsFull(char board[row][col], int r, int c)
{
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;
}
胜负判断 定义IsWin()函数,返回四种状态。1.玩家赢 2.电脑赢 3.平局 4.继续 如果不为继续,者出其他三个结果。 实质判断数组内容。横竖斜
char IsWin(char board[row][col], int r, int c)
{
int i = 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];
if (1 == IsFull(board, row, col))
{
return 'Q';
}
return 'C';
}
2.知识Tips
代码如下(示例):
1.srand((unsigned long)time(NULL)) 函数,通常与rand() 放在一起使用。 在C语言中位于<stdlib.h>头文件文件中。 原型:void srand(unsigned int seed) 原型:void rand(void) seed相当于一个种子,srand函数根据这个种子seed,设置一个随机的起点,rand函数就根据这个起点,返回一个随机数[seed , RAND_MAX]。 默认srand(1) 初始化rand() 值。为了让每一次程序的调用都产生不同的值,所以经常使用系统时间来初始化,也就是time(NULL)。 2.#define 定义数组大小,方便代码复用。 3.#define _CRT_SECURE_NO_WARNINGS 1 解决unsafe问题。 暂时方案:直接添加 永久解决:通过安装路径找到newc++file.cpp 文件,使用notpad++打开,添加。
总结
整个代码写下来,说一下我的感受。 把整个问题拆成 测试、声明、实现三个文件去写,我感觉整个问题都变得简单了,思路越写越清晰。丝毫不会随着整个代码的增多而混乱,在局部代码改进升级上很方便,没有相互影响。 这篇博客整体写下来,对我的思路又进行了一编梳理,对这种方法又进行了巩固。 当然适合自己的才是最好的,希望看到此篇博客的你能有所收获。**点赞的你无比帅气。**
|