哥们哥们,人机大战晓得吧玩家对战晓得吧,简易三子棋,呕心沥血500行代码手把手带你制作第一个小游戏,可以保存收藏以后接着看哟,最后有源码哦

发布于:2022-11-09 ⋅ 阅读:(377) ⋅ 点赞:(0)

目录

 

前言

 

一、游戏想要有意思,函数不可少,整活的函数

二、三子棋的游戏界面

三、三子棋的功能步骤分析 

    1.菜单

    2.三子棋实现的总体框架

    3.棋盘创建

    4.棋盘初始化

    5.棋盘打印

    6.玩家下棋

    7.电脑下棋

    8.判断输赢

    9.判断是否平局及其继续

四、人机大战

五、玩家对决

六、源码

 

总结


 

前言

大家好呀,欢迎来到我滴博客,就如同标题那样,我带大家实现的就是“三子棋” 小游戏,这个游戏很经典,也很有意思(有意思的是我们自己创造出来的人工智障哈哈),这个小游戏的具体功能呢有人机对战,玩家solo以及退出(有初级进度条的实现哟~),500行相信大家跟着这篇博客成功地实现了你自己的三子棋以后,你对循环,函数以及文件后缀.h呀.c以及游戏的先后出手顺序也会有一个新的认识,那么现在跟我一起去创造你的第一个人工智障吧!!! 


希望大家敲到足够的代码后也能像我一样找到女朋友 ,嘿嘿今个刚好是我家小姑娘生日哦~

动力源泉啊兄弟们!!!83d19dd99a254e1c87120a8a34db25c2.jpeg

 

 

 

一、游戏想要有意思,函数不可少,整活的函数

srand((unsigned int)time(NULL))(引入头文件#include<stdlib.h>)一般和rand()(引入头文件#include<time.h)一同使用用来产生随机数

Sleep(int x)(头文件#include<windows.h)可以使打印有时间间隔,这里我用来做进度条

system("cls")(头文件#include<stdlib.h>)用来清理屏幕。

 

先给大家看看需要自己写的函数,接口函数的功能都有备注(一般定义在.h文件里)

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<windows.h>
#define ROW 3//行
#define COL 3//列,不用加;
void test();//测试运行
void menu();//菜单栏
void game();//游戏逻辑
//先声明
void player_move1(char board[ROW][COL], int row, int col);//玩家b下棋
void init_board(char board[ROW][COL], int row, int col);//初始化棋盘
void print_board(char board[ROW][COL], int row, int col);//打印棋盘
void player_move(char board[ROW][COL], int row, int col);//玩家a下棋
void computer_move(char board[ROW][COL], int row, int col);//电脑下棋
char in_win(char board[ROW][COL], int row, int col);//判断输赢

二、三子棋的游戏界面

10049be2774a4471a88c7c44649b31ed.png

 上边就是界面的初步实现,界面越简洁,说明越容易实现,相信我,你也可以的。

 

三、三子棋的功能步骤分析 

1.菜单

3973ad7733d3456f968dbd5083b26f5e.png

展示一个页面,提示用户,根据数字选择游戏方式,主要是为了美观!!!

一般界面的实现用的是void menu()函数

void menu()//菜单
{
	printf("***********************\n");
	printf("***********************\n");
	printf("******0  退出游戏******\n");
	printf("******1. 人机大战******\n");
	printf("******2. 人人对决******\n");
	printf("***********************\n");
	printf("***********************\n");
}

2.三子棋实现的总体框架

根据菜单提示,输入数字,回车,进入游戏。

而这个数字的控制自然需要借助switch语句,而游戏肯定不是想只玩一局,这时候do--while()语句就派上了用场,一般来说,菜单以及测试实现游戏功能所需要的函数都放在void taxt()函数中

输入0退出游戏,1和2分别是人机大战和人人对决其他的则会提醒你重新输入。

然后是不是需要一些条件判断谁赢谁输以及继续游戏还是平局,下面我来提前规定一下

我们用游戏过程中产生的返回值来判断是否要继续,定义char ret来接收返回值

ret==C,游戏继续

ret==Q,游戏平局

ret==‘*’,玩家胜利

ret==‘#’,电脑胜利

void text()
{
	srand((unsigned int)time(NULL));//unsigned inttime最好强制类型转换一下
	int input = 0;
	char arr[50];
	strcpy(arr, "-------------------------------------------------");
	do
	{

		menu();
		
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1: {
			printf("三子棋\n");
			game1();
			printf("正在退出,请稍后哦亲~\n");
			for (int i = 0; i < 50; i++)
			{
				printf("%c", arr[i]);
				Sleep(100);
		}
			system("cls");
			break;
		}
		case 2: {
			printf("三子棋\n");
			game2();
			printf("正在退出,请稍后哦亲~\n");
			for (int i = 0; i < 50; i++)
			{
				printf("%c", arr[i]);
				Sleep(100);
			}
			system("cls");
			break;
		}
		case 0:
		{
			printf("正在退出,请稍后哦亲~\n");
			for (int i = 0; i < 50; i++)
			{
				printf("%c", arr[i]);
				Sleep(100);
			}
			system("cls");
			break;
		}
		default:
		{
			printf("选择错误,请重新选择\n");
			
		}
		}
	} while (input);
}

 我们输入的便是input的数值,当输入0的时候input==0则switch可以退出,while(input)里的条件也不成立,则可以退出游戏。

注意看在(正在退出,请稍后哦亲~)的那里我加了for循环,Sleep()就派上了用场,他可以使打印放慢,一个一个打印,实现就像进度条,读者可自己尝试。

3.棋盘创建

棋盘的创建以及棋子的改变则需要借助二维数组和for循环,因为不想把棋盘的大小定死,所以这里可以用#define宏定义一下,ROW为行COL为列的二维数组(三子棋中ROW=COL=3)棋盘长啥样子呢?话不多说,直接放图

9a21d32ad15e483c83d10eaf034f54bb.png52c955c5a5df46c489e81818bdf1b3c1.pngf1b4048260b74251b31df4281220b8f5.png

 

 因为用了宏定义,所以改一个数值,棋盘的大小就可以变

 注意,现在没下棋不代表棋盘里的内容是空的,他里边其实是空格,到时候也需要结束空格来判断是否有棋子,是否平局

棋盘如何打印呢

首先最外层有个循环,然后有两个小循环:第一个循环打印【‘字符’+‘|’】打印三次(其中加个条件时’|'只打印两次)这打印的是一行;第二个循环【‘- - - ’+‘|’】打印三次(其中加个条件时‘|’只打印两次)这打印的也是一行;最外层循环把第一个小循环循环三次,把第二个小循环循环两次
这个次数只是代表三行三列的,但我的代码可实现n行n列

打印之前需要创建一个二维数组,并且赋值为空格,也就是初始化棋盘,然后调用打印函数即可打印棋盘

void init_board(char board[ROW][COL], int row, int col)//初始化棋盘;
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] =' ';
		}
	}
}

void print_board(char board[ROW][COL], int row, int col)//打印棋盘
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}

	}
}

4.棋盘初始化

很简单就是个数组赋值为空格即可

void init_board(char board[ROW][COL], int row, int col)//初始化棋盘;
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] =' ';
		}
	}
}

5.棋盘打印

水了一下字数,具体可以看3.棋盘创建

void print_board(char board[ROW][COL], int row, int col)//打印棋盘
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}

	}
}

6.玩家下棋

玩家通过输入坐标进行下棋,如果坐标合法且该位置为空格则放下棋子,其实就是把数组里的那个位置的空格替换了一下,这里规定玩家a是*玩家b是#,读者也可自行修改。而人机大战中玩家是*电脑是#

坐标输入不合法则会提示,并且可以重新输入运用了循环

下边是两个函数,一个是玩家a一个是玩家b

void player_move(char board[ROW][COL], int row, int col)//玩家a输入
{
	
	int x, y;
	while (1)
	{
		printf("玩家下棋:");
		scanf("%d%d", &x, &y);
			if (x >= 1 && x <= row && y >= 1 && y <= col)
			{
				if (board[x-1][y-1] != ' ')
				{
					printf("该位置已被占用,请重新输入:\n");
				}
				else
				{
					board[x - 1][y - 1] ='*';
					break;
				}

			}
			else
			{
				printf("坐标不对,请重新输入\n");
			}
	}
}
void player_move1(char board[ROW][COL], int row, int col)//玩家b输入
{

	int x, y;
	while (1)
	{
		printf("玩家下棋:");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] != ' ')
			{
				printf("该位置已被占用,请重新输入:\n");
			}
			else
			{
				board[x - 1][y - 1] = '#';
				break;
			}

		}
		else
		{
			printf("坐标不对,请重新输入\n");
		}
	}
}

7.电脑下棋

电脑下棋其实就是随机生成一个坐标,但是随机数如何限制在合法的范围内呢?这时候就用到了rand()函数,在用他之前需要在test()里游戏开始前用一下srand()作为种子,使其更好地产生随机数,具体用法读者可看其他博客哦~

因为棋盘在0~2范围内,这时候用求余数就可以解决啦,rand()%3则代表着产生0~2的随机数,然后在坐标上放#

void computer_move(char board[ROW][COL], int row, int col)//电脑下棋
{
	printf("电脑下棋:\n");
	while (1)
	{
		int x = rand () % row;
		int y = rand() % col;
		if (board[x][y] ==' ')
		{
			board[x ][y ] = '#';
			break;
		}
	}
}//开始运行

8.判断输赢

棋盘有了,棋也下了,那既然是游戏输赢总应该要判断吧!这也是难点

对于三子棋来说横、竖、左斜线、右斜线连成三个则胜利

先判断左斜线,我的思路是一个坐标一个坐标判断,从第一行开始以该坐标为起点向右下两格,若都相等则该方胜利,从图上可知道,横从下往上数要大于2才可能向下有两个位置,竖也要从右向左保留两个才可以有足够的位置我的代码实现是判断任意棋盘三个连线,读者可以研究一下,那个num的位置放的也很讲究。把*换成#即可判断#是否可以

3e9abed81d0d418689fe788e5daad192.png

int i, j, num = 0,b=0,c;
	//判断左对角线*
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < (col - 2); j++)
		{
			int a =c= j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '*')
				{
					num += 1;
				}
				b++;
				c++;

			}
			if (num == 3)
				return '*';
		}
	}

 同理右对角线

//判断右对角线*
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 2; j < col ; j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '*')
				{
					num += 1;
				}
				b++;
				c--;
			}
			if (num == 3)
				return '*';
		}
	}

 

横竖就简单了,读者很容易想到 

//判断竖线*
	num = 0;
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < col; j++)
		{
			num = 0;
			int a = c = j;
			b = i;
			for (a=j; a < (j + 3); a++)
			{
				if (board[b][c] == '*')
				{
					num += 1;
				}
				b++;
			}
			if (num == 3)
				return '*';
		}
	}
for (i = 0; i < row ; i++)
	{
		for (j = 0; j < (col-2); j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a = j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '*')
				{
					num += 1;

				}
				c++;
			}
			if (num == 3)
				return '*';
		}
	}

9.判断是否平局及其继续

static int is_full(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')//若没有空格,游戏也没有结束则为平局,输出0;
			return 0;
		}
	}
	return 1;
}

这个根据输出的内容来看函数输出什么字符,根据字符判断游戏结果

为啥上边的代码可以判断平局以及继续呢,来看下边人机大战和人人对决


四、人机大战

既然是人机大战,那自然需要引用电脑下棋和玩家下棋了,这里的玩家我采用的是a玩家下的棋是“  *  ”电脑用“  #  ”

void player_move(char board[ROW][COL], int row, int col)//玩家输入 a
void computer_move(char board[ROW][COL], int row, int col)//电脑下棋

上边是需要引用的函数 

那么下棋的过程也就是游戏的实现,前文也说了放在game1()函数中,那么怎么使用game1()呢?这时候前边第二大块定义的返回值就可以派上用场了,每当一个玩家或者电脑下完棋后则判断一次,所以我们需要一个判断输赢函数in_win()函数,里边放着判断游戏的结果的步骤,就是之前所提到的,判断左斜线、右斜线、横竖那些条件,以及平局或者继续,函数会根据具体情况返回一个值,用ret接收,然后进行判断,说了那么多可能有点懵逼,我先放代码。

static int is_full(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			return 0;
		}
	}
	return 1;
}
char in_win(char board[ROW][COL], int row, int col)
{
	

	int i, j, num = 0,b=0,c;
	//判断左对角线*
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < (col - 2); j++)
		{
			int a =c= j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '*')
				{
					num += 1;
				}
				b++;
				c++;

			}
			if (num == 3)
				return '*';
		}
	}
	num = 0;
	//判断左对角线#
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < (col - 2); j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '#')
				{
					num += 1;
				}
				b++;
				c++;
			}
			if (num == 3)
				return '#';
		}
	}
	num = 0;
	//判断右对角线*
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 2; j < col ; j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '*')
				{
					num += 1;
				}
				b++;
				c--;
			}
			if (num == 3)
				return '*';
		}
	}
	//判断右对角线#
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 2; j < col; j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '#')
				{
					num += 1;
				}
				b++;
				c--;
			}
			if (num == 3)
				return '#';
		}
	}
	//判断竖线*
	num = 0;
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < col; j++)
		{
			num = 0;
			int a = c = j;
			b = i;
			for (a=j; a < (j + 3); a++)
			{
				if (board[b][c] == '*')
				{
					num += 1;
				}
				b++;
			}
			if (num == 3)
				return '*';
		}
	}
	//判断竖线#
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < col; j++) 
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
			
				if (board[b][c] == '#')
				{
					num += 1;
					
				}
				b++;
			}
			if (num == 3)
				return '#';
		}
	}
	//判断横线*
	for (i = 0; i < row ; i++)
	{
		for (j = 0; j < (col-2); j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a = j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '*')
				{
					num += 1;

				}
				c++;
			}
			if (num == 3)
				return '*';
		}
	}
	//判断横线#
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < (col - 2); j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a = j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '#')
				{
					num += 1;

				}
				c++;
			}
			if (num == 3)
				return '#';
		}
	}
	if (is_full(board, row, col)==1)
	{
		return 'Q';
	}
	else
		return 'C';
}

代码有点长,但是有注释,我相信你可以理解,不行可以私信我。

这时候同学就问了 static int is_full(char board[ROW][COL], int row, int col)

这个是干嘛的呀?大家看代码的最下方,它是负责产生‘C’

和‘Q’的,代表着游戏的继续或平局判断,因为只想在这个文件里引用它,所以前缀static。

大家以为这就结束了?nonono。因为game1()还没出现呢,前边定义的函数都要为它服务。

我来理一下逻辑啊

假如玩家先出手,则玩家下棋--判断输赢--电脑下棋--判断输赢--没结束?再次循环玩家下棋----

以此类推

所以我们需要while()函数吧,判断输赢需要定义 char  ret来接收in-win()函数的返回值,然后总不能一直一个人先手吧,所以需要一个判断条件,我是用rand()%2产生个随机数赋值给a,加个if语句判断就好,随机数一局一个,所以放在while外边。好啦,先看代码

void game1()
{
	
		char board[ROW][COL];
		char ret = 0;
		int a = rand() % 3;
		init_board(board, ROW, COL);
		print_board(board, ROW, COL);
		if (a == 1)
		{
			printf("玩家先手\n");
			while (1)
			{
				printf("玩家回合");
				player_move(board, ROW, COL);
				print_board(board, ROW, COL);
				/*按断输赢*/
				ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}
				printf("电脑回合");
				computer_move(board, ROW, COL);
				print_board(board, ROW, COL);
				ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}
				/*判断输赢*/
				/*ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}*/

			}
			if (ret == '*')
				printf("恭喜你赢了人工智障!\n");
			else if (ret == '#')
				printf("啧啧啧,居然输给了人工智障!\n");
			else  if (ret == 'Q')
				printf("恭喜啦勉强跟人工智障打了个平局!\n");
		}
		else
		{
			printf("电脑先手\n");
			while (1)
			{
				printf("电脑回合");
				computer_move(board, ROW, COL);
				print_board(board, ROW, COL);
				/*按断输赢*/
				ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}
				printf("玩家回合");
				player_move(board, ROW, COL);
				
				print_board(board, ROW, COL);
				ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}
				/*判断输赢*/
				/*ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}*/

			}
			if (ret == '*')
				printf("恭喜你赢了人工智障!\n");
			else if (ret == '#')
				printf("啧啧啧,居然输给了人工智障!\n");
			else  if (ret == 'Q')
				printf("恭喜啦勉强跟人工智障打了个平局!\n");
		}
	
}

退出while()循环代表游戏结束,会有个返回值,这时候根据ret的值就可以判断结果啦~在代码最后

下面的是我操作的结果,emmm居然输了。。。。。。。

可以根据代码对一下,产生结果后会出现相应的文字

下面那个进度条大家也看到了吧嘿嘿。

6ee759df5f6c4c9489c30b9559daa636.png

8058dcc75f1b47599bcc7c598f731db7.png 

这个是进度条以及具体代码的作用,清理的就是上边的棋盘,然后就重新出现主菜单了。

 a88fc3dd270b4c5787894475915e51a0.png

 上边就是大致的人机对战哈哈

五、玩家对决

玩家对决,顾名思义,就是a和b的对决,不需要电脑

这时候的逻辑啊跟上边大差不差玩家1下棋--判断输赢--玩家2下棋--判断输赢---以此类推

这个规定a棋子‘*’,b棋子‘#’

所以需要再定义一个玩家下棋以及game2()其他不变。

放代码这个是玩家对决的游戏思路

void game2()
{
	char board[ROW][COL];
	char ret = 0;
	int a = rand() % 3;
	init_board(board, ROW, COL);
	print_board(board, ROW, COL);
	if (a == 1)
	{
		printf("a先手\n");
		while (1)
		{

			printf("a的回合 ");
			player_move(board, ROW, COL);
			print_board(board, ROW, COL);
			/*按断输赢*/
			ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			printf("b的回合 ");
			player_move1(board, ROW, COL);
			print_board(board, ROW, COL);
			/*按断输赢*/
			ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			/*判断输赢*/
			/*ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}*/

		}
		if (ret == '*')
			printf("恭喜a赢了b!\n");
		else if (ret == '#')
			printf("恭喜b赢了a!\n");
		else  if (ret == 'Q')
			printf("恭喜啦a和b打了个平局!\n");
	}
	else 
	{
		printf("b先手\n");
		while (1)
		{

			printf("b的回合 ");
			player_move1(board, ROW, COL);
			print_board(board, ROW, COL);
			/*按断输赢*/
			ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			printf("a的回合 ");
			player_move(board, ROW, COL);
			print_board(board, ROW, COL);
			/*按断输赢*/
			ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			/*判断输赢*/
			/*ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}*/

		}
		if (ret == '*')
			printf("恭喜a赢了b!\n");
		else if (ret == '#')
			printf("恭喜b赢了a!\n");
		else  if (ret == 'Q')
			printf("恭喜啦a和b打了个平局!\n");
	}
}

玩家b的定义,可以看到里边的棋子是‘#’。

void player_move1(char board[ROW][COL], int row, int col)//玩家输入
{

	int x, y;
	while (1)
	{
		printf("玩家下棋:");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] != ' ')
			{
				printf("该位置已被占用,请重新输入:\n");
			}
			else
			{
				board[x - 1][y - 1] = '#';
				break;
			}

		}
		else
		{
			printf("坐标不对,请重新输入\n");
		}
	}
}

六、源码

游戏制作都要分块,分模块

定义文件game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<windows.h>
#define ROW 3//行
#define COL 3//列,不用加;
void test();//测试运行
void menu();//菜单栏
void game();//游戏逻辑
//先声明
void player_move1(char board[ROW][COL], int row, int col);//玩家b下棋
void init_board(char board[ROW][COL], int row, int col);//初始化棋盘
void print_board(char board[ROW][COL], int row, int col);//打印棋盘
void player_move(char board[ROW][COL], int row, int col);//玩家a下棋
void computer_move(char board[ROW][COL], int row, int col);//电脑下棋
char in_win(char board[ROW][COL], int row, int col);//判断输赢

 定义文件game.c

#include"game.h"

void menu()//菜单
{
	printf("***********************\n");
	printf("***********************\n");
	printf("******0  退出游戏******\n");
	printf("******1. 人机大战******\n");
	printf("******2. 人人对决******\n");
	printf("***********************\n");
	printf("***********************\n");
}
 static int is_full(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			return 0;
		}
	}
	return 1;
}
char in_win(char board[ROW][COL], int row, int col)
{
	

	int i, j, num = 0,b=0,c;
	//判断左对角线*
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < (col - 2); j++)
		{
			int a =c= j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '*')
				{
					num += 1;
				}
				b++;
				c++;

			}
			if (num == 3)
				return '*';
		}
	}
	num = 0;
	//判断左对角线#
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < (col - 2); j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '#')
				{
					num += 1;
				}
				b++;
				c++;
			}
			if (num == 3)
				return '#';
		}
	}
	num = 0;
	//判断右对角线*
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 2; j < col ; j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '*')
				{
					num += 1;
				}
				b++;
				c--;
			}
			if (num == 3)
				return '*';
		}
	}
	//判断右对角线#
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 2; j < col; j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '#')
				{
					num += 1;
				}
				b++;
				c--;
			}
			if (num == 3)
				return '#';
		}
	}
	//判断竖线*
	num = 0;
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < col; j++)
		{
			num = 0;
			int a = c = j;
			b = i;
			for (a=j; a < (j + 3); a++)
			{
				if (board[b][c] == '*')
				{
					num += 1;
				}
				b++;
			}
			if (num == 3)
				return '*';
		}
	}
	//判断竖线#
	for (i = 0; i < (row - 2); i++)
	{
		for (j = 0; j < col; j++) 
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a=j; a < (j + 3); a++)
			{
			
				if (board[b][c] == '#')
				{
					num += 1;
					
				}
				b++;
			}
			if (num == 3)
				return '#';
		}
	}
	//判断横线*
	for (i = 0; i < row ; i++)
	{
		for (j = 0; j < (col-2); j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a = j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '*')
				{
					num += 1;

				}
				c++;
			}
			if (num == 3)
				return '*';
		}
	}
	//判断横线#
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < (col - 2); j++)
		{
			int a = c = j;
			b = i;
			num = 0;
			for (a = j; a < (j + 3); a++)
			{
				
				if (board[b][c] == '#')
				{
					num += 1;

				}
				c++;
			}
			if (num == 3)
				return '#';
		}
	}
	if (is_full(board, row, col)==1)
	{
		return 'Q';
	}
	else
		return 'C';
}
void game2()
{
	char board[ROW][COL];
	char ret = 0;
	int a = rand() % 3;
	init_board(board, ROW, COL);
	print_board(board, ROW, COL);
	if (a == 1)
	{
		printf("a先手\n");
		while (1)
		{

			printf("a的回合 ");
			player_move(board, ROW, COL);
			print_board(board, ROW, COL);
			/*按断输赢*/
			ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			printf("b的回合 ");
			player_move1(board, ROW, COL);
			print_board(board, ROW, COL);
			/*按断输赢*/
			ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			/*判断输赢*/
			/*ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}*/

		}
		if (ret == '*')
			printf("恭喜a赢了b!\n");
		else if (ret == '#')
			printf("恭喜b赢了a!\n");
		else  if (ret == 'Q')
			printf("恭喜啦a和b打了个平局!\n");
	}
	else 
	{
		printf("b先手\n");
		while (1)
		{

			printf("b的回合 ");
			player_move1(board, ROW, COL);
			print_board(board, ROW, COL);
			/*按断输赢*/
			ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			printf("a的回合 ");
			player_move(board, ROW, COL);
			print_board(board, ROW, COL);
			/*按断输赢*/
			ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			/*判断输赢*/
			/*ret = in_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}*/

		}
		if (ret == '*')
			printf("恭喜a赢了b!\n");
		else if (ret == '#')
			printf("恭喜b赢了a!\n");
		else  if (ret == 'Q')
			printf("恭喜啦a和b打了个平局!\n");
	}
}
void game1()
{
	
		char board[ROW][COL];
		char ret = 0;
		int a = rand() % 3;
		init_board(board, ROW, COL);
		print_board(board, ROW, COL);
		if (a == 1)
		{
			printf("玩家先手\n");
			while (1)
			{
				printf("玩家回合");
				player_move(board, ROW, COL);
				print_board(board, ROW, COL);
				/*按断输赢*/
				ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}
				printf("电脑回合");
				computer_move(board, ROW, COL);
				print_board(board, ROW, COL);
				ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}
				/*判断输赢*/
				/*ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}*/

			}
			if (ret == '*')
				printf("恭喜你赢了人工智障!\n");
			else if (ret == '#')
				printf("啧啧啧,居然输给了人工智障!\n");
			else  if (ret == 'Q')
				printf("恭喜啦勉强跟人工智障打了个平局!\n");
		}
		else
		{
			printf("电脑先手\n");
			while (1)
			{
				printf("电脑回合");
				computer_move(board, ROW, COL);
				print_board(board, ROW, COL);
				/*按断输赢*/
				ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}
				printf("玩家回合");
				player_move(board, ROW, COL);
				
				print_board(board, ROW, COL);
				ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}
				/*判断输赢*/
				/*ret = in_win(board, ROW, COL);
				if (ret != 'C')
				{
					break;
				}*/

			}
			if (ret == '*')
				printf("恭喜你赢了人工智障!\n");
			else if (ret == '#')
				printf("啧啧啧,居然输给了人工智障!\n");
			else  if (ret == 'Q')
				printf("恭喜啦勉强跟人工智障打了个平局!\n");
		}
	
}

void text()
{
	srand((unsigned int)time(NULL));//unsigned inttime最好强制类型转换一下
	int input = 0;
	char arr[50];
	strcpy(arr, "-------------------------------------------------");
	do
	{

		menu();
		
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1: {
			printf("三子棋\n");
			game1();
			printf("正在退出,请稍后哦亲~\n");
			for (int i = 0; i < 50; i++)
			{
				printf("%c", arr[i]);
				Sleep(100);
		}
			system("cls");
			break;
		}
		case 2: {
			printf("三子棋\n");
			game2();
			printf("正在退出,请稍后哦亲~\n");
			for (int i = 0; i < 50; i++)
			{
				printf("%c", arr[i]);
				Sleep(100);
			}
			system("cls");
			break;
		}
		case 0:
		{
			printf("正在退出,请稍后哦亲~\n");
			for (int i = 0; i < 50; i++)
			{
				printf("%c", arr[i]);
				Sleep(100);
			}
			system("cls");
			break;
		}
		default:
		{
			printf("选择错误,请重新选择\n");
			
		}
		}
	} while (input);
}

void init_board(char board[ROW][COL], int row, int col)//初始化棋盘;
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] =' ';
		}
	}
}

void print_board(char board[ROW][COL], int row, int col)//打印棋盘
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}

	}
}
void player_move(char board[ROW][COL], int row, int col)//玩家输入 a
{
	
	int x, y;
	while (1)
	{
		printf("玩家下棋:");
		scanf("%d%d", &x, &y);
			if (x >= 1 && x <= row && y >= 1 && y <= col)
			{
				if (board[x-1][y-1] != ' ')
				{
					printf("该位置已被占用,请重新输入:\n");
				}
				else
				{
					board[x - 1][y - 1] ='*';
					break;
				}

			}
			else
			{
				printf("坐标不对,请重新输入\n");
			}
	}
}
void player_move1(char board[ROW][COL], int row, int col)//玩家输入
{

	int x, y;
	while (1)
	{
		printf("玩家下棋:");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] != ' ')
			{
				printf("该位置已被占用,请重新输入:\n");
			}
			else
			{
				board[x - 1][y - 1] = '#';
				break;
			}

		}
		else
		{
			printf("坐标不对,请重新输入\n");
		}
	}
}
void computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:\n");
	while (1)
	{
		int x = rand () % row;
		int y = rand() % col;
		if (board[x][y] ==' ')
		{
			board[x ][y ] = '#';
			break;
		}
	}
}//开始运

定义测试文件test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

int  main()
{
	text();
	
	return 0;
}

 跟我这样放入就可以运行啦~

 

06e9444248a74635a4990b890db999b3.png

 

 

总结

好了,以上就是本期的内容,因为本人较懒,需要粉丝激励,大家收藏关注谢谢啦~你们越激励我码字越有劲,扫雷,猜数字,推箱子,以及心得笔记都会有哦~

c的学习很简单,就是多敲代码,大家只要努力都可以敲代码成为大牛!!!

 

 

本文含有隐藏内容,请 开通VIP 后查看