用C语言实现三子棋

1.三子棋是什么,用C语言该如何解释

三子棋,民间传统游戏, 双方轮流在格子里摆放棋子,先连成三棋一线者视为胜利 ,棋盘被摆满棋子仍未分出胜利,视为平局。如果两个人都掌握了技巧,那么一般来说就是平棋。一般来说,下在中间最有利,下在角上次之,下在边上再次之。

 那么该如何用C语言来实现呢?三子棋其中的纵横线我们可以用 '|'和'-'打印,然后其中的棋子可以定义一个字符数组,先全部初始化为" ",只要玩家或者电脑输入坐标(落子在第几行第几列),就在对应的字符数组中将' '字符赋值为'*'或'#',没下完一次棋就将棋盘打印,并且判断输赢还是平局,否则继续游戏。

2.主函数

#include "game.h" //为了方便所有的头文件和函数定义都在game.h中,这个头文件是我们自己定义
//的所以包含它是应该用" ",当头文件是标准库函数的时候才是用<>
int main()
{
	int input=0;  
	int output = 0; 
	srand((unsigned int)time(NULL)); 
	menu(); //开始菜单函数
	do {
		if (output == 1) //我只想让玩家玩一次,游戏结束后,output就赋值为1,就退出
		{
			printf("\n游戏结束\n");
			break;
		}
		scanf("%d", &input);  //输入菜单上的选项
		switch (input)
		{
		case 1:
			game();  //游戏函数
			output = 1; 
			break;
		case 0:
			break;  //退出游戏
		default:
			printf("请选择正确的选项(1/0):");
			break;
		}
	} while (input);
	if(output!=1)  //如果output!=0,说明没玩并且选择0退出
	    printf("退出成功!\n");

	Sleep(3000);  //睡眠3秒,3000的单位是ms,可以让退出的时候不会一下子消失 
	return 0;
}

srand函数详见https://www.runoob.com/cprogramming/c-function-srand.html

3.头文件

#pragma once  //默认存在


#include <stdio.h>
#include <time.h> //time函数包含的头文件
#include <stdlib.h> //srand函数包含的头文件
#include <windows.h> //Sleep函数包含的头文件

#define R 3  //棋盘的行数
#define C 3 //棋盘的列数

void game(); 
void menu(); 
void InitBoard(char board[R][C], int r, int c); //初始化棋盘
void DisplyBoard(char board[R][C], int r, int c); //打印棋盘
void Player_play(char board[R][C],int r,int c);  //玩家下棋
void Computer_play1(char board[R][C],int r,int c);  //难度0的电脑下棋
void Computer_play2(char board[R][C],int r, int c,int fir_st); //难度为1的电脑下棋
char Judge_Win(char board[R][C], int r, int c); //判断输赢平局还是继续游戏
int Is_Full(char board[R][C], int r, int c); //判断棋盘是否铺满了

4.game函数

void game()
{
	char board[R][C],ch;
	int r = R, c = C,dif=0,st=0;  //st变量,如果玩家第一次下在中间,st++;
	printf("请选择游戏难度(0/1):");
	while (1)
	{	scanf("%d", &dif); //游戏难度选择
		switch (dif)
		{
		case 0:break;
		case 1:break;
		default:printf("请选择正确的选项(0/1): ");continue;
		}
		break;
	}
	system("cls");  //清空屏幕
	InitBoard(board,r,c);
	DisplyBoard(board,r,c); 
	if (dif == 0)  //难度0
	{
		while (1)
		{
			Player_play(board, r, c);  //玩家先手
			system("cls");
			DisplyBoard(board, r, c);
			ch=Judge_Win(board, r, c);  //没落一只,就判断输赢函数
			if (ch != 'C')  
				break;
			Computer_play1(board, r, c);
			DisplyBoard(board, r, c);
			ch = Judge_Win(board, r, c);
			if (ch != 'C')
				break;
		}
	}
	else  //难度1
	{
		while (1)
		{
			Player_play(board, r, c);
			if (board[1][1] == '*')
				st ++;
			system("cls");
			DisplyBoard(board, r, c);
			ch = Judge_Win(board, r, c);
			if (ch != 'C')
				break;
			Computer_play2(board, r, c,st);
			st = -2;  //赋值为-2,st就再也不会=1,保证只使用一次
			DisplyBoard(board, r, c);
			ch = Judge_Win(board, r, c);
			if (ch != 'C')
				break;
		}
	}
	if (ch == '*')  //根据判断输赢函数的返回值打印
		printf("你赢了!");
	else if (ch == '#')
		printf("电脑玩家获胜!");
	else if(ch=='Q')
		printf("势均力敌");
}

5.游戏菜单函数


void menu()
{
	printf("****游戏菜单*****\n");
	printf("****1.三子棋*****\n");
	printf("****0.离开游戏***\n");
	printf("*****************\n\n");
	printf("请选择:");
}

6.初始化函数

void InitBoard(char board[R][C],int r, int c)
{
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
			board[i][j] = ' '; //将棋盘初始化为空
}

7.打印棋盘函数

void DisplyBoard(char board[R][C], int r, int c)
{
	printf("\n");
	for (int i=0; i < r; i++)
	{
		printf(" %c | %c | %c ",board[i][0],board[i][1],board[i][2]);
		if(i<2)  //第三行就不打印了
		printf("\n---|---|---\n");
	}
	printf("\n");
}

8.玩家下棋函数

void Player_play(char board[R][C], int r, int c)
{
	int x=0, y=0;
	printf("\n你想下在哪,请输入落子坐标(中间用空格隔开): ");
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x>=1&&x<=3&&y>=1&&y<=3)  //确保坐标正确
		{
			if (board[x - 1][y - 1] == ' ') //如果这位置没棋子才能下
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
				printf("该位置已有棋子,请重新选择坐标: ");
		}
		else 
			printf("坐标范围(行(1~3),列(1~3)),请重新输入:");
	}
}

9.判断局势函数

//返回'*',玩家赢/返回'#',电脑玩家获胜/返回 'Q',平局/返回'C',继续游戏
char Judge_Win(char board[R][C], int r, int c)
{
	r = R, c = C;
	int i = 0;
	for (i = 0; i < r; i++) 
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
			return board[i][0];
	}
	for (i = 0; i < c; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
			return board[0][i];
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
		return board[0][0];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
		return board[1][1];
//只要有连成3子的,就返回它的符号
	if (Is_Full(board, r, c)==0)  //没下满,继续游戏
		return 'C';
	else if (Is_Full(board, r, c) == 1)  //棋盘满了,平局
		return 'Q';

}

10.判断棋盘是否满了函数

int Is_Full(char board[R][C], int r, int c)
{
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
		{
			if (board[i][j] == ' ')  //只要有空位,就返回0
				return 0;
		}
	return 1;  //说明棋盘满了
}

11.难度0的电脑下棋函数

void Computer_play1(char board[R][C], int r, int c)
{
	int x = 0, y = 0;
	printf("电脑正在思考中...\n");
	Sleep(3000);  //睡眠3s,模拟电脑思考
	while(1)
	{
		x = rand() % 3; //模3,代表0~2的随机数
		y = rand() % 3;
		if (board[x][y] == ' ')  //位置为空
		{
			board[x][y] = '#';
			break;
		}
		else
			continue;
	}
	system("cls");
}

rand函数详见https://www.runoob.com/cprogramming/c-function-rand.html

12.难度为1的电脑下棋函数

char co_board[R][C] = { " " };  //这是对棋盘的拷贝数组,等会有用
void Computer_play2(char board[R][C], int r, int c,int fir_st)
{
	if (fir_st == 1)  //这是game函数中的st,如果玩家第一步下了中间,那么电脑就会下四个角
	{
		while(1)
		{
			int x = rand() % 3;
			int y = rand() % 3;
			if (x == 1 || y == 1)  //如果将下的位置不在四角,就继续随机
				continue;
			else
			{
				board[x][y] = '#'; goto end; //电脑下完棋,就结束,去end(在最后面)
			}		
		}
	}
	if (fir_st==0) //如果玩家第一步没有下在中间,电脑就随机两种方式下棋
	{
		int choi = rand() % 2; //产生0~1的随机数
		if (choi == 0) //随机数为0
		{
            board[1][1] = '#'; goto end; //下在中间
			
		}
		if (choi == 1) //随机数为1
		{
				while (1)
				{
					int x = rand() % 3;
					int y = rand() % 3; 
					if (board[x][y] == ' ') //随机下棋
					{
						board[x][y] = '#';
						goto end;
					}
					else
						continue;
				}
				system("cls");
		}
	}
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
			co_board[i][j] = board[i][j];  //将棋盘一一赋值给拷贝棋盘co_board
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
		{
			if (board[i][j] == ' ')  //找到棋盘上的空位
			{
				co_board[i][j] = '#';  //将拷贝棋盘上的这个空位赋值电脑的棋子
				if (Judge_Win(co_board, r, c) == '#') //如果下完这步电脑赢了,那么就下这步
				{
					board[i][j] = '#';
					goto end;
				}
				co_board[i][j] = '*';//将拷贝棋盘上的这个空位赋值玩家的棋子
				
				char c = ' ';
				 c= Judge_Win(co_board, r, c);
				if (Judge_Win(co_board, r, c) == '*')//如果下完这步玩家赢了,那么就下这步
//堵玩家
				{
					board[i][j] = '#';
					goto end;
				}
				co_board[i][j] = ' ';
				continue;
			}
		}
	
	while (1) //如果空位不能让玩家赢或者电脑赢就随机下棋
	{
		int x = rand() % 3;
		int y = rand() % 3;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
end:
	printf("电脑正在思考中...\n");
	Sleep(3000);
	system("cls");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值