【C语言简陋实现小游戏】井字棋

【C语言简陋实现小游戏】井字棋

井字棋小游戏,是类似五子棋的一种棋类玩法:在一个井字棋盘中,双方依次落子,当一位玩家三子连成线,则该玩家获胜。

C语言实现井字棋游戏的界面:
选择序号 1:开始游戏开始游戏示例
选择序号 0:退出游戏退出游戏示例
选择其他序号:选择错误,需重新选择选择错误示例
即:井字棋游戏,执行代码后可直接进入游戏选择序号,然后执行相应序号的代码

可在do while循环内 使用 switch 语句来实现:

int main()
{
	int input = 0;
	do
	{
		//选择菜单
		printf("*********************************\n");
		printf("********     1. play     ********\n");
		printf("********     0. exit     ********\n");
		printf("*********************************\n");
		printf("请选择序号:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			//游戏本体函数
			game_main();
			break;
		case 0:
			printf("退出成功!");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while(input);

	return 0;
}

进入do while循环前,int 定义一个需要输入的整数变量 input。
因为 循环条件大于0 为真,所以可以直接用 input 作为循环条件的判断
**

  • input == 1,开始游戏,游戏结束后再次进入循环,可重复游玩
  • input == 0,退出游戏,循环条件判断为 假,退出循环,程序结束
  • input != 0 && input != 1,选择错误,循环条件判断为 真 ,进入下次循环

**
井字棋基本逻辑 和 代码 捋清楚之后,就可以写游戏的本体函数
我这里函数名 是 game_main()

下井字棋,需要一个二维数组来存放棋子,棋子和棋盘的显示,成如下形式:棋子和棋盘显示


首先,定义一个字符数组,并需要对字符数组进行全为 ‘ ’ 的初始化

	char board[3][3];
	//初始化 数组 函数
	InitiBoard(board, 3, 3);

定义一个 InitiBoard 函数来进行字符数组初始化 对数组遍历赋值

void InitiBoard(char board[3][3], 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] = ' ';		//遍历数组元素  赋值 ‘ ’ 		
				}
	 	}
 } 

初始化之后,将字符数组元素 和 棋盘打印出来

DispalyBoard(board, 3, 3);

定义一个 InitiBoard 函数 对 字符数组(棋子)和 棋盘 打印显示

void DisplayBoard(char board[3][3], int row, int col)
 { 	
 	int i = 0;
  	int j = 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)
	 		{
	 			int j = 0;
	 			for (j = 0; j < col; j++)
	 			{
					//棋子行 之间 需要分界线
					printf("---");
					if (j < col - 1)
						printf("|");
	 			} 			
				printf("\n"); 		
			} 	
		} 
 } 

上边 两个函数 在game_main() 游戏本体函数 使用后
选择序号 1 屏幕中显示:


接下来,由 玩家 和 电脑 依次下棋落子,落子后打印出棋盘,直到游戏结束
玩家落子 为 ‘ * ’,电脑落子 为 ‘ # ’
且 玩家落子的坐标 需合理
即,玩家 和 电脑 落子的执行 和 打印棋盘 需一直循环 除非游戏结束
每次落子后 我们对字符数组中的 棋子 进行计算,判断游戏是否结束
共自定义三个函数
玩家落子:PlayerMove()
电脑落子:ComputerMove()
判断游戏是否结束:IsWin()

char ret;
while (1)
{
	//玩家下棋
	PlayerMove(board, 3, 3);
	DisplayBoard(board, 3, 3);
	//判断 游戏的进程  游戏是否结束
	ret = IsWin(board, 3, 3);
	if (ret != 'C')
		break;
	//电脑下棋
	ComputerMove(board, 3, 3);
	DisplayBoard(board, 3, 3);
	//判断 游戏的进程  游戏是否结束
	ret = IsWin(board, 3, 3);
	if (ret != 'C')
		break;			
	//设定  IsFull() 函数
	//返回值为 '*' 玩家赢
	//返回值为 '#' 电脑赢
	//返回值为 'Q' 平局
	//返回值为 'C' 游戏继续
}

玩家落子 的函数:PlayerMove()

void PlayerMove(char board[3][3], int row, int col)
{
 	int x = 0;
	int y = 0;
 	printf("玩家走:>\n");
  	while (1)
   	{
   		printf("请输入坐标:>");
		scanf("%d %d", &x, &y);
 		//判断玩家落子是否在 棋盘内  即,玩家落子是否合理
  		if (x >= 1&& x <= row && y >= col && y <= 3)
   		{ 
   			//判断 玩家落子坐标是否已经被落子
    		if (board[x-1][y-1] == ' ')
    		{
				board[x-1][y-1] = '*';
				break;
 			} 
 			//玩家落子坐标已被落子,重新输入坐标
  			else
				printf("坐标占用,请重新输入!\n");
 		}
  		//玩家落子坐标非法,重新输入坐标
   		else
    		printf("非法坐标,请重新输入!\n");
  	} 
} 

电脑自动落子 函数:ComputerMove()

void ComputerMove(char board[3][3], int row, int col)
 { 	
 //最简单的下棋 电脑 无算法,完全随机落子
  	printf("电脑走:>\n");
   	while (1)
   	{
     	int x = rand() % row;		//用 rand 随机生成坐标x
      	int y = rand() % col;		//用 rand 随机生成坐标y
       	//rand 函数取随机值 的使用 可详见 本人另一篇 博客,链接放在最下方

		//判断 电脑落子坐标是否已经被落子
 		if (board[x][y] == ' ')
  		{
   			board[x][y] = '#'; 
   			break;
    	}
	}
} 

判断棋局进程 函数:IsWin()
在判断棋局的进程时,若无人获胜,还需判断棋盘是否下满,下满则平局,未下满则游戏继续( 需 自定义 IsFull() 函数 判断棋盘是否下满

 //设定
 //返回值为 '*' 玩家赢
 //返回值为 '#' 电脑赢
 //返回值为 'Q' 平局
 //返回值为 'C' 游戏继续
char IsWin(char board[3][3], int row, int col)
{
 	int i = 0;
  	int j = 0;
   	//循环判断 1-3 行 的棋子是否相同
   	for (i = 0; i < row; i++)
    {
   		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
   			//若有棋子连成一线  返回该棋子 即可
    		return board[i][1];
  	} 	
 	 //循环判断 1-3 列 的棋子是否相同
  	for (j = 0; j < col; j++)
   	{
   		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ') 						
  			 //若有棋子连成一线 返回该棋子 即可
   			return board[1][j];
   	}
   	//循环判断 2条对角线 的棋子是否相同
	if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
 		//若有棋子连成一线  返回该棋子 即可
  		return board[1][1];
   	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    	//若有棋子连成一线  返回该棋子 即可
     	return board[1][1];
      	//判断平局
       	// IsFull 返回值 为 1 棋盘满  平局
       	//		  返回值 为 0 棋盘未满  游戏继续
       	int ret = IsFull(board, row, col);
        	if (ret == '1') 
        		return 'Q';

		return 'C';
 }

棋盘是否下满的判断 函数:IsFull()

int IsFull(char board[3][3], int row, int col)
{
 	int i = 0;
  	int j = 0;
   	//遍历棋盘 判断 是否数组中是否有元素 为 ‘ ’
    //若有 返回 0,表示棋盘未满
    //若无 返回 1,表示棋盘已满
	for (i = 0; i < row; i++)
	{
 		for (j = 0; j < col; j++)
  		{
   			if (board[i][j] == ' ') 
   			{
				return '0';
				break; 
			} 
		} 
	} 
	return '1';		//上 循环中 未返回 0 ;  则返回 1 
}

接下来,由 ret 的值 判断 输赢

if (ret == '*')
	printf("玩家赢了!\n");
else if (ret == '#')
	printf("电脑赢了!\n");
else
	printf("平局!\n");
DisplayBoard(board, 3, 3);
printf("\n");

至此,game_main() 内容为:

void game_main()
{
	int j = 0;
	int i = 0;
	char ret;
	char board[3][3];
	//初始化 数组
	InitiBoard(board, 3, 3);
	//打印 棋盘
	DisplayBoard(board, 3, 3);
	while (1)
	{
		//玩家下棋
		PlayerMove(board, 3, 3);
		DisplayBoard(board, 3, 3);
		//判断 棋局输赢
		ret = IsWin(board, 3, 3);
		if (ret != 'C')
			break;
		//电脑下棋
		ComputerMove(board, 3, 3);
		DisplayBoard(board, 3, 3);
		//判断 棋局输赢
		ret = IsWin(board, 3, 3);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家赢了!\n");
	else if (ret == '#')
		printf("电脑赢了!\n");
	else
		printf("平局!\n");
	DisplayBoard(board, 3, 3);
	printf("\n");
}

游戏所需函数 等 编写完成;
可整合至项目中:
游戏各自定义函数 代码文件:chess_function.c

#include "chess_10_8.h"

//初始化棋盘 函数
void InitiBoard(char board[3][3], 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 DisplayBoard(char board[3][3], int row, int col)
{
	int i = 0;
	int j = 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)
		{
			int j = 0;
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

//玩家落子 函数
void PlayerMove(char board[3][3], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家走:>\n");
	while (1)
	{
		printf("请输入坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x-1][y-1] == ' ')
			{
				board[x-1][y-1] = '*';
				break;
			}
			else
				printf("坐标占用,请重新输入!\n");
		}
		else
			printf("非法坐标,请重新输入!\n");
	}
}

//电脑落子 函数
void ComputerMove(char board[3][3], int row, int col)
{
	printf("电脑走:>\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

int IsFull(char board[3][3], 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';
				break;
			}
		}
	}
	return '1';
}



//返回值为 '*' 玩家赢
//返回值为 '#' 电脑赢
//返回值为 'Q' 平局
//返回值为 'C' 游戏继续
//判断棋局输赢 函数
char IsWin(char board[3][3], 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][1] != ' ')
			return board[i][1];	
	}
	//判断 列
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
			return board[1][j];
	}
	//判断 对角线
	if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
		return board[1][1];
	//判断 平局
	// IsFull 返回值 为 1 棋盘满  平局
	//		  返回值 为 0 期盼未满  游戏继续
	int ret = IsFull(board, row, col);
	if (ret == '1')
		return 'Q';

	return 'C';
}


//游戏主体函数
void game_main()
{
	int j = 0;
	int i = 0;
	char ret;
	char board[3][3];
	//初始化 数组
	InitiBoard(board, 3, 3);
	//打印 棋盘
	DisplayBoard(board, 3, 3);
	while (1)
	{
		//玩家下棋
		PlayerMove(board, 3, 3);
		DisplayBoard(board, 3, 3);
		ret = IsWin(board, 3, 3);
		if (ret != 'C')
			break;
		//电脑下棋
		ComputerMove(board, 3, 3);
		DisplayBoard(board, 3, 3);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家赢了!\n");
	else if (ret == '#')
		printf("电脑赢了!\n");
	else
		printf("平局!\n");
	DisplayBoard(board, 3, 3);
	printf("\n");
}

游戏各自定义函数的引用 头文件:chess_function.h

#pragma once

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

void InitiBoard(char board[3][3], int row, int col);		//初始化数组的函数

void DisplayBoard(char board[3][3], int row, int col);		//打印棋盘的函数

void PlayerMove(char board[3][3], int row, int col);		//玩家下棋

void ComputerMove(char board[3][3], int row, int col);		//电脑下棋

char IsWin(char board[3][3], int row, int col);				//判断输赢的返回值

int IsFull(char board[3][3], int row, int col);				//判断棋盘 是否满

游戏的主函数文件:chess_game_main.c

#include "chess_10_8.h"

int main()
{
	int input = 0;
	//随机值前的调用
	srand((unsigned int)time(NULL));
	do
	{
		//选择菜单
		printf("*********************************\n");
		printf("********     1. play     ********\n");
		printf("********     0. exit     ********\n");
		printf("*********************************\n");
		
		printf("请选择序号:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			//游戏本体函数
			game_main();
			break;
		case 0:
			printf("退出成功!");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while(input);

	return 0;
}

游戏实现
Gitee :https://gitee.com/xyt-g/problem-of-learning/tree/%E5%AD%A6%E4%B9%A0%E6%97%B6%E5%9C%B0%E7%BB%83%E4%B9%A0%EF%BC%8C%E8%AE%B0%E5%BF%86/%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BF%86/%E4%BA%95%E5%AD%97%E6%A3%8B%E6%B8%B8%E6%88%8F

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值