C语言实现三子棋(胎教版教学)由浅入深
【摘要】 快来用C语言实现你的第一个项目把!教你一步步构建多文件形式的三子棋
@TOC
三子棋介绍
三子棋 是一种民间传统游戏,又叫九宫棋、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利。
确定步骤开始配置文件
我们选择的是用多文件的形式教大家独立完成,三子棋游戏的实现
首先我们要准备三个文件分别是 game.h 来声明函数 game.c 来实现函数的定义 test.c 大体的文件架构就完成了
游戏代码的实现
步骤一、确定文件主体test.c的几个部分
- 一、游戏的菜单来确定是否开始和退出
输入1为开始游戏输入0为退出游戏
#include “game.h”//由于我们要调用game.h头文件所以其他需要的头文件
//就全部放在game.h里面避免代码冗余,让代码更加简洁
//菜单
void menu()
{
printf("************************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("************************\n");
}
int main()
{
int input = 0; //创建变量来接收输入的结果
do
{
//打印菜单
menu();
printf("请输入你的选择 >");
scanf("%d",&input);
switch (input)
{
//开始游戏
case 1:
game();//这里先写出游戏函数后面实现
break;
//退出游戏
case 0:
printf("退出游戏!\n");
break;
default:
printf("输入错误,请重新输入!");
break;
}
} while (input);
return 0;
}
1、编写 game() 函数的主体
- 1、棋盘的初始化
- 2、打印棋盘
- 3、玩家下棋 棋子用 * 表示
- 4、电脑下棋 棋子用 # 表示
- 5、判断输赢
- 玩家赢返回 *****
- 电脑赢返回 #
- 平局返回 Q
- 继续返回 C
1、棋盘的初始化
观察棋盘三子棋盘是3×3的所以我们用3×3的数组存储棋子并完成初始化
void game()//三子棋游戏主体函数
{
char board[ROW][COL] = {0};
//初始化数组
InitBoard(board, ROW, COL);
}
在这里插入代码片
然后先创建实现5个小功能的函数后面再调用
//三子棋游戏
void game()
{
char board[ROW][COL] = {0};
//初始化数组
InitBoard(board, ROW, COL);
char ret = 0;//用来接收输赢函数返回的 值
char play = 0;//用来接收下棋坐标被占用的返回值
//打印棋盘
DisplayBoard(board, ROW, COL);
while (1)//创建一个循环只要没有人赢就一直下
{
//玩家下棋
play = PlayMove(board, ROW, COL);
if (play == 'P')//当下棋时坐标输入错误和坐标被占用就退出循环
continue;//不让电脑下棋
//判断输赢
ret = IsWin(board, ROW, COL);//接收每次判断的结果
if (ret != 'C')//当返回的不是 C 继续的话就退出说明有人赢了
{
system("cls");//退出时清空所有棋盘并打印一遍
//打印棋盘
DisplayBoard(board, ROW, COL);
break;
}
//打印棋盘
DisplayBoard(board, ROW, COL);
//电脑下棋
ComputerMove(board, ROW, COL);
system("cls");//每次下完棋后清空屏幕所有内容并打印一遍棋盘
//打印棋盘 //让每次屏幕上只有一个棋盘
DisplayBoard(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')//当返回的不是 C 继续的话就退出说明有人赢了
{ //就进入if里面结束本次循环
system("cls");//退出时清空所有棋盘并打印一遍
//打印棋盘
DisplayBoard(board, ROW, COL);
break;
}
}
if (ret == '*')
{
printf("玩家赢!\n");
}
else if (ret == '#')
{
printf("电脑赢!\n");
}
else
{
printf("平局!\n");
}
}
步骤二、game.h 头文件的声明
前面已经把游戏拆成了5个小部分接下来就是声明和定义了
- 声明和经常使用的头文件,我们把它都放在 game.h 的头文件里
#pragma once
#include <stdio.h> //输入输出头文件
#include <stdlib.h> //获取随机函数头文件 后面会用
#include <time.h> //srand函数所需要获取时间戳的头文件 后面会用
#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);
//玩家下棋
int PlayMove(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);
//平局
int IsFull(char board[ROW][COL], int row, int col);
步骤三、game.c 的函数实现
各种函数名和 函数声明 我们已经完成了接下来就是在 game.c 里面实现这些小功能
#include "game.h"//先在game.c里面调用
//在game.h里面声明的头文件和函数
1、初始化棋子数组函数的实现
用循环遍历数组的棋子使里面存放的都是空格
//初始化数组
void InitBoard(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] = ' ';
}
}
}
2、打印棋盘函数的实现
观察棋盘发现 分为2个部分组成
- 第一部分是 (空格 棋子 空格 | 空格 棋子 空格 | 空格 棋子 空格)
- 第二部分是 (- - - | - - - | - - -)而每个部分都要输出三次
所以我们用for循环来写
| 每行只有俩个所以要写个if判断
//打印棋盘
void DisplayBoard(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");
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
3、玩家下棋函数的实现
这边接收的是玩家输入的坐标 一般是1 开始 到 3
但是数组下标是从0开始所以把每次玩家输入的行和列 - 1 就好了
//玩家下棋
int PlayMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋");
printf("请输入坐标,中间用空格隔开 ->");
scanf("%d %d",&x,&y);
//检查坐标是否合法
if (x >= 1 && y >= 1 && x <= row && y <= col )
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
}
else
{
printf("坐标被占用请重新输入!\n");
return 'P';
}
}
else
{
printf("输入错误请重新输入!\n");
return 'P';
}
}
4、电脑下棋函数的实现
我们让电脑每次产生随机数坐标 产生行和列 来下棋
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
//随机下棋
int x = 0;
int y = 0;
printf("电脑下棋:>\n");
while (1)
{
x = rand() % row;//产生的随机数模除我们需要的行 产生的数就在行0~3之内了
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
5、判断输赢函数的实现
//玩家赢返回 *
//电脑赢返回 #
//平局返回 Q
//继续返回 C
char IsWin(char board[ROW][COL], int row, int col)
{
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][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];
//判断平局
if (IsFull(board, row, col) == 1)
{
return 'Q';
}
else
{
return 'C';
}
//继续 C
}
6、判断平局函数的实现
遍历一遍数组当数组里面存放的没有空格就说明棋盘满了 平局
//平局
int IsFull(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++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
整体代码如下:
test.c代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
// 菜单
void menu()
{
printf("************************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("************************\n");
}
//三子棋游戏
void game()
{
char board[ROW][COL] = {0};
//初始化数组
InitBoard(board, ROW, COL);
char ret = 0;
char play = 0;
//打印棋盘
DisplayBoard(board, ROW, COL);
while (1)
{
//玩家下棋
play = PlayMove(board, ROW, COL);
if (play == 'P')
continue;
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
system("cls");
//打印棋盘
DisplayBoard(board, ROW, COL);
break;
}
//打印棋盘
DisplayBoard(board, ROW, COL);
//电脑下棋
ComputerMove(board, ROW, COL);
system("cls");
//打印棋盘
DisplayBoard(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
system("cls");
//打印棋盘
DisplayBoard(board, ROW, COL);
break;
}
}
if (ret == '*')
{
printf("玩家赢!\n");
}
else if (ret == '#')
{
printf("电脑赢!\n");
}
else
{
printf("平局!\n");
}
}
int main()
{
int input = 0;
do
{
srand((unsigned int)time(NULL));
//打印菜单
menu();
printf("请输入你的选择 >");
scanf("%d",&input);
switch (input)
{
//开始游戏
case 1:
game();
break;
//退出游戏
case 0:
printf("退出游戏!");
break;
default:
printf("输入错误,请重新输入!");
break;
}
} while (input);
return 0;
}
game.h代码
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdlib.h>
#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);
//玩家下棋
int PlayMove(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);
//平局
int IsFull(char board[ROW][COL], int row, int col);
game.c代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//初始化数组
void InitBoard(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 DisplayBoard(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");
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
//玩家下棋
int PlayMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋");
printf("请输入坐标,中间用空格隔开 ->");
scanf("%d %d",&x,&y);
//检查坐标是否合法
if (x >= 1 && y >= 1 && x <= row && y <= col )
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
}
else
{
printf("坐标被占用请重新输入!\n");
return 'P';
}
}
else
{
printf("输入错误请重新输入!\n");
return 'P';
}
}
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
//随机下棋
int x = 0;
int y = 0;
printf("电脑下棋:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//玩家赢 *
//电脑赢 #
//平局 Q
//继续 C
char IsWin(char board[ROW][COL], int row, int col)
{
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][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];
//判断平局
if (IsFull(board, row, col) == 1)
{
return 'Q';
}
else
{
return 'C';
}
//继续 C
}
//平局
int IsFull(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++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)