五子棋---巧妙判断

五子棋的编写与三子棋相同,只不过输赢判断较为麻烦,我采用字符a和b代表不同的两子,用strstr寻找子串的方式判断输赢。这样与遍历相比就显得十分简单。与扫雷相同,要采用扩大数组的方式便于计算。代码如下

#define ROW 20 //显示行数
#define COL 20 //显示列数
#define ROWS ROW+8 //存储行数
#define COLS COL+8 //存储列数
#define DE 4 //相差的值
//这里我指使用了一个数组,也可以用两个数组实现

#include<stdio.h>
#include<Windows.h>
#include<time.h>
#include<string.h>
#include<stdbool.h>

void Initboard(char board[ROWS][COLS], int row, int col); //初始化棋盘
void Displayboard(char board[ROWS][COLS], int row, int col); //打印显示棋盘
int Playermove(char board[ROWS][COLS],char sb); //玩家下棋移动
int computermove(char board[ROWS][COLS],char sb); //电脑下棋移动
int Getresult(char board[ROWS][COLS], int x, int y, char sb); //判断输赢
bool Isfull(char board[ROWS][COLS]); //判断棋盘十否已满

//
//
//

void menu()
{
	printf("*******************************************\n");
	printf("*************     五子棋      *************\n");
	printf("************* 1.Play   0.exit *************\n");
	printf("*******************************************\n");
}
void game()
{
	int ret;
	char choice;
	char board[ROWS][COLS] = {0};
a:	Initboard(board, ROWS, COLS);
	Displayboard(board, ROW, COL);
	while (1)
	{
		ret=Playermove(board,'*'); //‘*’代表玩家的棋
		Displayboard(board, ROW, COL);
		if (ret == 1)//这里加了一个是否继续游戏的判断,写的不好
		{
			system("cls");
			printf("是否继续游戏>; Y/N\n");
			scanf("%c", &choice);
			getchar();
			if (choice == 'Y')
				goto a;
			else
				exit(0);
		}
		system("cls");
		ret=computermove(board,'#');//‘#’代表电脑的棋
		Displayboard(board, ROW, COL);
		if (ret == 1)
		{
			system("cls");
			printf("是否继续游戏>; Y/N\n");
			getchar();
			scanf("%c", &choice);
			if (choice == 'Y')
				goto a;
			else
				break;
			goto a;
		}
	}
}
void start()
{
	menu();
	int choice;
	do {
		printf("请选择:> \n");
		scanf("%d", &choice);
		switch (choice)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择有误,请重新选择:> \n");
			break;
		}
	} while (choice);
}
int main()
{
	srand((unsigned int) time(NULL));
	start();
	return 0;
}

void Initboard(char board[ROWS][COLS], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
			board[i][j] =' ';
	}
}
void Displayboard(char board[ROWS][COLS], int row, int col)
{
	for (int i = DE; i <=row+DE; i++)
	{
		for (int j = DE; j <col+DE; j++)
			printf(" —");
		printf("\n");
		if (i == row+DE)
			return;
		for (int j = DE; j < col+DE; j++)
			printf("| %c", board[i][j]);
		printf("|");
		printf("\n");
	}
}
int Playermove(char board[ROWS][COLS],char sb)
{
	int x, y;
	while (1)
	{
		printf("请输入坐标位置>; \n");
 		scanf("%d %d", &x, &y);
		if (x > ROW || x<0 || y>ROW || y < 0)
		{
			printf("坐标位置非法,请重新输入:> \n");
			continue;
		}
		else if (board[x+DE-1][y+DE-1]=='*'||board[x + DE-1][y + DE-1] == '#')
		{
			printf("该位置已被占用,请重新选择>: \n");
			continue;
		}
		else
		{
			board[x+DE-1][y+DE-1] = sb;
			int judge = Getresult(board, x+ DE-1, y+ DE-1, sb);
			if (judge == 1)
			{
				system("cls");
				Displayboard(board, ROW, COL);
				printf("你赢了\n");
				Sleep(2000);
			}
			else if (Isfull(board))
			{
				system("cls");
				Displayboard(board, ROW, COL);
				printf("平局\n");
				Sleep(2000);
			}
			else
				return 0;
			break;
		}
	}
	return 1;
}
int computermove(char board[ROWS][COLS],char sb)
{
	while (1)
	{
		int x = rand() % ROW;
		int y = rand() % COL;
		if (board[x+DE][y+DE] != ' ')
			continue;
		else
		{
			board[x+DE][y+DE] = sb;
			int judge = Getresult(board, x + DE, y + DE, sb);
			if (judge == 1)
			{
				system("cls");
				Displayboard(board, ROW, COL);
				printf("你赢了\n");
				Sleep(2000);
			}
			else if (Isfull(board))
			{
				system("cls");
				Displayboard(board, ROW, COL);
				printf("平局\n");
				Sleep(2000);
			}
			else
				return 0;
			break;
		}
	}
	return 1;
}
bool Isfull(char board[ROWS][COLS])
{
	for (int i = DE; i < ROW + DE; i++)
	{
		for (int j = DE; j < ROW + DE; j++)
			if (board[i][j] == ' ')
				return false;
	}
	return true;
}

//用字符代表黑白子,判断输赢
//存储当前行,列及两对角线上的棋对应的字符
//这里统一用一种字符判断,省得写两个对照字符串
int Getresult(char board[ROWS][COLS], int x, int y,char sb)
{
	if (Isfull(board))
		return 0;
	char key_c[10] = { 0 }; 
	char key_r[10] = { 0 };
	char key_stdl[10] = { 0 };
	char key_atdl[10] = { 0 };
	char dest[] ="aaaaa";
	for (int i = -4; i <5; i++)
	{
		if (board[x+i][y] == sb)
			key_c[i + 4] = 'a';
		else
			key_c[i + 4] = 'b';
		if (board[x][y + i] == sb)
			key_r[i+4] = 'a';
		else
			key_r[i+4] = 'b';
		if (board[x + i][y + i] == sb)
			key_stdl[i+4] = 'a';
		else
			key_stdl[i+4] = 'b';
		if (board[x - i][y + i] == sb)
			key_atdl[i+4] = 'a';
		else
			key_atdl[i+4] = 'b';
	}
 if(strstr(key_c,dest)||strstr(key_r,dest)||strstr(key_stdl,dest)||strstr(key_atdl,dest))
	return 1;
 else
	return -1;
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

...404 Not Found

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

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

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

打赏作者

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

抵扣说明:

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

余额充值