井字棋(棋子可消去(拿走))

设计题目:井字棋游戏设计与实现 游戏简介:一种在井字格上进行的连珠游戏,由分别代表O和X的两个游戏者轮流在格子里落子,任意三子形成一条直线,则为获胜。今天,小明发明了新玩法:①棋盘3x3大小,获胜条件不变;②当一方落下第4子仍未获胜时,则其落下的第1子会被拿掉,依次类推。

类似文章很多,但是可以拿走棋子的较少,故本文着重讲解拿走棋子部分

头文件

#include <stdio.h>
#include <windows.h>
#include<stdlib.h>//用于产生随机数

//全局变量
int QP[3][3];//棋盘,1为√,2为×,0为空
int qp1[8] = { 0 }, qp2[8] = { 0 };//用于存数以便于每六步消子
int player=1;//1为√ 玩家,2为× 玩家2或电脑
int cnt1=0,cnt2=0;

int judge_win();//判断输赢
void gotoxy(int x, int y);//跳转光标
void print_menu();//菜单
void print_box();//棋盘
void move_player1();//√下棋
void move_player2(int oder);//×下棋
int game(int oder);//游戏本体
void turn();//玩家状态
void updatebox();//更新棋盘
void xiaozi();//消去棋子

主函数

int main()
{
	int oder;
	system("mode con cols=90 lines=35");
begin:
	print_menu();
	scanf("%d", &oder);
	for (int a = 0; a < 3; a++)
		for (int b = 0; b < 3; b++)
			QP[a][b] = 0;//初始化a,b
	switch (oder)
	{
	case 0:
		return 0;
		break;
	case 1:
		game(oder);
		break;
	case 2:
		game(oder);
		break;
	default:
		printf("输入错误返回菜单\n");
		goto begin;
	}
	return 0;
}

拿走棋子:

原理:定义两个数组,用于存放已下棋子的坐标(qb1和qp2),然后用cnt来计数,当到了第四步(由于使用一维数组存数,故此时cnt=8)时,则将第一次所下棋子坐标赋值为0(代表此处没有棋子),并更新棋盘,后续步骤则用%来更新存放棋子坐标的数组(指qb1和qp2)

void xiaozi()
{
	if (cnt1 >= 8)
	{
		QP[qp1[(cnt1) %8]][qp1[((cnt1)%8+1)]] = 0;
		updatebox();
	}
	if (cnt2 >= 8)
	{
		QP[qp2[(cnt2) % 8]][qp2[((cnt2) % 8 + 1)]] = 0;
		updatebox();
	}
}

开始菜单

void print_menu()
{
	printf("请输入:\n1 玩家对战\n2 普通人机\n0 退出游戏\n");
}

打印棋盘 

void print_box()
{
	gotoxy(26, 5);
	printf("        ┃        ┃        ");
	gotoxy(26, 6);
	printf("        ┃        ┃        ");
	gotoxy(26, 7);
	printf("        ┃        ┃        ");
	gotoxy(26, 8);
	printf("━━━━━━━━╂━━━━━━━━╂━━━━━━━━");
	gotoxy(26, 9);
	printf("        ┃        ┃        ");
	gotoxy(26, 10);
	printf("        ┃        ┃        ");
	gotoxy(26, 11);
	printf("        ┃        ┃        ");
	gotoxy(26, 12);
	printf("━━━━━━━━╂━━━━━━━━╂━━━━━━━━");
	gotoxy(26, 13);
	printf("        ┃        ┃        ");
	gotoxy(26, 14);
	printf("        ┃        ┃        ");
	gotoxy(26, 15);
	printf("        ┃        ┃        \n");
}

玩家1移动

void move_player1()
{
	do
	{
	gotoxy(60, 15);
	printf("                              ");
	gotoxy(60, 6);
	printf("请输入x轴坐标:      ");
	gotoxy(60, 7);
	printf("请输入y轴坐标:      ");
	gotoxy(60, 6);
	int x, y;
	printf("请输入x轴坐标:");
	scanf("%d", &x);
	gotoxy(60, 7);
	printf("请输入y轴坐标:");
	scanf("%d", &y);
	if ((x > 3) || (x < 0) || (y < 0) || (y > 3))
	{
		gotoxy(60, 15);
		printf("x,y的值在1到3之间,请重输");
		continue;
	}
	if (QP[x - 1][y - 1] != 0)
	{
		gotoxy(60,15);
		printf("此处有棋子,请重输");
		continue;
	}
	else
	{
		QP[x - 1][y - 1] = 1;
		qp1[cnt1 %8] = x - 1;
		qp1[(cnt1+1)%8] = y - 1;
		break;
	}
	} while (1);
	updatebox();
	player = 

玩家二 

void move_player2(int oder)
{
	if (oder == 1) //玩家
	{
		do
		{
			gotoxy(60, 15);
			printf("                              ");
			gotoxy(60, 6);
			printf("请输入x轴坐标:      ");
			gotoxy(60, 7);
			printf("请输入y轴坐标:      ");
			gotoxy(60, 6);
			int x, y;
			printf("请输入x轴坐标:");
			scanf("%d", &x);
			gotoxy(60, 7);
			printf("请输入y轴坐标:");
			scanf("%d", &y);
			if ((x > 3) || (x < 0) || (y < 0) || (y > 3))
			{
				gotoxy(60, 15);
				printf("x,y的值在1到3之间,请重输");
				continue;
			}
			if (QP[x - 1][y - 1] != 0)
			{
				gotoxy(60, 15);
				printf("此处有棋子,请重输");
				continue;
			}
			else
			{
				QP[x - 1][y - 1] = 2;
				qp2[cnt2 % 8] = x - 1;
				qp2[(cnt2 + 1) % 8] = y - 1;
				break;
			}
		} while (1);
	}else if(oder==2)
	{
		while (1)
		{
			int x = rand() % 3;
			int y = rand() % 3;
			if (QP[x][y] == 0)
			{
				QP[x][y] = 2;
				break;
			}
		}
	}
	updatebox();
	player = 1;
}

 

 游戏体

int game(int oder)
{
	print_box();
	do
	{
		turn();//显示到谁
		move_player1();
		judge_win();
		if (judge_win() != 0)
			break;
		cnt1 += 2;
		xiaozi();
		
		turn();
		move_player2(oder);
		judge_win();
		if (judge_win() != 0)
			break;
		cnt2 += 2;
		xiaozi();
		
	} while (1);
	if (judge_win ()==1 )
		MessageBox(NULL, TEXT("√赢了"), TEXT("游戏结束"), 0);
	else if(judge_win ()==2)
		MessageBox(NULL, TEXT("×赢了"), TEXT("游戏结束"), 0);
	return 0;
}

打印游戏动态

void turn()
{
	gotoxy(60, 5);
	printf("     ");
	gotoxy(60, 5);
	if(player==1)
	printf("√");
	else if(player == 2)
		printf("×");
	gotoxy(63, 5);
	printf("走");
}

 更新棋盘

 

void updatebox()
{
	int a, b;//用于计算打印棋子的位置
	for(a=0;a<3;a++)
		for (b = 0; b < 3; b++)
		{
			if (QP[a][b] == 1)
			{
				gotoxy(30 + a * 8, 6 + b * 4);
				printf("√");
			}else if (QP[a][b] == 2)
			{
				gotoxy(30 + a * 8, 6 + b * 4);
				printf("×");
			}
			else if (QP[a][b] == 0)
			{
				gotoxy(30 + a * 8, 6 + b * 4);
				printf("   ");
			}
		}
}

判断输赢 

int judge_win()
{
	for (int r = 0; r < 3; r++)
	{
		//√赢返回1,×赢返回2
		//三横三竖的判断
		if (QP[r][0] == QP[r][1] && QP[r][2] == QP[r][1] && QP[r][1] == 1 || QP[0][r] == QP[1][r] && QP[2][r] == QP[1][r] && QP[1][r] == 1)
			return 1;
		if (QP[r][0] == QP[r][1] && QP[r][2] == QP[r][1] && QP[r][1] == 2 || QP[0][r] == QP[1][r] && QP[2][r] == QP[1][r] && QP[1][r] == 2)
			return 2;
	}
	if (QP[0][0] == QP[1][1] && QP[1][1] == QP[2][2] && QP[1][1] ==1 || QP[0][2] == QP[1][1] && QP[1][1] == QP[2][0] && QP[1][1] ==1)
		return 1;
	if (QP[0][0] == QP[1][1] && QP[1][1] == QP[2][2] && QP[1][1] ==2 || QP[0][2] == QP[1][1] && QP[1][1] == QP[2][0] && QP[1][1] == 2)
		return 2;
	return 0;
}

移动光标

void gotoxy(int x, int y)
{
	COORD pos = { x,y };
	HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hout, pos);//设置光标位置,并移动到相应位置
}//

 

总代码

#include <stdio.h>
#include <windows.h>
#include<stdlib.h>//用于产生随机数

//全局变量
int QP[3][3];//棋盘,1为√,2为×,0为空
int qp1[8] = { 0 }, qp2[8] = { 0 };//用于存数以便于每六步消子
int player=1;//1为√ 玩家,2为× 玩家2或电脑
int cnt1=0,cnt2=0;

int judge_win();//判断输赢
void gotoxy(int x, int y);//跳转光标
void print_menu();//菜单
void print_box();//棋盘
void move_player1();//√下棋
void move_player2(int oder);//×下棋
int game(int oder);//游戏本体
void turn();//玩家状态
void updatebox();//更新棋盘
void xiaozi();//消去棋子

int main()
{
	int oder;
	system("mode con cols=90 lines=35");
begin:
	print_menu();
	scanf("%d", &oder);
	for (int a = 0; a < 3; a++)
		for (int b = 0; b < 3; b++)
			QP[a][b] = 0;//初始化a,b
	switch (oder)
	{
	case 0:
		return 0;
		break;
	case 1:
		game(oder);
		break;
	case 2:
		game(oder);
		break;
	default:
		printf("输入错误返回菜单\n");
		goto begin;
	}
	return 0;
}

void print_menu()
{
	printf("请输入:\n1 玩家对战\n2 普通人机\n0 退出游戏\n");
}

void print_box()
{
	gotoxy(26, 5);
	printf("        ┃        ┃        ");
	gotoxy(26, 6);
	printf("        ┃        ┃        ");
	gotoxy(26, 7);
	printf("        ┃        ┃        ");
	gotoxy(26, 8);
	printf("━━━━━━━━╂━━━━━━━━╂━━━━━━━━");
	gotoxy(26, 9);
	printf("        ┃        ┃        ");
	gotoxy(26, 10);
	printf("        ┃        ┃        ");
	gotoxy(26, 11);
	printf("        ┃        ┃        ");
	gotoxy(26, 12);
	printf("━━━━━━━━╂━━━━━━━━╂━━━━━━━━");
	gotoxy(26, 13);
	printf("        ┃        ┃        ");
	gotoxy(26, 14);
	printf("        ┃        ┃        ");
	gotoxy(26, 15);
	printf("        ┃        ┃        \n");
}

void move_player1()
{
	do
	{
	gotoxy(60, 15);
	printf("                              ");
	gotoxy(60, 6);
	printf("请输入x轴坐标:      ");
	gotoxy(60, 7);
	printf("请输入y轴坐标:      ");
	gotoxy(60, 6);
	int x, y;
	printf("请输入x轴坐标:");
	scanf("%d", &x);
	gotoxy(60, 7);
	printf("请输入y轴坐标:");
	scanf("%d", &y);
	if ((x > 3) || (x < 0) || (y < 0) || (y > 3))
	{
		gotoxy(60, 15);
		printf("x,y的值在1到3之间,请重输");
		continue;
	}
	if (QP[x - 1][y - 1] != 0)
	{
		gotoxy(60,15);
		printf("此处有棋子,请重输");
		continue;
	}
	else
	{
		QP[x - 1][y - 1] = 1;
		qp1[cnt1 %8] = x - 1;
		qp1[(cnt1+1)%8] = y - 1;
		break;
	}
	} while (1);
	updatebox();
	player = 2;
}

void move_player2(int oder)
{
	if (oder == 1) //玩家
	{
		do
		{
			gotoxy(60, 15);
			printf("                              ");
			gotoxy(60, 6);
			printf("请输入x轴坐标:      ");
			gotoxy(60, 7);
			printf("请输入y轴坐标:      ");
			gotoxy(60, 6);
			int x, y;
			printf("请输入x轴坐标:");
			scanf("%d", &x);
			gotoxy(60, 7);
			printf("请输入y轴坐标:");
			scanf("%d", &y);
			if ((x > 3) || (x < 0) || (y < 0) || (y > 3))
			{
				gotoxy(60, 15);
				printf("x,y的值在1到3之间,请重输");
				continue;
			}
			if (QP[x - 1][y - 1] != 0)
			{
				gotoxy(60, 15);
				printf("此处有棋子,请重输");
				continue;
			}
			else
			{
				QP[x - 1][y - 1] = 2;
				qp2[cnt2 % 8] = x - 1;
				qp2[(cnt2 + 1) % 8] = y - 1;
				break;
			}
		} while (1);
	}else if(oder==2)
	{
		while (1)
		{
			int x = rand() % 3;
			int y = rand() % 3;
			if (QP[x][y] == 0)
			{
				QP[x][y] = 2;
				break;
			}
		}
	}
	updatebox();
	player = 1;
}

int game(int oder)
{
	print_box();
	do
	{
		turn();//显示到谁
		move_player1();
		judge_win();
		if (judge_win() != 0)
			break;
		cnt1 += 2;
		xiaozi();
		
		turn();
		move_player2(oder);
		judge_win();
		if (judge_win() != 0)
			break;
		cnt2 += 2;
		xiaozi();
		
	} while (1);
	if (judge_win ()==1 )
		MessageBox(NULL, TEXT("√赢了"), TEXT("游戏结束"), 0);
	else if(judge_win ()==2)
		MessageBox(NULL, TEXT("×赢了"), TEXT("游戏结束"), 0);
	return 0;
}

void turn()
{
	gotoxy(60, 5);
	printf("     ");
	gotoxy(60, 5);
	if(player==1)
	printf("√");
	else if(player == 2)
		printf("×");
	gotoxy(63, 5);
	printf("走");
}

void updatebox()
{
	int a, b;//用于计算打印棋子的位置
	for(a=0;a<3;a++)
		for (b = 0; b < 3; b++)
		{
			if (QP[a][b] == 1)
			{
				gotoxy(30 + a * 8, 6 + b * 4);
				printf("√");
			}else if (QP[a][b] == 2)
			{
				gotoxy(30 + a * 8, 6 + b * 4);
				printf("×");
			}
			else if (QP[a][b] == 0)
			{
				gotoxy(30 + a * 8, 6 + b * 4);
				printf("   ");
			}
		}
}

void xiaozi()
{
	if (cnt1 >= 8)
	{
		QP[qp1[(cnt1) %8]][qp1[((cnt1)%8+1)]] = 0;
		updatebox();
	}
	if (cnt2 >= 8)
	{
		QP[qp2[(cnt2) % 8]][qp2[((cnt2) % 8 + 1)]] = 0;
		updatebox();
	}
}

int judge_win()
{
	for (int r = 0; r < 3; r++)
	{
		//√赢返回1,×赢返回2
		//三横三竖的判断
		if (QP[r][0] == QP[r][1] && QP[r][2] == QP[r][1] && QP[r][1] == 1 || QP[0][r] == QP[1][r] && QP[2][r] == QP[1][r] && QP[1][r] == 1)
			return 1;
		if (QP[r][0] == QP[r][1] && QP[r][2] == QP[r][1] && QP[r][1] == 2 || QP[0][r] == QP[1][r] && QP[2][r] == QP[1][r] && QP[1][r] == 2)
			return 2;
	}
	if (QP[0][0] == QP[1][1] && QP[1][1] == QP[2][2] && QP[1][1] ==1 || QP[0][2] == QP[1][1] && QP[1][1] == QP[2][0] && QP[1][1] ==1)
		return 1;
	if (QP[0][0] == QP[1][1] && QP[1][1] == QP[2][2] && QP[1][1] ==2 || QP[0][2] == QP[1][1] && QP[1][1] == QP[2][0] && QP[1][1] == 2)
		return 2;
	return 0;
}

void gotoxy(int x, int y)
{
	COORD pos = { x,y };
	HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hout, pos);//设置光标位置,移动到
}//


本代码存在打印bug,有两段文字无法被打印

 本文为sztu学生张fm的大一上作业,要交给s小乐老师,为防止作业出现雷同特此声明,为完成博客任务不被卷死,只能发文来凑数.................

代码参考: https://b23.tv/9dCyt4B

实现若想要实现人工智能可参考(本代码无):(27条消息) 关于井字棋/三子棋的伪人工智能算法的实现_DanteKing的博客-CSDN博客_井字棋ai算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值