C语言实现三子棋游戏之代码分析

  感觉距离第一次写blog已经很久了(在此流下无奈的眼泪),19号学校开展了认知实习,忙忙碌碌到23号,快放假到最后因为灾情又被退了两次票,最后连夜赶火车到的家,到家歇了两三天,就开始编程+学游泳+考驾照,真的是放假也休息不了啊,算了算了,吐槽到此结束,这期间学习写了一个C语言实现的三子棋游戏,下面是代码的一些分析。


题目:三子棋游戏

编程环境:Visual Studio 2019

(一)创建文件

 为了逻辑清晰的编程,我们先创建一个叫game.h的头文件用以游戏函数的声明,两个源文件,一个是text,c用以测试,另一个game,c用以游戏函数的实现,如图所示。

(二)思路分析

  首先是进入游戏界面,进行界面打印,在主函数内引用菜单函数,为了使游戏能够重复玩,将函数放在do-while循环内部。然后玩家进行游戏选择,在主函数内运用switch语句判断所选内容。

int main()
{
	int put;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &put);
		switch (put)
		{
		case 1:
			system("cls");
			game();       //进行游戏
			break;
		case 0:
			printf("即将退出游戏!!!");
			break;
		default:
			printf("输入错误,请重新输入!!");
			system("cls");
		}
	} while (put);
	return 0;
}
void menu()//菜单函数
{
	printf("*******************************\n");
	printf("********* 1.玩游戏 ************\n");
	printf("********* 0.退出 **************\n");
	printf("*******************************\n");
}

  界面搞定完成之后,就要考虑棋盘的打印了,当玩家选择进行游戏的时候,我们希望打印出的棋盘是这样的。

  当我们想进行5*5的棋盘或者更大的棋盘打印的时候,可以定义全局变量X,Y分别表示行数和列数,这样更方便改动。

                   

  这个时候,可以利用字符型数组,给每个数组单元赋值为空格,然后进行打印。

void begin(char arr[X][Y], int x, int y)  //初始化棋盘
{
	int i = 0;
	int j = 0;
	for (i = 0; i < x; i++)
	{
		for (j = 0; j < y; j++)
			arr[i][j] = ' ';             //每个数组单元都为空格
	}
}
void Print(char arr[X][Y], int x, int y)  //对棋盘进行打印
{
	int i = 0;
	int j = 0;
	int k = 0;
	for (i = 0;i < x;i++)
	{
		for (j = 0;j < y;j++)
		{
			if (j == y - 1)
				printf(" %c \n", arr[i][j]);
			else
				printf(" %c |", arr[i][j]);
			if (j==y - 1)
			{
				if (i != x - 1)
				{
					for (k = 0;k < y;k++)
						{
						if (k == y - 1)
						{
							printf("---\n");
							break;
						}
						printf("---|");
					}
					break;
				}
			}
		}
	}
}

  随后,设置玩家下棋函数和电脑下棋函数,将玩家下棋坐标对应数组单元赋值为'*',电脑下棋坐标对应数组单元赋值为'#',玩家下棋时,首先输入要下的坐标(这里注意下棋坐标和数组下标差一),输入坐标后,还要进行判断该位置是否已经被下过,这时候要判断所下位置是否为空格,若不是空格则需要再次输入,电脑下棋时,生成随机数,为保证生成的随机数在数组下表范围内,需要将生成的随机数对x,y取余,为扩大rand函数的范围,在引用srand函数,在函数内部放置无符号time函数,保证生成的数真正意义上随机 。

void gamer(char arr[X][Y], int x, int y)//玩家输入
{
	int a, b;
	scanf("%d %d", &a, &b);
	if (a > 0 && a <= x && b > 0 && b <= y)
	{
		if (arr[a - 1][b - 1] != ' ')
		{
			printf("位置已经被下过,请重新选择:");
			gamer(arr, x, y);
		}
		arr[a - 1][b - 1] = '*';
	}
	else
	{
		printf("输入不符合规则,请重新输入:");
		gamer(arr, x, y);
	}

}
void computer(char arr[X][Y], int x, int y)
{

	int a = rand() % x;
	int b = rand() % y;
	if (arr[a][b] == ' ')
	{
		arr[a][b] = '#';
	}
	else
	{
		computer(arr, x, y);
	}
}

  玩家电脑下棋后,进行判断输赢,引用win函数,当横排或竖排或对角线相等的时候,返回相等元素的值,例如:第一排都为’*‘,则返回'*',根据返回值判断为玩家赢。当返回值为’*‘或者’#‘时,判断为游戏结束,玩家赢或者电脑赢,当返回值为’ ‘时,游戏继续,当以上判断都不成立时,判断游戏屏幕是否已经满了,若不存在’ ‘,则平局。

char win(char arr[X][Y], int x, int y)//判断输赢继续
{
	char ch = 'C';
	int flag = 0;
	for (int i = 0; i < x; i++)
	{
		if (arr[i][0] == arr[i][1] && arr[i][0] == arr[i][2] && arr[i][1] == arr[i][2])//行相等
		{
			return arr[i][0];
		}
	}
	for (int j = 0; j < y; j++)
	{
		if (arr[0][j] == arr[1][j] && arr[0][j] == arr[2][j] && arr[1][j] == arr[2][j])//列相等
		{
			return arr[0][j];
		}
	}
	if (arr[0][0] == arr[1][1] && arr[0][0] == arr[2][2] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')//对角线相等
	{
		return arr[0][0];
	}
	if (arr[0][2] == arr[1][1] && arr[0][2] == arr[2][0] && arr[1][1] == arr[2][0] && arr[0][2] != ' ')//对角线相等
	{
		return arr[0][2];
	}
	for (int m = 0; m < x; m++)//是否铺满
	{
		for (int n = 0; n < y; n++)
		{
			if (arr[m][n] == ' ')
				flag = 1;
		}
	}
	if (flag == 0)
	{
		ch = 'Q';
	}
	return ch;
}
void game()//游戏进行函数
{
	srand((unsigned int)time(NULL));
	char arr[X][Y];
	begin(arr, X, Y);
	char rat;
	Print(arr, X, Y);
	while (1)
	{
		rat = win(arr, X, Y);
		printf("请输入您要下的棋子坐标:");
		gamer(arr, X, Y);
		Print(arr, X, Y);
		rat = win(arr, X, Y);
		if (rat != 'C' && rat != ' ')
		{
			break;
		}
		printf("电脑走\n");
		computer(arr, X, Y);
		Print(arr, X, Y);
		rat = win(arr, X, Y);
		if (rat != 'C' && rat != ' ')
		{
			break;
		}
	}
	switch (rat)
	{
	case '*':
		printf("玩家赢了!\n");
		break;
	case '#':
		printf("电脑赢了!\n");
		break;
	case 'Q':
		printf("平局\n");
		break;
	}
	printf("游戏结束\n");
	system("cls");
}

   为了方便起见,我们将引用的头文件和函数放到game.h下,其他文件直接引用game.h即可。

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define X 3
#define Y 3

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

void menu();
void game();
void begin(char arr[X][Y], int x, int y);
void Print(char arr[X][Y], int x, int y);
void gamer(char arr[X][Y], int x, int y);
void computer(char arr[X][Y], int x, int y);
char win(char arr[X][Y], int x, int y);

(三)效果展示

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值