【C语言/入门游戏设计】三子棋(井字棋)的设计和实现

三子棋基本简述:

三子棋的规则是:在3x3的棋盘里,双方轮流下子(以X和O表示),先将3个子连成一条线(横竖斜都可以)的一方获胜。

所需要的基础知识

  • 自定义函数及实现;
  • 二维数组的定义和使用;
  • 循环和判断语句的使用等;

目录

初始界面的实现

棋盘的创建及初始化棋盘

棋盘的打印

玩家行动

电脑行动

胜负判定

game()函数的组装

全局展示


首先放一张VS2019运行的效果图:

【C语言/入门游戏设计】三子棋(井字棋)的设计和实现_第1张图片

初始界面的实现

首先点开VS2019,创建

  • game.h 头文件(声明game.c中的函数和需要的数据)
  • game.c 源文件(用于实现游戏内函数,测试游戏以及运行游戏)

首先,在game.h中引用所需要的头文件必要的定义

#pragma once

#include
#include
#include
#include

#define _CRT_SECURE_NO_WARNINGS

初始界面,顾名思义,就是点击.exe文件后初始化的选择界面。

int main()
{
	int input = 0;
   //用do while循环保证菜单至少被打开一次
    do
	{
		menu(); 
        //需要定义menu()函数
		printf("请选择>:");
		
		scanf("%d", &input);
		
		
		switch (input)
		{
		case 1:
			printf("游玩愉快\n");
			game();
			break;
		case 0:
			printf("已退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
            break;
		}
	} while (input);

//如果选择0,会判定为假,跳出循环,结束游戏;选择其他则不会,保证游戏可以重复游玩
//这是基本的游戏界面的编写程序,需要掌握。
    return 0;
}

menu()函数,只需要简单的阐述清楚,应该输入 1 / 0 ,1为开始游戏, 0为退出游戏。

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

棋盘的创建及初始化棋盘

现需要定义game( ) 函数,我们知道三子棋是3×3的棋盘,如何对棋盘进行初始化呢?

可以使用二维数组来表示棋盘中的元素,并且先初始化二维数组中的每个元素为' 空格 ',这样才会出现效果图的效果:

 我们首先用define 定义常量ROW COL (行和列),这样就可以轻松修改棋盘格式(任意a * a)

#define ROW 3
#define COL 3
	char graph[ROW][COL] = { 0 };   //放在game函数内部!!
	Initgraph(graph,ROW,COL);
	Displaygraph(graph, ROW, COL);

现在我们来写将棋盘初始化的函数Initgraph,这里我们用二重循环简单写出:

void Initgraph(char arr[ROW][COL], int x, int y)
{
	for (int i = 0; i < x; i++)
	{
		for (int j = 0; j < y; j++)
		{
			arr[i][j] = ' ';
		}
	}
}

这样就对二维数组的每个元素进行了赋值,全部都是空格。接下来我们就要对棋盘进行打印了。

棋盘的打印

我们需要将棋盘展示出来,就是用 printf 函数。

为了实现效果,这里我们也需要一个函数来实现,我们将其命名为Displaygraph()

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

玩家行动

现在到了本游戏的重点,玩家行动,这里我们用‘*’来代表玩家的棋子

玩家下棋代表用*将棋盘中的空格替代

void PlayerMove(char arr[ROW][COL], int x, int y)
{
	printf("请玩家下棋:>\n");
	int a = 0;
	int b = 0;
	while (1)
	{
		scanf("%d %d", &a, &b);
		if (a <= x && b <= y && arr[a - 1][b - 1] == ' ')
		{
			arr[a-1][b-1] = '*';
			break;
		}
		else
			printf("\n位置非法,请重新输入:>");
	}
}

电脑行动

我们先设置一个智障的电脑,随机数。

记得既然使用了rand()函数,也需要用time函数。格式如下。

	srand((unsigned int)time(NULL));
void ComMove(char arr[ROW][COL], int x, int y)
{
	printf("电脑下棋:>\n");	
	int a, b;

	while (1)
	{
		a = rand() % x;
		b = rand() % y;
		if (arr[a][b] == ' ')
		{
			arr[a][b] = '#';
			break;
		}
	}
}

胜负判定


这里我们需要列举全部的游戏情况

  • 胜利:横行三子,竖行三子,对角线三子;
  • 平局:棋盘已被占满且无胜利情况;
  • 继续:棋盘未占满且没有胜利情况;

我们规定

  • 如果玩家胜利,返回'*'
  • 如果电脑胜利,返回'#'
  • 如果平局,返回'E'
  • 如果继续,返回'C

用于在game.c中判定胜负

每一方行动完后,都要判定胜负。

char JudgeWin(char arr[ROW][COL], int x, int y)  //电脑赢# 玩家赢* 平局Q 未分胜负C
int i = 0;
	//judge row
	for (i = 0; i < x; i++)
	{
		if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][1] != ' ')
			return arr[i][1];//直接返回其中的字符,方便后续判定
	}
	//judge col
	for (i = 0; i < y; i++)
	{
		if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[1][i] != ' ')
			return arr[1][i];
	}
	//judge dia
	if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[1][1] != ' ')
		return arr[1][1];
	if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ')
		return arr[1][1];
	//判平和继续
	for (int i = 0; i < x; i++)
	{
		for (int n = 0; n < y; n++)
		{
			if (arr[i][n] == ' ')
				return 'C';
		}
	}
	return 'Q';
}

game()函数的组装

现在所有的函数都已经编写完毕了,只需要把这些函数都组装起来 。

void game()
{
	char ret = 0;
	char graph[ROW][COL] = { 0 };   //放在game函数内部!!
	Initgraph(graph,ROW,COL);
	Displaygraph(graph, ROW, COL);

	if (ret != 'C')
	{
		while (1)
		{
			PlayerMove(graph, ROW, COL);
			Displaygraph(graph, ROW, COL);
			ret = JudgeWin(graph, ROW, COL);
			if (ret != 'C')
				break;
			ComMove(graph, ROW, COL);
			Displaygraph(graph, ROW, COL);
			ret = JudgeWin(graph, ROW, COL);
			if (ret != 'C')
				break;
		}
	}
	if (ret != 'C')
	{
		if (ret == '*')
		{
			printf("玩家胜利\n");
			printf("\n");
		}
		else if (ret == '#')
		{
			printf("电脑胜利\n");
			printf("\n");
		}
		else if (ret == 'E')
		{
			printf("平局!\n");
			printf("\n");
		}
	}
}

全局展示

game.h:

#include
#include
#include
#include
#define _CRT_SECURE_NO_WARNINGS
#pragma once

#define ROW 3
#define COL 3
void menu()
{
	printf("*************************************\n");
	printf("********** 1.play  0.exit ***********\n");
	printf("*************************************\n");
}


void menu();

game.c:

#include"game.h"

void Initgraph(char arr[ROW][COL], int x, int y)
{
	for (int i = 0; i < x; i++)
	{
		for (int j = 0; j < y; j++)
		{
			arr[i][j] = ' ';
		}
	}
}
void Displaygraph(char arr[ROW][COL], int x, int y)
{
	for (int i = 0; i < x; i++)
	{
		for (int j = 0; j < y; j++)
		{
			printf(" %c ", arr[i][j]);
			if (j < y - 1)
				printf("|");
		}
		printf("\n");
		if (i < x - 1)
		{
			for (int  n = 0; n < x; n++)
			{
				printf("---");
				if (n < x - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}
void PlayerMove(char arr[ROW][COL], int x, int y)
{
	printf("请玩家下棋:>\n");
	int a = 0;
	int b = 0;
	while (1)
	{
		scanf("%d %d", &a, &b);
		if (a <= x && b <= y && arr[a - 1][b - 1] == ' ')
		{
			arr[a-1][b-1] = '*';
			break;
		}
		else
			printf("\n位置非法,请重新输入:>");
	}
}
void ComMove(char arr[ROW][COL], int x, int y)
{
	printf("电脑下棋:>\n");	
	int a, b;

	while (1)
	{
		a = rand() % x;
		b = rand() % y;
		if (arr[a][b] == ' ')
		{
			arr[a][b] = '#';
			break;
		}
	}
}

int even(char board[ROW][COL], int row, int col)//平局判定
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

char JudgeWin(char arr[ROW][COL], int x, int y)  //电脑赢# 玩家赢* 平局Q 未分胜负C
{
	int i = 0;
	//judge row
	for (i = 0; i < x; i++)
	{
		if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][1] != ' ')
			return arr[i][1];//直接返回其中的字符,方便后续判定
	}
	//judge col
	for (i = 0; i < y; i++)
	{
		if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[1][i] != ' ')
			return arr[1][i];
	}
	//judge dia
	if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[1][1] != ' ')
		return arr[1][1];
	if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ')
		return arr[1][1];
	//判平和继续
	for (int i = 0; i < x; i++)
	{
		for (int n = 0; n < y; n++)
		{
			if (arr[i][n] == ' ')
				return 'C';
		}
	}
	return 'Q';
}
void game()
{
	char ret = 0;
	char graph[ROW][COL] = { 0 };   //放在game函数内部!!
	Initgraph(graph,ROW,COL);
	Displaygraph(graph, ROW, COL);

	if (ret != 'C')
	{
		while (1)
		{
			PlayerMove(graph, ROW, COL);
			Displaygraph(graph, ROW, COL);
			ret = JudgeWin(graph, ROW, COL);
			if (ret != 'C')
				break;
			ComMove(graph, ROW, COL);
			Displaygraph(graph, ROW, COL);
			ret = JudgeWin(graph, ROW, COL);
			if (ret != 'C')
				break;
		}
	}
	if (ret != 'C')
	{
		if (ret == '*')
		{
			printf("玩家胜利\n");
			printf("\n");
		}
		else if (ret == '#')
		{
			printf("电脑胜利\n");
			printf("\n");
		}
		else if (ret == 'E')
		{
			printf("平局!\n");
			printf("\n");
		}
	}
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请输入(1/0):>\n");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			//三子棋游戏
			game();
			break;
		case 0:
			printf("游戏结束!\n");
			printf("三秒后退出游戏\n");
			Sleep(3000);
			break;
		default:
			printf("输入错误!\n");
			printf("请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

你可能感兴趣的:(学习感悟,游戏,c语言)