🌈前言
三子棋小游戏:
1、收获快乐
:
- 学习的过程是枯燥无味的,如果在学习中寻找到乐趣,让自己爱上学习,那么你会轻而易举的收获满满,并且你会因此感到高兴与快乐,甚至你会很幸福且沉迷于学习的乐趣中去。
2、收获知识
:
- 学会如何
组织大型代码
,学习分文件编写。 - 复习数组、函数、循环…等知识。
为了让逻辑
看起来更加清晰,我们这次创建了3个文件
来编写。
- 头文件
game.h
用于存放需要用到的函数的头文件
、自定义函数的声明
和预处理信息
。 game.c
文件用于编写在game.h中自定义函数的具体定义
。test.c
文件用于测试游戏的逻辑。
游戏实现:
🏆三子棋游戏规则
在控制台上输入下棋的坐标,玩家输出“*
”在棋盘上,电脑输出“#
”在棋盘上,只要在棋盘上的列或横或对角线
上连成3个
字符组成的一条线,系统就判断为胜方
。
🎢制作步骤
【1】、编写test.c文件
1、编写main函数
- 因为我们至少要进入一次游戏,所以用
do... ...while
循环来搭建游戏框架 - 用switch语句来完成游戏选项功能,选择
1
,则调用game函数进入游戏;选择0
,则退出游戏。
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
system("cls");
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏!\n");
break;
default:
printf("输入非法,请重新选择!\n");
break;
}
} while (input);
return 0;
}
2、编写game函数
- game函数是
实现游戏运行
的函数。 - 首先调用InitBoard函数(初始化棋盘)
- 再调用DisplayBoard函数(打印棋盘)
- 之后进入while循环,分别调用PlayerMove函数(玩家下棋),ComputerMove函数(电脑下棋),Iswin函数(判断胜负)。
void game()
{
int ret = 0;
char board[ROW][COL] = { 0 };
InitBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
while (1)
{
PlayerMove(board,ROW,COL);
system("cls");
DisplayBoard(board, ROW, COL);
ret = Iswin(board, ROW, COL);
if (ret != 'C')
{
break;
}
ComputerMove(board, ROW, COL);
system("cls");
DisplayBoard(board, ROW, COL);
ret = Iswin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
system("cls");
printf("恭喜,玩家赢了!\n");
}
else if (ret == '#')
{
system("cls");
printf("很遗憾,电脑赢了!\n");
}
else if (ret == 'Q')
{
system("cls");
printf("平局!\n");
}
DisplayBoard(board, ROW, COL);
}
【2】、编写game.c文件
1、打印菜单
在进入游戏前,我们需要让玩家通过菜单来选择开始游戏或退出游戏。
菜单设置包括:
- 1.开始游戏
- 0.退出游戏
- 其他数字返回提示输入错误
void menu()
{
printf("*******************************\n");
printf("* 趣味三子棋 V1.0 *\n");
printf("*******************************\n");
printf("* >1、play *\n");
printf("* >0、exit *\n");
printf("*******************************\n");
}
2、初始化棋盘
在开始游戏前,我们需要将棋盘中的元素都设置为空格。
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] = ' ';
}
}
}
3、打印棋盘
完成棋盘初始化后,我们需要将初始化后的棋盘打印到控制台上。
棋盘的整体布局:
空格
:用空格来显示可以下棋的位置。- 分隔符
|
和- - - +
:用来对棋盘进行分割。 - 用数字标明行和列的坐标。
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
//打印第一行的坐标
printf(" ");//打印空格是为了对齐
for (i = 1; i <= row; i++)
{
printf("%3d ", i);//一个数据行的格子占3个位置
}
printf("\n");
for (i = 0; i < row; i++)
{
printf("%2d", i + 1);//打印第一列的坐标
printf(" ");
for (j = 0; j < col; j++) //打印格子
{
printf(" %c ", board[i][j]);
if (j < col - 1) {
printf("|");
}
}
printf("\n");
if (i < row - 1)//打印分隔符
{
printf(" +");//对齐
for (j = 0; j < row; j++)
{
printf("---+");
}
printf("\n");
}
}
}
4、玩家下棋
- 思路:
- 玩家下棋的操作为输入要下位置的坐标,按回车键即可。但需要
注意
的是,数组下标是从0开始的,因此要对玩家输入的坐标进行转换。例如:玩家输入(1,2)坐标,将(1,2)坐标分别减1,得到对应的数组坐标(0,1)。 - 玩家输入坐标后,判断该坐标是否为空格,若是,则坐标位置标为
*
,并退出让电脑操作;若不是空格,则提示坐标位置被占用,请重新输入! ;若输入坐标超出棋盘范围,则提示坐标非法,请重新输入!**
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家下棋:>");
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");
}
}
}
5、电脑下棋
- 思路:
- 电脑为
自动下棋
,不需要手动输入坐标。 - 电脑自动下棋利用
srand
,rand
,time.h
函数来完成相关操作。 - 随机值取值范围应在0~2,因行和列都为3,则直接让
rand()%3
即可。 - 电脑下棋用
#
表示`。 - 为了让电脑看上去更高级一点,轮到电脑下棋时,先打印出“电脑思考中…”这句话,使用Sleep(1000),暂停1秒钟,再让电脑下棋。
//电脑下
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑思考中...\n");
Sleep(1000);
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
6、判断胜负
判断胜负的情况:
返回一个字符来告诉编译器
- 玩家胜 -
*
- 电脑胜 -
#
- 平局 -
Q
- 继续 -
C
思路:
- 当行,列,两个对角线的元素均
相同且不为空
时,则为胜。 - 当两方均未符合胜的条件时,判断为平局。判断平局的思路为查看棋盘是否满了,即没有空格,则返回
1
判断为平局。 - 若双方均未符合胜和平局的条件,则返回
C
继续游戏
//玩家赢--'*'
//电脑赢--'#'
//平局 --'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][0] != ' ')
{
return board[i][0];
}
}
//列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
//判断正对角线
int cout1 = 0;
int cout2 = 0;
for (i = 0; i < row; i++)
{
if (board[i][i] == '*')
{
cout1++;
}
else if (board[i][i] == '#')
{
cout2++;
}
}
if (cout1 == row)
{
return '*';
}
if (cout2 == row)
{
return '#';
}
//判断反对角线
int cout3 = 0;
int cout4 = 0;
for (i = 0; i < row; i++)
{
if (board[i][row - 1 - i] == '*')
{
cout3++;
}
else if (board[i][row - 1 - i] == '#')
{
cout4++;
}
}
if (cout3 == row)
{
return '*';
}
if (cout4 == row)
{
return '#';
}
//判断平局
if (IsFull(board, row, col))
{
return 'Q';
}
//游戏继续
return 'C';
}
//判断棋盘是否已满
int IsFull(char board[ROW][COL], int row, int col)
{
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;
}
【3】、编写game.h头文件
- 存放需要用到的函数的
头文件
、自定义函数的声明
和预处理信息
。 - 然后让game.c和test.h文件
包含game.h头
文件即可。 - 注意:自定义头文件,用
" "
。如:#include"game.h"
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<time.h>
#define ROW 3
#define COL 3
//打印菜单
void menu();
//游戏功能实现
void game();
//初始化棋盘
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);
//判断棋盘是否已满
int IsFull(char board[ROW][COL], int row, int col);
🚀游戏源代码
以下是趣味三子棋游戏的源代码,有兴趣的朋友可以去玩一下!
- game.h头文件
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<time.h>
#define ROW 3
#define COL 3
//打印菜单
void menu();
//游戏功能实现
void game();
//初始化棋盘
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);
//判断棋盘是否已满
int IsFull(char board[ROW][COL], int row, int col);
- game.c函数实现文件
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//打印菜单
void menu()
{
printf("*******************************\n");
printf("* 趣味三子棋 V1.0 *\n");
printf("*******************************\n");
printf("* >1、play *\n");
printf("* >0、exit *\n");
printf("*******************************\n");
}
//初始化棋盘
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, j = 0;
printf(" ");
for (i = 1; i <= row; i++)
{
printf("%3d ", i);
}
printf("\n");
for (i = 0; i < row; i++)
{
printf("%2d", i + 1);
printf(" ");。
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1) {
printf("|");
}
}
printf("\n");
if (i < row - 1)
{
printf(" +");
for (j = 0; j < row; j++)
{
printf("---+");
}
printf("\n");
}
}
}
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家下棋:>");
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)
{
int x = 0;
int y = 0;
printf("电脑思考中...\n");
Sleep(1000);
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][0] != ' ')
{
return board[i][0];
}
}
//列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
//判断正对角线
int cout1 = 0;
int cout2 = 0;
for (i = 0; i < row; i++)
{
if (board[i][i] == '*')
{
cout1++;
}
else if (board[i][i] == '#')
{
cout2++;
}
}
if (cout1 == row)
{
return '*';
}
if (cout2 == row)
{
return '#';
}
//判断反对角线
int cout3 = 0;
int cout4 = 0;
for (i = 0; i < row; i++)
{
if (board[i][row - 1 - i] == '*')
{
cout3++;
}
else if (board[i][row - 1 - i] == '#')
{
cout4++;
}
}
if (cout3 == row)
{
return '*';
}
if (cout4 == row)
{
return '#';
}
//判断平局
if (IsFull(board, row, col))
{
return 'Q';
}
//游戏继续
return 'C';
}
//判断棋盘是否已满
int IsFull(char board[ROW][COL], int row, int col)
{
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;
}
- test.c文件
//游戏功能实现
void game()
{
int ret = 0;
char board[ROW][COL] = { 0 };
InitBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
while (1)
{
PlayerMove(board,ROW,COL);
system("cls");
DisplayBoard(board, ROW, COL);
ret = Iswin(board, ROW, COL);
if (ret != 'C')
{
break;
}
ComputerMove(board, ROW, COL);
system("cls");
DisplayBoard(board, ROW, COL);
ret = Iswin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
system("cls");
printf("恭喜,玩家赢了!\n");
}
else if (ret == '#')
{
system("cls");
printf("很遗憾,电脑赢了!\n");
}
else if (ret == 'Q')
{
system("cls");
printf("平局!\n");
}
DisplayBoard(board, ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
system("cls");
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏!\n");
break;
default:
printf("输入非法,请重新选择!\n");
break;
}
} while (input);
return 0;
}
🎉🎉完结🎊🎊
✨✨最后希望各位小伙伴能多多点赞关注收藏支持鸭!✨✨