详解——如何C语言实现三子棋小游戏

目录

一、划分步骤

二、游戏的实现

1、整体框架:

2、游戏菜单

3、打印棋盘

4、玩家落棋(用 * 表示)

5、电脑落棋(用 @ 表示)

6、任意一方落棋之后判断赢家

三、代码

1、头文件:

2、功能实现:

3、程序测试:


三子棋这个小游戏虽然玩法简单,但是小时候的我们却常常乐在其中。

前两天在学习的时候,发现了很多人做这个小游戏,所以自己也想做一个简单的三子棋游戏,来重温小时候的乐趣,哈哈哈

一、划分步骤

想要实现这个小游戏,就先得了解在程序中应该如何玩(分为哪些步骤):

1、整体框架

2、游戏菜单

3、打印棋盘

4、玩家落棋

5、电脑落棋

6、任意一方落棋之后判断输赢

二、游戏的实现

1、整体框架:

先出现菜单并选择,“1”玩游戏;“0”退出游戏;其他输入错误重新输入。而且默认一直玩,直到选择退出游戏。

int main()
{
	int input = 0;
	do
	{
		menu();                    //菜单
		printf("请选择:>");
		scanf_s("%d", &input);
	
		switch(input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误\n");
			break;
		}
	} while (input);
	;
	return 0;
}

2、游戏菜单

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

3、打印棋盘

这是一个简单棋盘的图示,那么就需要一个二维数组去实现棋盘,然后对棋盘进行初始化和打印。

char Board[ROW][COL] = { 0 };      //二维数组表示棋盘,ROW和COL分别表示棋盘的行和列,
                                   //ROW和COL是用#define定义的两个符号,方便以后棋盘大小的改变    
InitBoard(Board, ROW, COL);        //初始化
PrintBoard(Board, ROW, COL);       //打印
void InitBoard(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++)
		{
			Board[i][j] = ' ';    //将数组中的所有元素都初始化为空格(如棋盘图示所示)
		}
	}
}

void PrintBoard(char Board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	int k = 0;
	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++)    //打印横向棋盘线,此时j已经跳出上次循环,此处可以用
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");        //棋盘的边框不用打印,所以最后一列不用打印棋盘线
				}
			}
			printf("\n");
		}
	}
}

4、玩家落棋(用 * 表示)

void Player(char Board[ROW][COL], int row, int col)        //输入坐标并将其替换并展示
{
	int x = 0;
	int y = 0;
	
	while (1)                                    //一直输入落子的位置坐标,直到落棋(break)
	{
		printf("请输入你选择的位置坐标\n");
		scanf_s("%d %d", &x, &y);
		if ((x > row) || (y > col) || (x < 0) || (y < 0))  //位置有效(在数组的范围内)
		{
			printf("输入位置有误,请重新输入\n");
		}
		else if (Board[x][y] == ' ')                       //同时该位置处没有棋子
		{
			Board[x][y] = '*';                             //落棋
			break;
		}
	}
}

5、电脑落棋(用 @ 表示)

void Computer(char Board[ROW][COL], int row, int col)   
{
	while (1)
	{
		srand((unsigned int)time(NULL)); //使用rand函数前必须调用srand函数,同时以time为时间种    
                                           子,用于生成随机数
		int x = rand() % row;            //用row和col对随机数进行取模,保证其在数组范围内
		int y = rand() % col;		     //rand函数用于生成两个随机数作为电脑此次落棋的位置坐标


		if (Board[x][y] == ' ')	        //通过if语句进行判断,如果这个位置不是空格,那么重新随机 
                                          生成坐标,直到填入@                       
		{
			Board[x][y] = '@';
			break;
		}
	}
}

6、任意一方落棋之后判断赢家

有三个相连的字符是相等的,则赢(包括行、列、对角线)

如果没人赢,看棋盘是否满了。如果满,则平局;如果未满,继续。

int FullBoard(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 -1;                 //有空格,棋盘未满
			}
		}
	}
	return 1;                              //没有空格,棋盘已经满了
}            



char CheckWiner(char Board[ROW][COL], int row, int col)    //判断赢家
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)        //判断行是否相等
	{
		if ((Board[i][0] == Board[i][1]) && (Board[i][1] == Board[i][2]) && (Board[i][2] != ' '))
			return Board[i][2];      //随便返回三者中的一个
	}
	for (i = 0; j < col; j++)        //判断列是否相等
	{
		if ((Board[0][j] == Board[1][j]) && (Board[1][j] == Board[2][j]) && (Board[2][j] != ' '))
			return Board[2][j];
	}
	if ((Board[0][0] == Board[1][1]) && (Board[1][1] == Board[2][2]) && (Board[2][2] != ' '))                                  //判断对角线是否相等
	{
		return Board[2][2];
	}
	 if ((Board[0][2] == Board[1][1]) && (Board[1][1] == Board[2][0]) && (Board[2][0] != ' '))                                //判断对角线是否相等
	{
		return Board[2][0];
	}
	 if (1 == FullBoard(Board, row, col))    //判断是否为平局
	 {
		 return 'e';                  //平局 
	}
	 else
	 {
		 return 'a';                  //不是平局,继续游戏
	 }
}

此时,各部分的程序已经完成。在实现程序时,我们将头文件、功能、测试分别放在不同的项目中,也方便检查修改。

三、代码

1、头文件:

#ifndef __SANZIQI_H__     //(#ifnedf  #define  #endif)防止头文件被重复使用
#define __SANZIQI_H__


#define ROW 3            //通过定义两个符号,来实现对数组大小的改变(棋盘大小)

#define COL 3

                         //对于各个函数的声明                         
void InitBoard(char Board[ROW][COL], int row, int col);

void PrintBoard(char Board[ROW][COL], int row, int col);

void Player(char Board[ROW][COL], int row, int col);

void Computer(char Board[ROW][COL], int row, int col);


char CheckWiner(char Board[ROW][COL], int row, int col);

#endif //__GAME-SANZIQI_H__

2、功能实现:

#include <stdio.h>
#include "sanziqi.h"            //自定义的头文件用""
#include <stdlib.h>
#include <time.h>

void InitBoard(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++)
		{
			Board[i][j] = ' ';
		}
	}
}

void PrintBoard(char Board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	int k = 0;
	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(char Board[ROW][COL], int row, int col)
//输入坐标并将其替换并展示
{
	int x = 0;
	int y = 0;
	
	while (1)
	{
		printf("请输入你选择的位置坐标\n");
		scanf_s("%d %d", &x, &y);
		if ((x > row) || (y > col) || (x < 0) || (y < 0))
		{
			printf("输入位置有误,请重新输入\n");
		}
		else if (Board[x][y] == ' ')
		{
			Board[x][y] = '*';
			break;
		}
	}
}


void Computer(char Board[ROW][COL], int row, int col)   
{
	while (1)
	{
		srand((unsigned int)time(NULL));//增加了随机性
		int x = rand() % row;
		int y = rand() % col;		//生成两个随机数作为电脑这一步的位置


		if (Board[x][y] == ' ')	//通过if语句进行判断,如果这个位置不是空格,那么重新随机生成坐标,直到填入@
		{
			Board[x][y] = '@';
			break;
		}
		
	}
	
}

int FullBoard(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 -1; //有空格,棋盘未满
			}
		}
	}
	return 1; //没有空格,棋盘已经满了
}



char CheckWiner(char Board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)//判断行是否相等
	{
		if ((Board[i][0] == Board[i][1]) && (Board[i][1] == Board[i][2]) && (Board[i][2] != ' '))
			return Board[i][2];  //随便返回三者中的一个
	}
	for (i = 0; j < col; j++)//判断列是否相等
	{
		if ((Board[0][j] == Board[1][j]) && (Board[1][j] == Board[2][j]) && (Board[2][j] != ' '))
			return Board[2][j];
	}
	if ((Board[0][0] == Board[1][1]) && (Board[1][1] == Board[2][2]) && (Board[2][2] != ' '))//判断对角线是否相等
	{
		return Board[2][2];
	}
	 if ((Board[0][2] == Board[1][1]) && (Board[1][1] == Board[2][0]) && (Board[2][0] != ' '))//判断对角线是否相等
	{
		return Board[2][0];
	}
	 if (1 == FullBoard(Board, row, col))
	 {
		 return 'e';
	}
	 else
	 {
		 return 'a';
	 }
}


3、程序测试:

#include <stdio.h>
#include "sanziqi.h"                       //也要引用头文件
#include <windows.h>

void menu()
{
	printf("******************\n");
	printf("**** 1.paly ******\n");
	printf("**** 0.exit ******\n");
	printf("******************\n");
}
void game()
{
	char c = 0;
	
	char Board[ROW][COL] = { 0 };
	InitBoard(Board, ROW, COL);
	PrintBoard(Board, ROW, COL);
	while (1)
	{
		Player(Board, ROW, COL);            //玩家走
		PrintBoard(Board, ROW, COL);        //打印棋盘
		printf("\n");
		c = CheckWiner(Board, ROW, COL);    //判断赢家
		if (c!= 'a')
		{
			break;
		}
		Sleep(800);                         //等一会儿
		Computer(Board, ROW, COL);          //电脑走
		PrintBoard(Board, ROW, COL);
		printf("\n");
		c = CheckWiner(Board, ROW, COL);
		if (c != 'a')
		{
			break;
		}
	}
	
		if (c == '*')
		{
			printf("玩家赢\n");
		}
		else if (c == '@')
		{
			printf("电脑赢\n");
		}

		else if (c == 'e')
		{
			printf("平局\n");
		}
}
int main()
{
	int input = 0;
	do
	{
		menu();//打印游戏菜单
		printf("请选择:>");
		scanf_s("%d", &input);
	
		switch(input)
		{
		case 1:
			
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误\n");
			break;
		}
	} while (input);
	;
	return 0;
}

我来玩一局:

   

哈哈哈,我赢啦。

虽然赢了,但是小时候的乐趣早已消失不见了。

惆怅,那我还是去吃饭吧,看能不能从中找出乐趣来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值