如何利用最简单的C语言实现AI五子棋

 更新时间:2021年07月31日 09:09:01   作者:Ja_king_  
这篇文章主要给大家介绍了关于如何利用最简单的C语言实现AI五子棋的相关资料,包含了一些五子棋常见的功能,文中也通过详细的实例代码和图片介绍的非常详细,需要的朋友可以参考下

一.如何实现

1.说明:由于本文只是对初学C语言的人学习,所以将不会涉及任何算法,电脑将采用随机下子的方式。(后期会为大家介绍Alpha-Beta剪枝算法实现人工智能AI)

2.主要部分:

(1)菜单

(2)打印棋盘

(3)玩家下子

(4)电脑下子

(5)判断输赢

二.实现代码及分析

(1)菜单的制作

在这里插入图片描述

在这里插入图片描述

运用do…while循环调用菜单,根据用户选择实现玩游戏和退出游戏

(2)棋盘的初始化和打印

棋盘采用标准的15*15的格子,我们可以宏定义ROW和COL分别为15和15来表示行和列。

在这里插入图片描述

分别封装两个函数对棋盘进行初始化和打印

初始化:(这里将棋盘初始化为空格,可初始化为其他)

在这里插入图片描述

打印棋盘:

在这里插入图片描述

效果如下:

在这里插入图片描述

(3)玩家下子

void PlayerMove(char board[ROW][COL], int row, int col) {
	int x, y;
	while (1) {
		printf("玩家走:\n");
		printf("请输入坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (board[x - 1][y - 1] == ' ') {
				board[x - 1][y - 1] = 'O';
				break;
			}
			else {
				printf("坐标被占用,请重新输入\n");
			}
		}
		else {
			printf("坐标非法,请重新输入\n");
		}
	}
}

玩家下子主要采用的思路是,判断棋盘上是否有子,已经输入的坐标是否合法。

(4)电脑下子

void ComputerMove(char board[ROW][COL], int row, int col) {
	int x, y;
	printf("电脑走\n");
	while (1) {
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ') {
			board[x][y] = 'X';
			break;
		}
	}
}

与玩家下子相同,此处采用的随机下子,后期可进行优化(比如:极大极小值算法、Alpha-Beta剪枝算法等)

(5)判断输赢

通过遍历整个棋盘,观察是否有连五子情况出现,代码如下:

char iswin(char board[ROW][COL], int row, int col) {
	//行
	int ren=0,dian=0,i,j;
	for (i = 0;i < row;i++) {
		ren = 0;
		for (j = 0;j < col;j++) {
			if (board[i][j] == 'O')
				ren++;
			else
				ren = 0;
			if (ren >= 5)
				return 'o';
		}
		
	}
	for (i = 0;i < row;i++) {
		dian = 0;
		for (j = 0;j < col;j++) {
			if (board[i][j] == 'X')
				dian++;
			else
				dian = 0;
			if (dian >= 5)
				return 'x';
		}
		
	}
	//列
	ren = dian = 0;
	for (i = 0;i < row;i++) {
		ren = 0;
		for (j = 0;j < col;j++) {
			if (board[j][i] == 'O')
				ren++;
			else
				ren = 0;
			if (ren >= 5)
				return 'o';
		}
		
	}
	for (i = 0;i < row;i++) {
		dian = 0;
		for (j = 0;j < col;j++) {
			if (board[j][i] == 'X')
				dian++;
			else
				dian = 0;
			if (dian >= 5)
				return 'x';
		}
		
	}
	//右下
	ren = dian =i=j= 0;
	for (int k = 0;k < row;k++) {
		i = k;
		j = 0;
		ren = 0;
		while (i < row && j < col) {
			if (board[i][j] == 'O') {
				ren++;
			}
			else {
				ren = 0;
			}
			i++;
			j++;
			if (ren >= 5)
				return 'o';
		}
		
	}
	i = j = 0;
	for (int k = 0;k < row;k++) {
		i = k;
		j = 0;
		dian = 0;
		while (i < row && j < col) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i++;
			j++;
			if (dian >= 5)
				return 'x';
		}
		
	}
	//右上
	for (int k = row;k >=0;k--) {
		j = col;
		i = k;
		ren = 0;
		while (i >=0 && j >=0) {
			if (board[i][j] == 'O') {
				ren++;
			}
			else
				ren = 0;
			i--;
			j--;
			if (ren >= 5)
				return 'o';
		}

	}
	
	for (int k = row;k >= 0;k--) {
		i = k;
		j = col;
		dian = 0;
		while (i >= 0 && j >= 0) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i--;
			j--;
			if (dian >= 5)
				return 'o';
		}
		
	}
	for (int k = row;k >= 0;k--) {
		i = k;
		j = 0;
		dian = 0;
		while (i >= 0 && j <col) {
			if (board[i][j] == 'O') {
				dian++;
			}
			else
				dian = 0;
			i--;
			j++;
			if (dian >= 5)
				return 'o';
		}

	}
	for (int k = row;k >= 0;k--) {
		i = k;
		j = 0;
		dian = 0;
		while (i >= 0 && j <col) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i--;
			j++;
			if (dian >= 5)
				return 'x';
		}

	}
	for (int k = 0;k < row;k++) {
		i = k;
		j = col;
		dian = 0;
		while (i < row && j >= 0) {
			if (board[i][j] == 'O') {
				dian++;
			}
			else
				dian = 0;
			i++;
			j--;
			if (dian >= 5)
				return 'o';
		}

	}
	for (int k = 0;k <row;k++) {
		i = k;
		j = col;
		dian = 0;
		while (i <row && j >= 0) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i++;
			j--;
			if (dian >= 5)
				return 'x';
		}

	}
	for (int k = row;k >= 0;k--) {
		i = k;
		j = 0;
		dian = 0;
		while (i >= 0 && j <col) {
			if (board[i][j] == 'O') {
				dian++;
			}
			else
				dian = 0;
			i--;
			j++;
			if (dian >= 5)
				return 'o';
		}

	}
	for (int k = row;k >= 0;k--) {
		i = k;
		j = 0;
		dian = 0;
		while (i >= 0 && j <col) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i--;
			j++;
			if (dian >= 5)
				return 'x';
		}

	}
	for (int k = 0;k < row;k++) {
		i = k;
		j = col;
		dian = 0;
		while (i < row && j >= 0) {
			if (board[i][j] == 'O') {
				dian++;
			}
			else
				dian = 0;
			i++;
			j--;
			if (dian >= 5)
				return 'o';
		}

	}
	for (int k = 0;k <row;k++) {
		i = k;
		j = col;
		dian = 0;
		while (i <row && j >= 0) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i++;
			j--;
			if (dian >= 5)
				return 'x';
		}

	}
	return 'c';
	//左
}

三.整个代码

(1)test.c文件下代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu() {
	printf("**************************\n");
	printf("******* 1. play  *********\n");
	printf("******* 0. exit  *********\n");
	printf("**************************\n");
}
void game() {
	//棋盘数组
	char board[ROW][COL],ret;
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	PrintBoard(board, ROW, COL);
	//下棋
	int a;
	printf("1.先手 0.后手");
	scanf("%d", &a);
	if(a==1)
		PlayerMove(board, ROW, COL);
	else
		ComputerMove(board, ROW, COL);
	while (1) {
		if (a == 0) {
			//PlayerMove(board, ROW, COL);
			PlayerMove(board, ROW, COL);
			PrintBoard(board, ROW, COL);
			ret=iswin(board, ROW, COL);
			if (ret != 'c') {
				break;
			}
			//ComputerMove(board, ROW, COL);
			ComputerMove(board, ROW, COL);
			PrintBoard(board, ROW, COL);
			ret = iswin(board, ROW, COL);
			if (ret != 'c') {
				break;
			}
		}
		else {
			//ComputerMove(board, ROW, COL);
			ComputerMove(board, ROW, COL);
			PrintBoard(board, ROW, COL);
			ret = iswin(board, ROW, COL);
			if (ret != 'c') {
				break;
			}
			//PlayerMove(board, ROW, COL);
			PlayerMove(board, ROW, COL);
			PrintBoard(board, ROW, COL);
			ret = iswin(board, ROW, COL);
			if (ret != 'c') {
				break;
			}
		}
	}
	if (ret == 'o')
		printf("玩家赢\n");
	else if (ret == 'x')
		printf("电脑赢\n");
	else
		printf("平局\n");
}
int main() {
	int input;
	srand((unsigned int)time(NULL));
	do {
		menu();
		scanf("%d", &input);
		switch (input) {
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

(2)game.c下的代码

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void InitBoard(char board[ROW][COL], int row, int col) {
	for (int i = 0;i < row;i++) {
		for (int j = 0;j < col;j++) {
			board[i][j] = ' ';
		}
	}
}
void PrintBoard(char board[ROW][COL], int row, int col) {
	for (int i = 0;i < row;i++) {
		printf("  ");
		printf("%2d", i+1);
	}
	printf("\n");
	for (int i = 0;i < row;i++) {
		//打印数据
		printf("%2d", i + 1);
		for (int j = 0;j < col;j++) {
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		//打印分割行
		if (i < row - 1) {
			printf("  ");
			for (int j = 0;j < col;j++) {

				printf("---");
				if (j < col-1)
					printf("|");
			}
			printf("\n");
		}
	}
}

void PlayerMove(char board[ROW][COL], int row, int col) {
	int x, y;
	while (1) {
		printf("玩家走:\n");
		printf("请输入坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (board[x - 1][y - 1] == ' ') {
				board[x - 1][y - 1] = 'O';
				break;
			}
			else {
				printf("坐标被占用,请重新输入\n");
			}
		}
		else {
			printf("坐标非法,请重新输入\n");
		}
	}
}

void ComputerMove(char board[ROW][COL], int row, int col) {
	int x, y;
	printf("电脑走\n");
	while (1) {
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ') {
			board[x][y] = 'X';
			break;
		}
	}
}

char iswin(char board[ROW][COL], int row, int col) {
	//行
	int ren=0,dian=0,i,j;
	for (i = 0;i < row;i++) {
		ren = 0;
		for (j = 0;j < col;j++) {
			if (board[i][j] == 'O')
				ren++;
			else
				ren = 0;
			if (ren >= 5)
				return 'o';
		}
		
	}
	for (i = 0;i < row;i++) {
		dian = 0;
		for (j = 0;j < col;j++) {
			if (board[i][j] == 'X')
				dian++;
			else
				dian = 0;
			if (dian >= 5)
				return 'x';
		}
		
	}
	//列
	ren = dian = 0;
	for (i = 0;i < row;i++) {
		ren = 0;
		for (j = 0;j < col;j++) {
			if (board[j][i] == 'O')
				ren++;
			else
				ren = 0;
			if (ren >= 5)
				return 'o';
		}
		
	}
	for (i = 0;i < row;i++) {
		dian = 0;
		for (j = 0;j < col;j++) {
			if (board[j][i] == 'X')
				dian++;
			else
				dian = 0;
			if (dian >= 5)
				return 'x';
		}
		
	}
	//右下
	ren = dian =i=j= 0;
	for (int k = 0;k < row;k++) {
		i = k;
		j = 0;
		ren = 0;
		while (i < row && j < col) {
			if (board[i][j] == 'O') {
				ren++;
			}
			else {
				ren = 0;
			}
			i++;
			j++;
			if (ren >= 5)
				return 'o';
		}
		
	}
	i = j = 0;
	for (int k = 0;k < row;k++) {
		i = k;
		j = 0;
		dian = 0;
		while (i < row && j < col) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i++;
			j++;
			if (dian >= 5)
				return 'x';
		}
		
	}
	//右上
	for (int k = row;k >=0;k--) {
		j = col;
		i = k;
		ren = 0;
		while (i >=0 && j >=0) {
			if (board[i][j] == 'O') {
				ren++;
			}
			else
				ren = 0;
			i--;
			j--;
			if (ren >= 5)
				return 'o';
		}

	}
	
	for (int k = row;k >= 0;k--) {
		i = k;
		j = col;
		dian = 0;
		while (i >= 0 && j >= 0) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i--;
			j--;
			if (dian >= 5)
				return 'o';
		}
		
	}
	for (int k = row;k >= 0;k--) {
		i = k;
		j = 0;
		dian = 0;
		while (i >= 0 && j <col) {
			if (board[i][j] == 'O') {
				dian++;
			}
			else
				dian = 0;
			i--;
			j++;
			if (dian >= 5)
				return 'o';
		}

	}
	for (int k = row;k >= 0;k--) {
		i = k;
		j = 0;
		dian = 0;
		while (i >= 0 && j <col) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i--;
			j++;
			if (dian >= 5)
				return 'x';
		}

	}
	for (int k = 0;k < row;k++) {
		i = k;
		j = col;
		dian = 0;
		while (i < row && j >= 0) {
			if (board[i][j] == 'O') {
				dian++;
			}
			else
				dian = 0;
			i++;
			j--;
			if (dian >= 5)
				return 'o';
		}

	}
	for (int k = 0;k <row;k++) {
		i = k;
		j = col;
		dian = 0;
		while (i <row && j >= 0) {
			if (board[i][j] == 'X') {
				dian++;
			}
			else
				dian = 0;
			i++;
			j--;
			if (dian >= 5)
				return 'x';
		}

	}
	return 'c';
	//左
}

(3)game.h下的代码

#pragma once
#define ROW 15
#define COL 15
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col);
//人走
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑走
void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
char iswin(char board[ROW][COL], int row, int col);

四.具体效果

1.棋盘打印以及选择先后手

在这里插入图片描述

2.玩家和电脑下子

在这里插入图片描述

3.判断输赢

在这里插入图片描述

此处我们看到玩家赢了,可是电脑实在太蠢了,所以还有很多地方需要添加的

欢迎各位大佬对此代码进行优化!

总结

到此这篇关于如何利用最简单的C语言实现AI五子棋的文章就介绍到这了,更多相关C语言实现AI五子棋内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++控制结构详情

    C++控制结构详情

    这篇文章主要介绍了C++控制结构详情,C++的控制结构和其它编程语言类似包括顺序结构、选择结构、循环结构,更多相关资料需要的小伙伴可以参考下面文章内容
    2022-03-03
  • VS C++头文件引用提示“未定义标识符”的问题解决

    VS C++头文件引用提示“未定义标识符”的问题解决

    本文主要介绍了VS C++头文件引用提示“未定义标识符”的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • C++印刷模板使用方法详解

    C++印刷模板使用方法详解

    模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型
    2022-11-11
  • 浅谈单调队列、单调栈

    浅谈单调队列、单调栈

    其实,单调队列和单调栈是类似的,在我看来,这两个东西只是名字不一样 - - ! 比较容易想的一道题啦! 首先,这题的两个关键点: 1、区间的和。这个简单,地球人都知道! 2、区间的最小值。
    2015-07-07
  • C++begin和end运算符的返回迭代器的类型如何判断?

    C++begin和end运算符的返回迭代器的类型如何判断?

    今天小编就为大家分享一篇关于C++begin和end运算符的返回迭代器的类型如何判断?,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • C++读取注册表的实现方法

    C++读取注册表的实现方法

    这篇文章主要介绍了C++读取注册表的实现方法的相关资料,希望通过本文能帮助到大家,让大家理解掌握实现这样的功能,需要的朋友可以参考下
    2017-10-10
  • c++读取excel的代码详解

    c++读取excel的代码详解

    在本篇文章里小编给大家分享的是一篇关于c++读取excel的代码详解内容,需要的朋友们可以学习参考下。
    2020-02-02
  • C语言中实现KMP算法的实例讲解

    C语言中实现KMP算法的实例讲解

    KMP算法即字符串匹配算法,C语言中KMP可以避免指针回溯从而达到高效,接下来就来总结一下C语言中实现KMP算法的实例讲解
    2016-06-06
  • 简单的socket编程入门示例

    简单的socket编程入门示例

    这篇文章主要介绍了简单的socket编程入门示例,简单实现client输入内容发送到server端输出,需要的朋友可以参考下
    2014-03-03
  • 简单讲解C++的内部和外部函数以及宏的定义

    简单讲解C++的内部和外部函数以及宏的定义

    这篇文章主要介绍了简单讲解C++的内部和外部函数以及宏的定义,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09

最新评论