C语言实现三子棋小游戏---超详细讲解

第1步—打印一个菜单提示选择是否进入游戏

void menu()
{
    
    
	printf("***********************\n");
	printf("*** 1.play  0.exit  ***\n");
	printf("***********************\n");
}

在这里插入图片描述
下面部分可不需要,按个人需求选择
进入游戏则提示游戏开始,并在0.5秒后清空屏幕

void playgame()
{
    
    
	printf("游戏开始!\n");
	Sleep(500);//待机0.5秒钟
	system("cls");//清空屏幕
}

演示效果就没有等0.5秒让屏幕清空

第2步—创建棋盘

创建一个3*3的二维数组作为棋盘,这里之所以能用ROW和COL是因为使用了#define定义了ROW和COL为3,后面会贴出具体代码,先继续往下看
放入0使棋盘(数组不完全初始化)全为0(本人习惯赋初值为0)
不知道数组不完全初始化的小伙伴可以百度了解一下

char board[ROW][COL] = {
    
     0 };

第3步—初始化棋盘

创建好棋盘之后可以先不初始化,而是先打印看一下是否全为0,检查棋盘是否创建好了
然后初始化为1再次打印看一下初始化函数是否写错

void voidchequerboard(char board[ROW][COL]) {
    
    
	int i = 0, j = 0;
	for (i = 0; i < ROW; i++) {
    
    
		for (j = 0; j < COL; j++) {
    
    
			board[i][j] = ' ';//初始化的内容
		}
	}
}

第4步—打印棋盘

加入边框,在边框中输出数据,更加形象
如果需要实现的更好可以自行参考easyx库实现

void printchequerboard(char board[ROW][COL]) {
    
    
	int i = 0, j = 0;
	for (i = 0; i < ROW; i++) {
    
    
		if (i == 0) {
    
    
			for (int k = 0; k < ROW; k++) {
    
    
				printf(" ---");
			}
			printf("\n");
		}
		for (j = 0; j < COL; j++) {
    
    
			if (j == 0) {
    
    
				printf("|");
			}
			printf(" %c ", board[i][j]);
			printf("|");
		}
		if (j == COL) {
    
    
			printf("\n");
			for (j = 0; j < ROW; j++) {
    
    
				printf(" ---");
			}
			if (1) {
    
    
				printf("\n");
			}
		}
	}
}

演示效果中可以看到有一个3*3的棋盘
下面的提示则是我们接下来要完成的功能

第5步—下棋,并判断输赢

下棋
玩家下则提示玩家输入坐标,并检查坐标是否合法
电脑则是随机下棋,并未封装算法函数,感兴趣的小伙伴可以自己实现一下

void playboard(char board[ROW][COL]) {
    
    
	int x = 0, y = 0;
	while (1) {
    
    
		printf("玩家走>:\n");
		printf("请输入坐标>:\n");
		scanf("%1d%1d", &x, &y);//考虑使用%1d格式化输入
		if (board[x-1][y-1] == ' ' && x <= ROW && y <= COL&& x> 0 && y > 0) {
    
    
			board[x-1][y-1] = '*';
			break;
		}
		else {
    
    
			printf("坐标非法或已被占用,请重新输入!\n");
		}
	}
	char ret = Iswin(board);
	//Sleep(500);
	system("cls");
	printchequerboard(board);
	if (ret == 'C') {
    
    
		printf("电脑走>:\n");
		while (1) {
    
    
			x = rand() % ROW;
			y = rand() % COL;
			if (board[x][y] == ' ') {
    
    
				board[x][y] = '#';
				break;
			}
		}
		Sleep(500);
		system("cls");
		printchequerboard(board);
		ret = Iswin(board);
	}
	if (ret == 'C') {
    
    
		playboard(board);
	}
	else if (ret == '*') {
    
    
		printf("玩家赢\n");
	}
	else if (ret == '#') {
    
    
		printf("电脑赢\n");
	}
	else {
    
    
		printf("平局\n");
	}
}

判断输赢,将所有胜的情况都判断一下,并返回赢家的棋子符号
*表示玩家,#表示电脑,
若是没有出现赢家则判断棋盘是否满了,若没满则返回C表示继续,若满了则返回D表示平局
当然了,具体返回什么符号和用什么符号表示赢家,平局,继续由自己决定,我建议选择有意义的字母比如我表示继续的C就是continue的首字母

char Iswin(char board[ROW][COL]) {
    
    
	int i = 0;
	int j = 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 (j = 0; j < COL; j++) {
    
    
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
			return board[1][j];
	}
	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 < ROW; i++) {
    
    
		for (j = 0; j < COL; j++) {
    
    
			if (board[i][j] == ' ')
				return 'C';
		}
	}
	return 'D';
}

演示效果
在这里插入图片描述

第6步—将上述函数做成项目

这里有两种选择一种是全部做成一个源文件
另一种是将函数的声明,定义,测试分开形成3个源文件
首先第一种就没必要多说了,直接做成源文件即可,唯一需要注意的就是,如果没有提前声明函数,就需要在调用前定义它即可。
我们来看看第另一种方式,多个源文件方式
在这里插入图片描述

可以看到有两个 .c文件和一个 .h文件 .h文件表示头文件可以像库函数一样引用,所以我们将函数的定义和需要用到的库函数头文件放到我们创建的头文件中,这样可以减少库函数的拷贝次数变相减少代码行数(不明白的小伙伴可以百度一下库函数调用的规则),然后在源文件中引用我们创建的头文件即可,我们将测试放在了test源文件中,而函数的定义则是放在了另一个源文件中,这样可以更好的,更直观的从test文件看到你的代码功能,也方便调试时的观察那个函数模块出了问题,下面贴出了完整代码。

完整代码

game.h

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#define ROW 3
#define COL 3

//开始游戏
void playgame();
//打印菜单
void menu();
//初始化棋盘
void voidchequerboard(char board[ROW][COL]);
//打印棋盘
void printchequerboard(char board[ROW][COL]);
//开始下棋
void playboard(char board[ROW][COL]);
//判断输赢  返回*表示玩家赢,#表示电脑赢,返回C表示继续,返回D表示平局
char Iswin(char board[ROW][COL]);

test.c

#define _CRT_SECURE_NO_WARNINGS

#include"game.h"

void game()
{
    
    
	char board[ROW][COL] = {
    
     0 };//设置棋盘
	playgame(); //提示游戏开始
	voidchequerboard(board);//初始化棋盘
	printchequerboard(board);//打印棋盘
	playboard(board);//开始下棋
}
int main()
{
    
    
	int n = 0;
	srand((unsigned int) time(NULL)); 
	while (1) {
    
    
		menu();
		scanf("%d", &n);
		switch (n) {
    
    
		case 1:game();
			   break;
		case 0:printf("游戏结束!\n"); return 0;
		default:printf("输入错误,请重新输入!\n"); break;
		}
	}
	return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS

#include"game.h"

char Iswin(char board[ROW][COL]) {
    
    
	int i = 0;
	int j = 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 (j = 0; j < COL; j++) {
    
    
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
			return board[1][j];
	}
	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 < ROW; i++) {
    
    
		for (j = 0; j < COL; j++) {
    
    
			if (board[i][j] == ' ')
				return 'C';
		}
	}
	return 'D';
}
void printchequerboard(char board[ROW][COL]) {
    
    
	int i = 0, j = 0;
	for (i = 0; i < ROW; i++) {
    
    
		if (i == 0) {
    
    
			for (int k = 0; k < ROW; k++) {
    
    
				printf(" ---");
			}
			printf("\n");
		}
		for (j = 0; j < COL; j++) {
    
    
			if (j == 0) {
    
    
				printf("|");
			}
			printf(" %c ", board[i][j]);
			printf("|");
		}
		if (j == COL) {
    
    
			printf("\n");
			for (j = 0; j < ROW; j++) {
    
    
				printf(" ---");
			}
			if (1) {
    
    
				printf("\n");
			}
		}
	}
}
void playboard(char board[ROW][COL]) {
    
    
	int x = 0, y = 0;
	while (1) {
    
    
		printf("玩家走>:\n");
		printf("请输入坐标>:\n");
		scanf("%1d%1d", &x, &y);//考虑使用%1d格式化输入
		if (board[x-1][y-1] == ' ' && x <= ROW && y <= COL&& x> 0 && y > 0) {
    
    
			board[x-1][y-1] = '*';
			break;
		}
		else {
    
    
			printf("坐标非法或已被占用,请重新输入!\n");
		}
	}
	char ret = Iswin(board);
	//Sleep(500);
	system("cls");
	printchequerboard(board);
	if (ret == 'C') {
    
    
		printf("电脑走>:\n");
		while (1) {
    
    
			x = rand() % ROW;
			y = rand() % COL;
			if (board[x][y] == ' ') {
    
    
				board[x][y] = '#';
				break;
			}
		}
		Sleep(500);
		system("cls");
		printchequerboard(board);
		ret = Iswin(board);
	}
	if (ret == 'C') {
    
    
		playboard(board);
	}
	else if (ret == '*') {
    
    
		printf("玩家赢\n");
	}
	else if (ret == '#') {
    
    
		printf("电脑赢\n");
	}
	else {
    
    
		printf("平局\n");
	}
}
void voidchequerboard(char board[ROW][COL]) {
    
    
	int i = 0, j = 0;
	for (i = 0; i < ROW; i++) {
    
    
		for (j = 0; j < COL; j++) {
    
    
			board[i][j] = ' ';
		}
	}
}
void menu()
{
    
    
	printf("***********************\n");
	printf("*** 1.play  0.exit  ***\n");
	printf("***********************\n");
}
void playgame()
{
    
    
	printf("游戏开始!\n");
	Sleep(500);//待机0.5秒钟
	system("cls");//清空屏幕
}

由于这是本人的第一篇博客难免有疏漏或说错的地方,如有发现欢迎留言指正,或私信本人。
本篇博客就到此结束了,希望对小伙伴能有所帮助。
咱们下篇博客见。

猜你喜欢

转载自blog.csdn.net/JunFengYiHan/article/details/114308340