C语言实现井字棋游戏

前言:c语言是一门编程语言,可用于嵌入式系统以及游戏开发等领域,本文是运用c语言制作一个简易的井字棋游戏。

总体思路:创建界面-->创建并初始化二维数组(作为棋盘)-->打印棋盘-->玩家下棋逻辑-->电脑下棋逻辑-->判断胜负逻辑-->分出胜负并且重新回到游戏开始界面

.h文件如下:

#pragma once

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

#define ROW 3
#define COL 3

void print();
void play(char(*arr)[COL], int row, int col);

步骤1:

        界面的制作,并且设定好界面中的选项。这里用函数的形式将这个界面封装起来,如下图。这里我用的是do...while();循环配合上switch语句,保证玩了一把之后还能接着玩。

void print()
{
	printf("*************************\n");
	printf("*********1、paly*********\n");
	printf("*********0、exit*********\n");
	printf("*************************\n");

}
#include"game.h"

int main()
{
	char arr[ROW][COL];//二维数组创建(把他作为棋盘)
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		print();//界面函数
		printf("请选择选项:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			play(arr,ROW,COL);//游戏函数
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("非法输入,请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}


步骤2:

        在主函数创建一个二维数组,目的是将他当作井字棋的棋盘。当然,还要对他进行一系列的操作,例如:初始化,并对他加入一些棋盘的元素(比如:边界),让他变的像一个棋盘。

效果图:

        这里我选择游戏所以所需要的函数都封装在了case 1:play()这个函数当中,使主函数看起来更加简短。二维数组初始化代码:

void Init(char(*arr)[COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			*(*(arr + i) + j) = ' ';//初始化成空格的形式
		}
	}
	
}


步骤3:

        将初始化好的数组打印出来,并且加上棋盘的元素:这里为了视觉效果要注意“|”和“---”的循环打印次数,即最后一次不打印“|”和“---”。

void PrintBorad(char(*arr)[COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", *(*(arr+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:

        下棋逻辑:遵循着只有空格处才能下棋,落过子的地方不能再下子。并且注意用户理解:对棋盘的坐标是从1开始的,与我们对数组从0下标开始的理解不一样。

void PlayerInput(char(*arr)[COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家回合:\n");
	printf("请输入要下棋的坐标(中间用空格隔开):");
	while (scanf("%d%d", &x, &y)==2)
	{
		while (getchar() != '\n')
		{
			;
		}
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (arr[x - 1][y - 1] == ' ')//这样写就能够将用户理解的从1开始与数组从0从开始相对应
			{
				arr[x - 1][y - 1] = 'O';
				break;
			}
			else
				printf("此处已下过棋子,请重新下子:");
		}
		else
			printf("非法输入,请重新输入:");
	}
}

        接下来就是电脑下棋,为了让电脑能够自动下棋,因此需要生产一个随机值。这里用rand()与srand((unsigned int)time(NULL));这两个函数要互相搭配才能够生产随机值,注意:srand((unsigned int)time(NULL));写在主函数内,只需要运行一次即可。(电脑下棋无需考虑坐标开始问题)

void ComputerInput(char(*arr)[COL], int row, int col)
{
	printf("电脑回合:\n");
	while (1)
	{
		int x = rand() % 3;//生产0-2的随机数
		int y = rand() % 3;
		if (arr[x][y] != ' ')
		{
			continue;
		}
		else
		{
			arr[x][y] = 'X';
			break;
		}
		/*if (arr[x][y] == ' ')
		{
			arr[x][y] = 'X';
		}
		else
		{
			;
		}*/
	}
}


步骤5:

        判断胜负的函数,下棋的结果无非就是三种情况,胜、负、平局。对于井字棋而言,哪边优先完成3棵子的连续(竖、横、斜),就能获胜。若棋盘内下满了还没有一方能达到三子连续,则判为平局,否则为继续下棋。因此该函数需要返回一个内容告诉系统接下来的操作是什么(这里注意当都是空格时,也会判断为三子连续,因此要排除等于空格的情况)

char IsWin(char(*arr)[COL], int row, int col)//c继续 q平局 O玩家获胜 X电脑获胜
{
	int i = 0;
	int j = 0;
	char c = 'c';
	char q ='q';
	//斜线确定
	if (arr[0][0] == arr[1][1] && arr[1][1]== arr[2][2]&& arr[1][1] !=' ')
	{
		return arr[0][0];//返回坐标,更加省事
	}
	}
	else if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1]!=' ')
	{
		return arr[1][1];//返回坐标,更加省事
	}
	
	//行确定
	for ( i=0; i < row; i++)
	{
		int flag = 1;
		for ( j = 0; j < col-1; j++)
		{
			if (arr[i][j] != arr[i][j + 1] || arr[i][j] ==' ')
			{
				flag = 0;
			}
		}
		if (flag == 1)
		{
			return arr[i][j];//返回坐标,更加省事
	}
		}
	}
	
	//列确定
	for (j = 0; j < col; j++)
	{
		int flag = 1;
		for (i = 0; i< row - 1; i++)
		{
			if (arr[i][j] != arr[i+1][j] || arr[i][j] ==' ')
			{
				flag = 0;
			}
		}
		if (flag == 1)
		{
			return arr[i][j];//返回坐标,更加省事
	}
		}
	}

	//平局
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (arr[i][j] == ' ')
				return c;
		}
	}	
	return q;
}


步骤6:

        最后将这些功能按顺序放在一起即可,每一次与电脑下棋都是一个循环,判断胜负的函数就是跳出这个循环的条件,因此该函数接收到一个值后,会根据这个值再进行相关操作。

void play(char(*arr)[COL], int row, int col)
{
	Init(arr, row, col);//初始化
	PrintBorad(arr, row, col);//打印棋盘
	char poi = 0;
	while (1)
	{
		PlayerInput(arr, row, col);//玩家下棋
		PrintBorad(arr, row, col);
		poi = IsWin(arr, row, col);
		if (poi != 'c')//判断胜负
			break;

		ComputerInput(arr, row, col);//电脑下棋
		PrintBorad(arr, row, col);
		poi = IsWin(arr, row, col);//每一次下棋都会改变返回值,因此要再赋值给poi
		if (poi != 'c')//判断胜负
			break;

	}
	if (poi == 'O')
	{
		printf("玩家获胜!\n");
	}
	else if (poi == 'X')
	{
		printf("电脑获胜!\n");
	}
	else
	{
		printf("平局!\n");
	}
		
	
	
}

        这个也是整个游戏实现的逻辑方式,将上面的函数按顺序封装,并体现再这个game函数中就可以。

最终效果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安权_code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值