zl程序教程

您现在的位置是:首页 >  后端

当前栏目

如何用C语言快速实现三子棋(步骤详细)

C语言 实现 如何 快速 详细 步骤
2023-09-27 14:22:51 时间

目录

前言

问题描述

工具

基本思路和流程

三子棋的规则

代码实现思路

实现步骤

模块化

菜单界面

 代码

选择的实现

初始化和打印棋盘

棋盘

使用宏定义

初始化

打印

考虑如何实现图表

提供代码

效果图

 玩家落子

考虑问题

参考代码

电脑实现落子

简单落子(实现随机数)

参考代码

判断

采取返回值

参考代码

整体游戏流程代码

下附源码

game.h

test.c

game.c


前言


检验学习成果最好的方式是实践

在学习完C语言的函数和数组以后,就可以简易的实现一些小游戏

本文章为手把手讲解实现C语言三子棋(好好看,相信不会太难的说)

当你自己完成后一定成就感幸福感满满的!!

问题描述

用C语言实现小游戏三子棋

工具

vs2019

基本思路和流程


三子棋的规则

在3X3的棋盘里,率先将三个棋子连成一条直线则胜出

代码实现思路

1.菜单界面:选择开始或者退出游戏
2.初始化棋盘并打印棋盘
3.玩家选择落子坐标
4.电脑实现落子
5.每次落子判断输赢平还是继续

实现步骤


模块化

1.test.c :写整个游戏实现思路流程
2.game.c: 写游戏实现思路中的各个函数的定义,完成函数内容实现函数功用
3.game.h :引用需要用到的头文件,以及对各个自定义函数的声明
(其他模板上方只需要加上 #include “game.h”,避免重复引用相同头文件)
注:模块化便于管理和修改

菜单界面


比较简单直接上代码

 代码

void menu()//游戏菜单
{
	printf("******************************\n");
	printf("**********  1.play  **********\n");
	printf("**********  0.exit  **********\n");
	printf("******************************\n");
}

选择的实现


玩家通过输入1/0 来选择是开始游戏还是退出游戏

用do while语句实现比较适合

menu();
		printf("请开始你的选择:>>>\n");
		scanf("%d", &input);
			switch (input)
			{
				case 0:
					printf("退出游戏成功\n");
					break;
				case 1:
					printf("即将开始游戏\n");
					game();
					break;
				default:
					printf("输入错误:please input your number again!\n");
					break;
			}
	} while (input);

初始化和打印棋盘


棋盘

使用3行3列的二维数组来表示,元素类型是char

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

使用宏定义

1.推高代码可读性,后续代码中遇到3,方便理解含义
2.提高扩展性,如果将来要修改棋盘尺寸,代码修改会很方便

#define ROW 3
#define COL 3

初始化

void Initboard(char board[ROW][COL], int row, int col)//初始化棋盘内容
{
	for (int i = 0; i < row; i++)//行
	{
		for (int n = 0; n < col; n++)//列
		{
			board[i][n] = ' ';
		}
	}
}

打印

考虑如何实现图表

什么时候该打印

什么时候不该打印

打印的间距

换行的考虑

提供代码

void Displayboard(char board[ROW][COL], int row, int col)//打印棋盘
{
	for (int i = 0; i < row; i++)//行数
	{
		for (int j = 0; j < col; j++)//列数
		{
			if (j < col - 1)//第一排内容,控制最后一次不打印‘|’
				printf(" %c |", board[i][j]);
			else
				printf(" %c ", board[i][j]);
		}
		printf("\n");//换行
		if (i < row - 1)//第二排,控制最后一次不打印
		{
			for (int k = 0; k < col; k++)
			{
				if (k < col - 1)
					printf("---|");
				else
					printf("---");
			}
			printf("\n");//同样换行
		}
	}
}

效果图

 玩家落子


考虑问题

1.作为玩家的思维坐标从1开始,而电脑规定标码从0开始,所以玩家落子坐标还需-1处理

2.落子范围

3.落子位置是否已经覆盖

参考代码

void Player(char board[ROW][COL], int row, int col)
{
	printf("player:输入坐标>\n");
	int i, j;
	while (1)
	{
		scanf("%d%d", &i, &j);
		if (i > 0 && i <= col && j > 0 && j <= row)//范围
		{
			if (board[i - 1][j - 1] == ' ')//减一处理
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
				printf("已经被走过了,请重新输入坐标>\n");//重复
		}
		else
			printf("超出范围啦,请重新输入坐标>\n");
	}
}

电脑实现落子


简单落子(实现随机数)

1.主函数中使用srand((unsigned int)time(0))
将时间作为随机数种子,确保得到的行列坐标是真随机
2.包含对应头文件
3.实现随机数还应符合范围(直接取余)

#include<time.h>
#include<stdlib.h>

参考代码

void Compter(char board[ROW][COL], int row, int col)
{
	printf("Compter:输入坐标>\n");
	while (1)
	{
		int i = rand() % col;
		int j = rand() % row;//范围
		if (i >= 0 && i <col && j >= 0 && j < row)
		{
			if (board[i][j] == ' ')//是否覆盖
			{
				board[i][j] = '#';
				break;
			}
		}
	}
}

判断


采取返回值

1.返回‘*’ 表示玩家获胜
2.返回‘#’ 表示电脑获胜
3.返回’g’ 表示胜负未分
4.返回‘s’ 表示和棋

胜负:判定所有的行,列,对角线

继续游戏:如果数组中有元素为’ ‘,那么没下完,返回‘g’,游戏继续,不跳出

平局:如果以上条件都未实现返回值,既是无胜负,也无继续游戏,那就是平局则返回‘s’

参考代码


char Iswin(char board[ROW][COL], int row, int col)//判断输赢
{
	for (int i = 0; i < row; i++)//横排
	{
		if (board[i][0] == board[i][1]&& board[i][0] == board[i][2] && board[i][0] == '*')
		{
			return '*';
		}
		if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == '#')
		{
			return '#';
		}	
	}
	for (int j = 0; j < col; j++)//判断竖排
	{
		if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[0][j] == '*')
		{
			return '*';
		}
		if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[0][j] == '#')
		{
			return '#';
		}
	}
	//判断对角线
		if ((board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == '*')|| (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] == '*'))
		{
			return '*';
		}
		if ((board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == '#')|| (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] == '#'))
		{
			return '#';
		}
		for (int i = 0; i < row; i++)
		{
			for (int n = 0; n < col; n++)
			{
				if (board[i][n] == ' ')
					return 'g';//继续游戏
			}
		}
		return 's';//平局
}

整体游戏流程代码

void game()//进入游戏
{
	srand((unsigned int)time(NULL));
	char ret = { 0 };
	char board[ROW][COL] = { 0 };
	Initboard(board, ROW, COL);//初始化棋盘
	Displayboard(board, ROW, COL);//展示打印棋盘
	while (1)
	{
		Player(board, ROW, COL);//玩家落子
		Displayboard(board, ROW, COL);//打印落子后棋盘
		ret=Iswin(board, ROW, COL);//返回判断结果
		if (ret != 'g')//不是继续的返回值就退出
			break;
		Compter(board, ROW, COL);//电脑落子
		Displayboard(board, ROW, COL);//打印落子后棋盘
		ret=Iswin(board, ROW, COL);//返回判断结果
		if (ret != 'g')//不是继续的返回值就退出
			break;
	}
	if (ret == '*')//进一步选择游戏结果
		printf("恭喜你赢了!\n");
	else if (ret == '#')
		printf("别灰心,下次再来\n");
	else
		printf("平局\n");
}

效果示意

******************************
请开始你的选择:>>>
1
即将开始游戏
   |   |
---|---|---
   |   |
---|---|---
   |   |
player:输入坐标>
11
11
超出范围啦,请重新输入坐标>
1 1
 * |   |
---|---|---
   |   |
---|---|---
   |   |
Compter:输入坐标>
 * |   |
---|---|---
   |   | #
---|---|---
   |   |
player:输入坐标>
1 2
 * | * |
---|---|---
   |   | #
---|---|---
   |   |
Compter:输入坐标>
 * | * | #
---|---|---
   |   | #
---|---|---
   |   |
player:输入坐标>
2 1
 * | * | #
---|---|---
 * |   | #
---|---|---
   |   |
Compter:输入坐标>
 * | * | #
---|---|---
 * |   | #
---|---|---
   |   | #
别灰心,下次再来
******************************
**********  1.play  **********
**********  0.exit  **********
******************************
请开始你的选择:>>>

赶紧试试吧,锻炼代码能力!

下附源码

game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#define ROW 3
#define COL 3


#include<stdio.h>
#include<time.h>
#include<stdlib.h>

extern void Initboard(char board[ROW][COL], int row, int col);
extern void Displayboard(char board[ROW][COL], int row, int col);
extern void Player(char board[ROW][COL], int row, int col);
extern void Compter(char board[ROW][COL], int row, int col);
extern char Iswin(char board[ROW][COL], int row, int col);

test.c

#include"game.h"

void menu()//游戏菜单
{
	printf("******************************\n");
	printf("**********  1.play  **********\n");
	printf("**********  0.exit  **********\n");
	printf("******************************\n");
}
void game()//进入游戏
{
	srand((unsigned int)time(NULL));
	char ret = { 0 };
	char board[ROW][COL] = { 0 };
	Initboard(board, ROW, COL);
	Displayboard(board, ROW, COL);
	while (1)
	{
		Player(board, ROW, COL);
		Displayboard(board, ROW, COL);
		ret=Iswin(board, ROW, COL);
		if (ret != 'g')//不是继续就退出
			break;
		Compter(board, ROW, COL);
		Displayboard(board, ROW, COL);
		ret=Iswin(board, ROW, COL);
		if (ret != 'g')//不是继续就退出
			break;
	}
	if (ret == '*')
		printf("恭喜你赢了!\n");
	else if (ret == '#')
		printf("别灰心,下次再来\n");
	else
		printf("平局\n");
}

int main()
{
	int input = 0;
	do 
	{
		menu();
		printf("请开始你的选择:>>>\n");
		scanf("%d", &input);
			switch (input)
			{
				case 0:
					printf("退出游戏成功\n");
					break;
				case 1:
					printf("即将开始游戏\n");
					game();
					break;
				default:
					printf("输入错误:please input your number again!\n");
					break;
			}
	} while (input);
	return 0;
}

game.c

#include"game.h"


void Initboard(char board[ROW][COL], int row, int col)//初始化棋盘内容
{
	for (int i = 0; i < row; i++)
	{
		for (int n = 0; n < col; n++)
		{
			board[i][n] = ' ';
		}
	}
}
void Displayboard(char board[ROW][COL], int row, int col)//打印棋盘
{
	for (int i = 0; i < row; i++)//行数
	{
		for (int j = 0; j < col; j++)//列数
		{
			if (j < col - 1)//第一排内容,控制最后一次不打印‘|’
				printf(" %c |", board[i][j]);
			else
				printf(" %c ", board[i][j]);
		}
		printf("\n");//换行
		if (i < row - 1)//第二排,控制最后一次不打印
		{
			for (int k = 0; k < col; k++)
			{
				if (k < col - 1)
					printf("---|");
				else
					printf("---");
			}
			printf("\n");//同样换行
		}
	}
}
void Player(char board[ROW][COL], int row, int col)
{
	printf("player:输入坐标>\n");
	int i, j;
	while (1)
	{
		scanf("%d%d", &i, &j);
		if (i > 0 && i <= col && j > 0 && j <= row)
		{
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
				printf("已经被走过了,请重新输入坐标>\n");
		}
		else
			printf("超出范围啦,请重新输入坐标>\n");
	}
}
void Compter(char board[ROW][COL], int row, int col)
{
	printf("Compter:输入坐标>\n");
	while (1)
	{
		int i = rand() % col;
		int j = rand() % row;
		if (i >= 0 && i <col && j >= 0 && j < row)
		{
			if (board[i][j] == ' ')
			{
				board[i][j] = '#';
				break;
			}
		}
	}
}
char Iswin(char board[ROW][COL], int row, int col)//判断输赢
{
	for (int i = 0; i < row; i++)//横排
	{
		if (board[i][0] == board[i][1]&& board[i][0] == board[i][2] && board[i][0] == '*')
		{
			return '*';
		}
		if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == '#')
		{
			return '#';
		}	
	}
	for (int j = 0; j < col; j++)//判断竖排
	{
		if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[0][j] == '*')
		{
			return '*';
		}
		if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[0][j] == '#')
		{
			return '#';
		}
	}
	//判断对角线
		if ((board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == '*')|| (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] == '*'))
		{
			return '*';
		}
		if ((board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == '#')|| (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] == '#'))
		{
			return '#';
		}
		for (int i = 0; i < row; i++)
		{
			for (int n = 0; n < col; n++)
			{
				if (board[i][n] == ' ')
					return 'g';//继续游戏
			}
		}
		return 's';//平局
}