【C语言】实现三字棋

大家好,最近一直在学习C语言的相关知识,今天分享的是C语言中的三子棋代码与思路

首先分为头文件game.h 和game.c与test.c三个文件  

目录

 1、菜单界面

2、玩家选择游戏界面

3、初始化三子棋棋盘

4、打印棋盘

5、玩家下棋

6、电脑下棋

 7、判断输赢 已经平局的函数

判断棋盘是否满的函数

在test.c中的game函数中调用

整体程序实现

test.c  

game.c

game.h


 1、菜单界面

void menu()
{


	printf("*****************************\n");
	printf("*****************************\n");
	printf("*******1、play    ***********\n");
	printf("*******0、exit    ***********\n");
	printf("*****************************\n");
	printf("*****************************\n");
	printf("*****************************\n");


}

2、玩家选择游戏界面

玩家输入0/1进入游戏  调用菜单界面  选择1调用game函数开始游戏   选择0退出游戏

int main()
{

	int input = 0;
	srand((unsigned int)time(NULL));  //记得包含两个头文件
	do
	{
		menu();  //先是打印菜单
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("输入错误,请重新输入!\n");
				break;
		}

	} while (input);

	return 0;
}

3、初始化三子棋棋盘

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

		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';  //这是字符  不是字符串!!!!
		}
	}
}

初始化二维数组   这里将遍历的行、列数组全部用字符‘ ’(字符空格)初始化

4、打印棋盘

void display(char board[ROW][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 ", 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");

		}

	}

}

这里将三子棋“井”字框架搭建起来

 

5、玩家下棋

void player_move(char board[ROW][COL], int row, int col)  //玩家下棋
{
	
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("玩家下棋:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')    //因为玩家是送1开始的  数组的坐标是从0开始的 所以必须减1
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标已满,请重新输入!");
			}
		}
		else
		{
			printf("输入的坐标非法,请重新输入");
		}
	}
	

}

这里输入坐标,将‘  ’位置换成‘*’ 并加入判断语句 ,如果输入的坐标不符合条件范围则坐标非法,如果输入的坐标没有‘ ’,则说明此坐标已经被占用。

6、电脑下棋

#include<stdlib.h>
#include<time.h>
void computer_move(char board[ROW][COL], int row, int col)  //电脑下棋
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:\n");
	while (1)
	{
		x = rand() % row; //  0~2 随机数
		y = rand() % col; //  0~2 随机数
		if (board[x ][y ] == ' ')   //0~2的随机数 这时坐标就不能在减1
		{
			board[x][y] = '#';
			break;
		}
	}


}

电脑下棋需要生成随机的坐标  这里用到随机函数,这样对行、列取模  得到的是0~2的随机数,在坐标中while循环填入  ,填入后退出循环。

 7、判断输赢 已经平局的函数

int iswin(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][0];    //这里返回i行的几列都行 结果都是相同的
		}
	}

	for (j = 0; j < col; j++)  
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ')//判断列
		{
			return board[0][j];    //这里返回j列的几行都行 结果都是相同的
		}
	}

	if (board[0][0] == board[1][1]&& board[1][1 ]== board[2][2] && board[2][2] != ' ')    //判断对角线
	{
		return board[0][0];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ')
	{
		return board[2][0];
	}

	if (isfull(board, ROW, COL) == 1)   //如果满了 用Q表示
	{
		return 'Q';
	}
	
	return 'C';       //没满 继续 用C表示
	
}

此函数通过判断行、判断列、判断对角线是否相等且不等于‘ ’,来判断是否满足获胜条件 如果满足则返回结果  ‘*’说明玩家赢  ‘#’说明电脑赢  返回‘Q’说明棋盘已满 说明是平局  如果以上条件都没满足则返回‘C’,游戏继续 玩家与电脑继续输入

判断棋盘是否满的函数

static int isfull(char board[ROW][COL], int row, int col)
{

	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;

		for (j = 0; j < col; j++)
		{
			if (board[i][j]==' ')
			{
				return 0;   //返回0说明没满  返回1说明满了
			}
		}
	}
	return 1;
}

此函数用来判断棋盘是否满  如果有‘ ’说明没满返回0   不满足说明满了 返回1   同时此函数加入static说明在头文件和test.c中都可以不出现 只用在iswin函数内部就行

以上就是游戏的基本逻辑了

在test.c中的game函数中调用

void game()
{
	char ret = '0';//初始化字符ret
	char board[ROW][COL] = { 0 };
	initboard(board, ROW, COL);   //初始化棋盘
	display(board, ROW, COL);     //打印棋盘 
	while (1)
	{
		player_move(board, ROW, COL);//玩家下棋
		display(board, ROW, COL);     //打印棋盘 
	    ret = iswin(board, ROW, COL); //输赢结果判断
		if (ret != 'C')   //如果不继续 要不棋盘满了 要不电脑或者玩家赢了 退出循环
		{
			break;
		}
		computer_move(board, ROW, COL);//电脑下棋
		display(board, ROW, COL);     //打印棋盘 
		ret = iswin(board, ROW, COL); //输赢结果判断
		if (ret != 'C')   //如果不继续 要不棋盘满了 要不电脑或者玩家赢了 退出循环
		{
			break;
		}

	}
	if (ret == '*')
	{
		printf("玩家获胜!\n");
	}
	else if (ret == '#')
	{
		printf("电脑获胜!\n");
	}
	else if (ret == 'Q')
	{
		printf("平局!\n");
	}


}

整体程序实现

test.c  

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

void menu()
{


	printf("*****************************\n");
	printf("*****************************\n");
	printf("*******1、play    ***********\n");
	printf("*******0、exit    ***********\n");
	printf("*****************************\n");
	printf("*****************************\n");
	printf("*****************************\n");


}

void game()
{
	char ret = '0';//初始化字符ret
	char board[ROW][COL] = { 0 };
	initboard(board, ROW, COL);   //初始化棋盘
	display(board, ROW, COL);     //打印棋盘 
	while (1)
	{
		player_move(board, ROW, COL);//玩家下棋
		display(board, ROW, COL);     //打印棋盘 
	    ret = iswin(board, ROW, COL); //输赢结果判断
		if (ret != 'C')   //如果不继续 要不棋盘满了 要不电脑或者玩家赢了 退出循环
		{
			break;
		}
		computer_move(board, ROW, COL);//电脑下棋
		display(board, ROW, COL);     //打印棋盘 
		ret = iswin(board, ROW, COL); //输赢结果判断
		if (ret != 'C')   //如果不继续 要不棋盘满了 要不电脑或者玩家赢了 退出循环
		{
			break;
		}

	}
	if (ret == '*')
	{
		printf("玩家获胜!\n");
	}
	else if (ret == '#')
	{
		printf("电脑获胜!\n");
	}
	else if (ret == 'Q')
	{
		printf("平局!\n");
	}


}


int main()
{

	int input = 0;
	srand((unsigned int)time(NULL));  //记得包含两个头文件
	do
	{
		menu();  //先是打印菜单
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("输入错误,请重新输入!\n");
				break;
		}

	} while (input);

	return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1


#include"game.h"


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

		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';  //这是字符  不是字符串!!!!
		}
	}
}

void display(char board[ROW][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 ", 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)  //玩家下棋
{
	
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("玩家下棋:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')    //因为玩家是送1开始的  数组的坐标是从0开始的 所以必须减1
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标已满,请重新输入!");
			}
		}
		else
		{
			printf("输入的坐标非法,请重新输入");
		}
	}
	

}

void computer_move(char board[ROW][COL], int row, int col)  //电脑下棋
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:\n");
	while (1)
	{
		x = rand() % row; //  0~2 随机数
		y = rand() % col; //  0~2 随机数
		if (board[x ][y ] == ' ')   //0~2的随机数 这时坐标就不能在减1
		{
			board[x][y] = '#';
			break;
		}
	}


}

//封装一个棋盘满的函数  并且不给头文件用  前面加上static
static int isfull(char board[ROW][COL], int row, int col)
{

	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;

		for (j = 0; j < col; j++)
		{
			if (board[i][j]==' ')
			{
				return 0;   //返回0说明没满  返回1说明满了
			}
		}
	}
	return 1;
}
int iswin(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][0];    //这里返回i行的几列都行 结果都是相同的
		}
	}

	for (j = 0; j < col; j++)  
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ')//判断列
		{
			return board[0][j];    //这里返回j列的几行都行 结果都是相同的
		}
	}

	if (board[0][0] == board[1][1]&& board[1][1 ]== board[2][2] && board[2][2] != ' ')    //判断对角线
	{
		return board[0][0];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ')
	{
		return board[2][0];
	}

	if (isfull(board, ROW, COL) == 1)   //如果满了 用Q表示
	{
		return 'Q';
	}
	
	return 'C';       //没满 继续 用C表示
	
}

game.h

#pragma once


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

#define ROW 3
#define COL 3

void initboard(char board[ROW][COL], int row, int col);        //初始化棋盘

void display(char board[ROW][COL], int row, int col);     //打印棋盘

void player_move(char board[ROW][COL], int row, int col);    //玩家下棋

void computer_move(char board[ROW][COL], int row, int col);//电脑下棋

int iswin(char board[ROW][COL], int row, int col);       //输赢结果

头文件主要包括函数的声明和库函数头文件

以上就是实现三字棋的全部代码

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值