少侠请留步!“C语言” “三子棋”游戏教程!

三子棋游戏——C语言

大家好,今天给大家带来的是用C语言实现“三子棋游戏”的代码编写。
手把手教学,包教包会,童叟无欺哦~
若有不足或疑问,欢迎评论区指正交流。
我是黎明_CL,接下来我们进入主题。

创建文件

准备:

  • 首先打开编译器,创建工程。
  • 为了方便编写和管理,我们创建三个文件,分别如下:
    • 头文件game.h

      • 用来存放数与函数的声明,便于直观地阅读代码
      • 注:以下所有游戏函数的声明都放在该文件中
    • game.c

      • #include "game.h"引用头文件
      • 用来定义函数,存放函数实现的具体内容
      • 注:以下所有游戏定义都放在该文件中
    • 创建test.c文件,用来游戏的调试

      • main函数
      • #include "game.h"引用头文件
        `
        //test.c
        #include “game.h”
        //#include <stdio.h>在头文件中声明,此处只声明头文件即可
        int mian()
        {

      return 0;
      }
      `C
      接下来让我为大家带来三子棋游戏内容的实现过程

游戏

  • 游戏菜单

用一个简单的printf函数打印菜单mune。

  • 当玩家键盘输入input为1时开始游戏,进入游戏部分,所以我们进入game()函数;
  • 输入input为0退出游戏;
  • 输入input为其它数字,退出游戏;
  • (使用switch语句多语句判断。为了使玩家玩多次,使用do…while循环
    。)
    代码如下:
int mian()
	{
		do
		{
			manu();
			printf("请选择:>");
			scanf("%d", &input);
			switch (input)
				{
				case 1:
					printf("开始游戏\n");
					game();	
					break;
				case 0:
					printf("退出游戏\n");
					break;
				default:
					printf("输入错误,请重新输入:>\n");
					break;
				}
			} while (input==1);
		return 0;
	}

游戏主体

  • 分析棋盘,我们发现可以采用二维数组board[3][3]来表示棋盘。但为了使程序可被复用,便于更改数据,扩展游戏,我们在头文件内定义宏COL与ROW来表示棋盘的行和列。
#define ROW 3	//行
#define COL 3	//列

1.初始化棋盘

  • 游戏刚开始时,要使棋盘中数据为空格字符’ '。所以要对数组board[ ROW ][COL]进行初始化。
    初始化棋盘InPut(board,ROW,COL);
//game.c
void InPut(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.打印棋盘

  • 这时我们尝试打印棋盘,发现看不见棋盘,因为数组是空格。所以我们要在屏幕上打印分割线来显示棋盘。所以数字间用分割线来显示,定义显示棋盘函数void DisplayBoard(char board[ROW][COL], int row, int col)
    1. 打印数据
    2. 打印分割行
      效果如下:
      在这里插入图片描述
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//1.打印数据
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);	//数据
			if (j < col - 1)
				printf("|");	//分隔线
		}
		printf("\n");
		//2.打印分割行
		if (i < col - 1)	
		{
			int i = 0;
			for (i = 0; i < col; i++)	
			{
				printf("---");
				if (i < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

3.玩家/电脑下棋

目标:在这里插入图片描述

  • 接下来【玩家下棋】,定义函数void PlayerMove(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col)
{
	while(1)
	{
		printf("请输入坐标:>\n");
		printf("输入行号列号,中间用空格隔开:>");
		int x = 0;
		int y = 0;
		scanf("%d %d", &x, &y);
		//判断输入行列号是否符合数量
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
		//判断该行是否已经落子
			if (board[x - 1][y - 1] == ' ')        //玩家不是程序员,而数组是从0开始,故减去1;
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
				printf("该位置已落子,请重新输入\n");
		}
		else
			printf("坐标错误,请重新输入\n");
	}
}
  • 接下来【电脑下棋】,定义函数void ComputerMove(char board[ROW][COL], int row, int col);
  • 要求:随机输入
    • 调用rand()函数产生随机数,在头文件中包含#include <stdlib.h>
    • 在main函数中调用srand((int)time(NULL) 来生成时间戳,在头文件中包含#include <time.h>
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;
		}
	}
}

4.判断输赢

  • 定义char IsWin(char board[ROW][COL], int row, int col);函数在玩家和电脑每次下完后都来判断输赢,故使用while循环;
  • 通过返回字符判断,规则如下:
    • 结束游戏·
      1. 玩家赢 ‘*’
      2. 玩家输 ‘#’
      3. 平局 ‘Q’ 如果棋盘满了,则平局
    • 继续游戏 ‘C’
  • 为简化判断,每次下完都有【继续游戏】或【结束游戏】两种结果,所以在主函数中判断是否继续;
  1. 即若返回’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];
	 }
	 //对角元素相等
	 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
		 return board[0][0];
	 if (board[0][2] == board[1][2] && board[1][2] == board[2][0] && board[0][2] != ' ')
		 return board[0][2];
	  //如果棋盘满了,则平局,所以判断棋盘是否放满。
	  //故定义函数int IsFull(char board[ROW][COL],int row,int col)
	 if (IsFull(board, row, col) == 1)
	 {
		 return 'Q';
	 }
	 return 'C';
}
int IsFull(char board[ROW][COL],int row,int col)
{
	//遍历每个元素,判断是否为空格。但凡有一个空格没放,则返回0;
	//若没空格,则表示棋盘都满了,返回1;
	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;
}
  1. 如果结束游戏,则在main函数中跳出循环,进行输赢判断`
if (ret == '*')
		printf("玩家赢\n");
	else if (ret == '#')
		printf("电脑赢\n");
	else 
		printf("平局\n");

代码

//game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3	//行
#define COL 3	//列
//打印菜单
void manu();
//初始化菜单
void InPut(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);
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void game()
{
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InPut(board,ROW,COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	//下棋
	char ret = 0;
	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");
	else if (ret == '#')
		printf("电脑赢\n");
	else 
		printf("平局\n");

}

int main()
{
	srand((unsigned int)time(NULL));
	//打印菜单
	int input = 0;//注意放在while循环外面
	do
	{
		manu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏\n");
			game();	
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入:>\n");
			break;
		}

	} while (input);
	return 0;
}
//game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

void manu()
{
	printf("***********************\n");
	printf("******  1. Play  ******\n");
	printf("******  0. Exit  ******\n");
	printf("***********************\n");
}
void InPut(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++)
	{
		//1.打印数据
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);	//数据
			if (j < col - 1)
				printf("|");	//分隔线
		}
		printf("\n");
		//2.打印分割行
		if (i < col - 1)	
		{
			int i = 0;
			for (i = 0; i < col; i++)	
			{
				printf("---");
				if (i < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{

	while(1)
	{
		printf("请输入坐标:>\n");
		printf("输入行号列号,中间用空格隔开:>");
		int x = 0;
		int y = 0;
		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");
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

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;
}
//判断输赢
 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];
	 }
	 //对角
	 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
		 return board[0][0];
	 if (board[0][2] == board[1][2] && board[1][2] == board[2][0] && board[0][2] != ' ')
		 return board[0][2];
	 if (IsFull(board, row, col) == 1)
	 {
		 return 'Q';
	 }
	 return 'C';
	 // 玩家赢 '*'
	//玩家输	'#'
	//平局	'Q'
	//继续	'C'
}

写在最后

  • 以上即为这个游戏所有详细操作及解释,当然还有可优化的地方如下;
    • 优化
      1. 在game.c中判断时代码不具有很强的复用性,可在后期进行改进优化
        //判断输赢
        char IsWin(char board[ROW][COL], int row, int col)
      2. 在界面上可以采用图形库,,让游戏界面更美观
        感谢阅读!创作不易,如果觉得其中一点有帮助到您,还请关注我,一起进步。
        当然来一个点赞也是可以的哦!
        🚀Live long and Prosper!🖖🏼
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值