(C语言)五子棋(人机对战过程中要求电脑比较智能)

五子棋(人机对战过程中要求电脑比较智能)

这里使用15 × 15 的棋盘
首先确定程序框架,再逐一实现。

具体实现如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_ROW 15
#define MAX_COL 15
char chessboard[MAX_ROW][MAX_COL];
int y, x;//玩家输入的坐标
int y1, x1;//电脑输入的坐标
int m, n;//检测连续棋子后坐标移动到的位置
int CheckGameOver(int N, int y, int x, char ch);
void Menu() {
	printf("1.开始游戏\n");
	printf("0.退出游戏\n");
	printf("请输入您的选择\n");
}
void Init() {
	for (int row = 0; row < MAX_ROW; ++row) {
		for (int col = 0; col < MAX_COL; ++col) {
			chessboard[row][col] = ' ';
		}
	}
}
void Print() {
	printf("  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 \n");
	printf(" _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n");
	for (int row = 0; row < MAX_ROW; ++row) {
		for (int col = 0; col < MAX_COL; ++col) {
			printf("| %c", chessboard[row][col]);
		}
		printf("|\n|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|");
		printf("%d\n", row);
	}
}
void PlayerMove() {
	printf("请输入您落子位置的坐标值\n");
	while (1) {
		scanf("%d %d", &y, &x);
		if (y > 14 || y < 0 || x > 14 || x < 0) {
			printf("输入非法,请重新输入!\n");
			continue;
		}
		if (chessboard[y][x] != ' ') {
			printf("此位置已有棋子\n");
			continue;
		}
		break;
	}
	chessboard[y][x] = 'x';
}
int AI_1(int N, int a) {//判断需要的棋子半径为N范围内的棋盘,再选择是否落子
	if (a == 1) {
		if (m - N >= 0 && chessboard[m - N][n] == ' ') {
			chessboard[m - N][n] = 'o';
			y1 = m - N;
			x1 = n;
			return 1;
		}
		if (m + 1 < 15 && chessboard[m + 1][n] == ' ') {
			chessboard[m + 1][n] = 'o';
			y1 = m + 1;
			x1 = n;
			return 1;
		}
	}
	else if (a == 2) {
		if (n - N >= 0 && chessboard[m][n - N] == ' ') {
			chessboard[m][n - N] = 'o';
			y1 = m;
			x1 = n - N;
			return 1;
		}
		if (n + 1 < 15 && chessboard[m][n + 1] == ' ') {
			chessboard[m][n + 1] = 'o';
			y1 = m;
			x1 = n + 1;
			return 1;
		}
	}
	else if (a == 3) {
		if (n - N >= 0 && m - N > 0 && chessboard[m - N][n - N] == ' ') {
			chessboard[m - N][n - N] = 'o';
			y1 = m - N;
			x1 = n - N;
			return 1;
		}
		if (n + 1 < 15 && m + 1 < 15 && chessboard[m + 1][n + 1] == ' ') {
			chessboard[m + 1][n + 1] = 'o';
			y1 = m + 1;
			x1 = n + 1;
			return 1;
		}
	}
	else if (a == 4) {
		if (n - 1 >= 0 && m + 1 < 15 && chessboard[m + 1][n - 1] == ' ') {
			chessboard[m + 1][n - 1] = 'o';
			y1 = m + 1;
			x1 = n - 1;
			return 1;
		}
		if (m - N >= 0 && n + N < 15 && chessboard[m - N][n + N] == ' ') {
			chessboard[m - N][n + N] = 'o';
			y1 = m + N;
			x1 = n - N;
			return 1;
		}
	}
	return 0;
}

int AI_2(int a, char ch) {//判断 oo o 或  o oo类型的落子
	if (a == 1) {
		if (m + 2 < 15 && chessboard[m + 1][n] == ' ' && chessboard[m + 2][n] == ch) {
			chessboard[m + 1][n] = 'o';
			y1 = m + 1;
			x1 = n;
			return 1;
		}
		else if (m - 3 >= 0 && chessboard[m - 2][n] == ' ' && chessboard[m - 3][n] == ch) {
			chessboard[m - 2][n] = 'o';
			y1 = m - 2;
			x1 = n;
			return 1;
		}
	}
	else if (a == 2) {
		if (n + 2 < 15 && chessboard[m][n + 1] == ' ' && chessboard[m][n + 2] == ch) {
			chessboard[m][n + 1] = 'o';
			y1 = m;
			x1 = n + 1;
			return 1;
		}
		if (n - 3 >= 0 && chessboard[m][n - 2] == ' ' && chessboard[m][n - 3] == ch) {
			chessboard[m][n - 2] = 'o';
			y1 = m;
			x1 = n - 2;
			return 1;
		}
	}
	else if (a == 3) {
		if (n + 2 < 15 && m + 2 < 15 && chessboard[m + 1][n + 1] == ' ' && chessboard[m + 2][n + 2] == ch) {
			chessboard[m + 1][n + 1] = 'o';
			y1 = m + 1;
			x1 = n + 1;
			return 1;
		}
		if (n - 3 >= 0 && m - 3 >= 0 && chessboard[m - 2][n - 2] == ' ' && chessboard[m - 3][n - 3] == ch) {
			chessboard[m - 2][n - 2] = 'o';
			y1 = m - 2;
			x1 = n - 2;
			return 1;
		}
	}
	else if (a == 4) {
		if (m + 2 < 15 && n - 2 >= 0 && chessboard[m + 1][n - 1] == ' ' && chessboard[m + 2][n - 2] == ch) {
			chessboard[m + 1][n - 1] = 'o';
			y1 = m + 1;
			x1 = n - 1;
			return 1;
		}
		if (n + 3 < 15 && m - 3 >= 0 && chessboard[m - 2][n + 2] == ' ' && chessboard[m - 3][n + 3] == ch) {
			chessboard[m - 2][n + 2] = 'o';
			y1 = m - 2;
			x1 = n + 2;
			return 1;
		}
	}
	return 0;
}

int AI_3(int a,int b) {//判断  ooo  类型落子
	srand((unsigned int)time(0));
	if (a == 1) {
		if (m + 1 < 15 && m - b >= 0 && chessboard[m + 1][n] == ' ' && chessboard[m - b][n] == ' ') {
			if (rand() % 1 == 0) {
				chessboard[m + 1][n] = 'o';
				y1 = m + 1;
				x1 = n;
				return 1;
			}
			chessboard[m - b][n] = 'o';
			y1 = m - b;
			x1 = n;
			return 1;
		}

	}
	else if (a == 2) {
		if (n + 1 < 15 && n - b >= 0 && chessboard[m][n + 1] == ' ' && chessboard[m][n - b] == ' ') {
			if (rand() % 1 == 0) {
				chessboard[m][n + 1] = 'o';
				y1 = m;
				x1 = n + 1;
				return 1;
			}
			chessboard[m][n - b] = 'o';
			y1 = m;
			x1 = n - b;
			return 1;
		}
	}
	else if (a == 3) {
		if (n + 1 < 15 && m + 1 < 15 && n - b >= 0 && m - 3 >= 0 && chessboard[m + 1][n + 1] == ' ' && chessboard[m - b][n - b] == ' ' ) {
			if (rand() % 1 == 0) {
				chessboard[m + 1][n + 1] = 'o';
				y1 = m + 1;
				x1 = n + 1;
				return 1;
			}
			chessboard[m - b][n - b] = 'o';
			y1 = m - b;
			x1 = n - b;
			return 1;
		}
	}
	else if (a == 4) {
		if (m + b < 15 && n - b >= 0 && chessboard[m + 1][n - 1] == ' ' && chessboard[m + b][n - b] == ' ') {
			if (rand() % 1 == 0) {
				chessboard[m + 1][n - 1] = 'o';
				y1 = m + 1;
				x1 = n - 1;
				return 1;
			}
			chessboard[m + b][n - b] = 'o';
			y1 = m + b;
			x1 = n - b;
			return 1;
		}
	}
	return 0;
}
int AI_5(char ch) {//判断 x/o  x/o 落子到中间
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if (i + 2 < 15 && chessboard[i][j] == ch && chessboard[i + 1][j] == ' ' && chessboard[i + 2][j] == ch) {
				chessboard[i + 1][j] = 'o';
				y1 = i + 1;
				x1 = j;
				return 1;
			}
		}
	}
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if(j + 2 < 15 && chessboard[i][j] == ch && chessboard[i][j + 1] == ' ' && chessboard[i][j + 2] == ch) {
				chessboard[i][j + 1] = 'o';
				y1 = i;
				x1 = j + 1;
				return 1;
			}
		}
	}
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if (j + 2 < 15 && i + 2 < 15 &&chessboard[i][j] == ch && chessboard[i + 1][j + 1] == ' ' && chessboard[i + 2][j + 2] == ch) {
				chessboard[i + 1][j + 1] = 'o';
				y1 = i + 1;
				x1 = j + 1;
				return 1;
			}
		}
	}
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if (j - 2 >= 0 && i + 2 < 15 && chessboard[i][j] == ch && chessboard[i + 1][j - 1] == ' ' && chessboard[i + 2][j - 2] == ch) {
				chessboard[i + 1][j - 1] = 'o';
				y1 = i + 1;
				x1 = j - 1;
				return 1;
			}
		}
	}
	return 0;
}
int AI_4() {//便利棋盘找出适合落子的位置落子
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if (chessboard[i][j] == 'o' && AI_1(4, CheckGameOver(4, i, j, 'o')) == 1) {//如果有4个连在一起的o则连接第5个o
				return 1;
			}
		}
	}
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if (chessboard[i][j] == 'o' && AI_3(CheckGameOver(3, i, j, 'o'), 3) == 1) {//出现  ooo  连接第四个o
				return 1;
			}
		}
	}
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if (chessboard[i][j] == 'o' && AI_2(CheckGameOver(2, i, j, 'o'), 'o') == 1) {//出现oo o时在空处落子
				return 1;
			}
		}
	}
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if (chessboard[i][j] == 'o' && AI_1(3, CheckGameOver(3, i, j, 'o')) == 1) {//如果有3个连在一起的o则连接第4个o
				return 1;
			}
		}
	}
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if (AI_3(CheckGameOver(2, i, j, 'o'), 2) == 1) {//如果有 oo 则落子
				return 1;
			}
		}
	}
	if (AI_5('x') == 1) {//若出现x x则落子o在中间
		return 1;
	}
	if (AI_5('o') == 1) {//若出现o o则落子o在中间
		return 1;
	}
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 15; ++j) {
			if (chessboard[i][j] == 'o' && AI_1(2, CheckGameOver(2, i, j, 'o')) == 1) {// 如果有2个连在一起的o则连接第3个o
				return 1;
			}
		}
	}
	for (int i = 1; i < MAX_ROW - 1; ++i) {
		for (int j = 1; j < MAX_COL - 1; ++j) {
			if (chessboard[i][j]=='o') {// 如果有1个o则连接第2个o
				m = i;
				n = j;
				if (AI_1(1, rand() % 4 + 1) == 1) {//随机竖向或者横向或者对角线落子
					return 1;
				}
			}
		}
	}
	for (int i = 0; i < MAX_ROW; ++i) {
		for (int j = 0; j < MAX_COL; ++j) {
			if (chessboard[i][j] == 'o') {// 如果有1个o则连接第2个o
				m = i;
				n = j;
				if (AI_1(1, rand() % 4 + 1) == 1) {//随机竖向或者横向或者对角线落子
					return 1;
				}
			}
		}
	}
	return 0;
}
int CheckGameOver(int N, int y, int x, char ch) {
	int count = 0;
	int up = y < 4 ? 0 : y - 4;
	int down = y > 10 ? 14 : y + 4;
	int left = x < 4 ? 0 : x - 4;
	int right = x > 10 ? 14 : x + 4;
	for (int i = up; i <= down; ++i) {//竖向判断
		if (chessboard[i][x] != ch) {
			count = 0;
			continue;
		}
		++count;
		if (count == N) {
			m = i;
			n = x;
			return 1;
		}
	}
	count = 0;
	for (int i = left; i <= right; ++i) {//横向判断
		if (chessboard[y][i] != ch) {
			count = 0;
			continue;
		}
		++count;
		if (count == N) {
			m = y;
			n = i;
			return 2;
		}
	}
	count = 0;
	for (int i = y - 4, j = x - 4; i <= y + 4 && j <= x + 4; ++i, ++j) {//对角线判断(左上角到右下角)
		if (i < 0 || j < 0) {
			continue;
		}
		if (i > 14 || j > 14) {
			break;
		}
		if (chessboard[i][j] != ch) {
			count = 0;
			continue;
		}
		++count;
		if (count == N) {
			m = i;
			n = j;
			return 3;
		}
	}
	count = 0;
	for (int i = y - 4, j = x + 4; i <= y + 4 && j >= x - 4; ++i, --j) {//对角线判断(右上角到左下角)
		if (i < 0 || j > 14) {
			continue;
		}
		if (i > 14 || j < 0) {
			break;
		}
		if (chessboard[i][j] != ch) {
			count = 0;
			continue;
		}
		++count;
		if (count == N) {
			m = i;
			n = j;
			return 4;
		}
	}
	return 0;
}

void ComputerMove() {
	srand((unsigned int)time(0));
	while (1) {
		if (AI_1(4, CheckGameOver(4, y1, x1, 'o')) == 1) {//如果有4个连在一起的o则连接第5个o
			break;
		}
		if (AI_1(4, CheckGameOver(4, y, x, 'x')) == 1) {//四子连结堵截
			break;
		}
		if (AI_2(CheckGameOver(2, y, x, 'x'), 'x') == 1) {//二子连结堵截(出现xx x时在空处落子)
			break;
		}
		if (AI_3(CheckGameOver(3, y1, x1, 'o'),3) == 1) {//出现  ooo  连接第四个o
			break;
		}
		if (AI_1(3, CheckGameOver(3, y1, x1, 'o')) == 1) {//如果有3个连在一起的o则连接第4个o
			break;
		}
		if (AI_1(3, CheckGameOver(3, y, x, 'x')) == 1) {//三子连结堵截
			break;
		}
		if (AI_2(CheckGameOver(2, y1, x1, 'o'), 'o') == 1) {//出现oo o时在空处落子
			break;
		}
		if (AI_4() == 1) {
 			break;
		}
		y1 = rand() % 5 + 5;
		x1 = rand() % 5 + 5;
		if (chessboard[y1][x1] == ' ') {
			chessboard[y1][x1] = 'o';
			break;
		}
	}
}
void Game() {
	int num = 0;
	int choic;
	printf("1.玩家先落子\n2.电脑先落子\n请输入您的选择\n");
	scanf("%d", &choic);
	while (choic != 2 && choic != 1) {
		printf("您的输入非法,请重新输入!\n");
		scanf("%d", &choic);
	}
	system("cls");
	Init();//初始化棋盘
	if (choic == 1) {
		while (1) {
			++num;
			Print();//打印棋盘
			PlayerMove();//玩家落子,玩家落子用x表示
			Print();
			system("cls");
			if (CheckGameOver(5, y, x, 'x') != 0) {//检测游戏是否结束
				Print();
				printf("\n你赢了!\n");
				break;
			}
			ComputerMove();//电脑落子
			Print();
			system("cls");
			if (CheckGameOver(5, y1, x1, 'o') != 0) {//检测游戏是否结束
				Print();
				printf("\n电脑赢了!\n");
				break;
			}
			if (num == 225) {
				printf("和棋\n");
				break;
			}
		}
	}
	else {
		while (1) {
			++num;
			ComputerMove();//电脑落子
			Print();//打印棋盘
			if (CheckGameOver(5, y1, x1, 'o') != 0) {//检测游戏是否结束
				Print();
				printf("\n电脑赢了!\n");
				break;
			}
			PlayerMove();//玩家落子
			Print();
			system("cls");
			if (CheckGameOver(5, y, x, 'x') != 0) {//检测游戏是否结束
				Print();
				printf("\n你赢了!\n");
				break;
			}
			if (num == 225) {
				printf("和棋\n");
				break;
			}
		}
	}
}
void main() {
	int choic;
	Menu();
	scanf("%d", &choic);
	while (choic != 0 && choic != 1) {
		printf("您的输入非法,请重新输入!\n");
		scanf("%d", &choic);
	}
	if (choic == 1) {
		system("cls");
		Game();
	}
	else {
		printf("再见!\n");
	}
	system("pause");
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41071068/article/details/89189408
今日推荐