MATLAB实现井字棋

news2025/6/4 7:30:02

一、智能决策系统与博弈游戏概述

(一)智能决策系统核心概念

智能决策系统(Intelligent Decision System, IDS)是通过数据驱动和算法模型模拟人类决策过程的计算机系统,核心目标是在复杂环境中自动生成最优策略,实现决策自动化与智能化。其核心要素包括:

  • 数据层:负责采集、存储、处理和管理数据,为后续分析提供支撑。
  • 算法层:通过数学模型和逻辑规则解析数据、生成候选策略。
  • 决策层:整合算法输出、执行最终决策,并对结果进行反馈优化。
  • 交互层:接收用户输入、展示决策结果,并支持人机协同决策。

其决策流程为:用户落子→数据层采集棋盘状态→算法层用 Minimax 评估所有落子可能→决策层选择最优位置落子→交互层展示结果→反馈机制记录对弈数据优化算法。

(二)博弈游戏的研究价值

  1. 规则明确,易于建模:博弈游戏规则清晰固定,便于转化为计算机可处理的模型。以井字棋为例,3×3 棋盘、双方轮流落子、先连成三子者胜的规则简单,可用二维数组表示棋盘状态。
  2. 算法验证的理想场景:为各类决策算法提供测试平台,从基础的决策树、极大极小值算法(Minimax)到复杂的蒙特卡洛树搜索(MCTS)、强化学习算法,都能在博弈游戏中验证有效性和性能。如井字棋中使用 Minimax 算法,通过递归搜索所有可能落子、评估棋局状态、选择最优落子策略,可直观展现算法在有限状态空间内的决策过程。

二、井字棋场景下的技术架构

(一)棋盘状态表示

使用 3x3 矩阵表示棋盘,空点为 0,玩家 1 棋子为 1,玩家 2(AI)棋子为 - 1。例如:

plaintext

0  -1  1  
1  -1  0  
-1  1  0  

初始化空棋盘代码为:board = zeros(3,3);

(二)核心算法:分数评估算法

在棋局未结束时,根据棋盘上棋子的布局情况进行细致打分,计算己方和对方连子的数量和潜在威胁,为不同情况赋予不同分数,同时考虑不同位置的重要性并进行加权。中心位置权重较高(4),边角位置次之(2),其他位置权重较低(0)。计算分数时,将连子得分加上对应位置的权重得分,以区分不同局面的优劣。具体局面得分情况如下:

局面情况玩家 1 得分玩家 2 得分
行 / 列 / 对角线形成双连子 (无对方棋子)+5+5
占据中心位置 (5 号)+4+4
占据边角位置 (1/3/7/9 号)+2+2

(三)极大极小值算法(Minimax)

  • 算法流程:从当前棋盘状态出发,递归搜索所有可能的落子位置,模拟双方交替落子的过程。Max 层为玩家 1,目标是让净得分(玩家 1 得分 - 玩家 2 得分)越大越好;Min 层为玩家 2(AI),目标是让净得分越小越好。通过递归一次评估得分,最终选择最优落子位置。
  • 示例说明:在给定的棋盘状态下,通过递归计算不同落子情况的得分,确定最优策略。

三、MATLAB 代码实现与案例解析

(一)主函数tic_tac_toe()

  • 功能:实现井字棋游戏的主逻辑,包括棋盘初始化、玩家输入处理、AI 落子、棋盘显示、得分计算和结局判断等。
  • 代码要点
    • 初始化棋盘和游戏状态,显示位置编号与棋盘对应关系。
    • 进入游戏主循环,交替进行玩家 1 和玩家 2(AI)的回合。
    • 玩家 1 输入落子位置,进行有效性检查后更新棋盘。
    • AI 通过minimax算法计算最佳落子位置并更新棋盘。
    • 显示棋盘和得分,判断游戏是否结束,处理平局、玩家 1 胜或玩家 2 胜的情况,并询问是否重新开始游戏。

(二)显示棋盘display_board(board)

  • 功能:将棋盘状态以直观的方式显示,用 'X' 表示玩家 1 的棋子,'O' 表示玩家 2(AI)的棋子,'.' 表示空点。
  • 代码逻辑:遍历棋盘的每个位置,根据棋子状态生成相应的字符串并显示。

(三)评分系统evaluateBoard(board)

  • 功能:评估棋盘状态,判断游戏是否结束,并计算当前得分。
  • 代码逻辑
    • 首先检查行、列、对角线是否有一方连成三子,若有则确定游戏结束并给出相应得分。
    • 检查是否平局,若棋盘无空点则游戏结束,得分为 [0,0]。
    • 若游戏未结束,计算非终局得分,包括连子得分和位置权重得分。

(四)决策系统 Min 层minimax(board)

  • 功能:实现 Min 层(AI)的决策逻辑,通过递归调用minimaxi函数评估所有可能的落子位置,选择使净得分最小的最佳落子位置。
  • 代码要点:获取所有可用落子位置,模拟 AI 落子后,调用minimaxi函数计算玩家 1 的最佳应对得分,选择得分最小的位置作为 AI 的落子位置。

(五)决策系统 Max 层minimaxi(new_board)

  • 功能:实现 Max 层(玩家 1)的决策逻辑,评估玩家 1 在 AI 落子后的最佳落子位置,计算净得分。
  • 代码要点:获取所有可用落子位置,模拟玩家 1 落子后,计算当前得分,选择得分最大的位置对应的净得分作为结果。

四、扩展思考:从井字棋到五子棋

(一)算法适用性对比

算法类型井字棋适用性五子棋适用性关键改进点
Minimax★★☆☆☆(需剪枝)深度扩展至 4 + 层,结合 α-β 剪枝★★★★☆/
Minimax+α-β★★★☆☆剪枝效率决定搜索深度★★★★☆/
蒙特卡洛树搜索适合高复杂度状态空间★★☆☆☆★★★★☆/
强化学习结合策略网络与价值网络★★★★★★★★(需训练)/

(二)发展路径建议

从 Minimax+α-β 剪枝起步,实现基础 AI;逐步引入 MCTS 提升中局能力;最终可尝试深度强化学习(如 AlphaGo Zero 思路)构建高性能 AI。

通过对井字棋的研究,我们深入了解了智能决策系统在博弈游戏中的应用架构和算法实现,而从井字棋到五子棋的扩展思考,为我们展示了更复杂博弈场景下智能决策系统的发展方向和潜力。希望本文能为对智能决策系统和博弈游戏算法感兴趣的读者提供有益的参考。

function tic_tac_toe()

% 初始化棋盘

board = zeros(3, 3);

game_over = false;

disp('===== 井字棋游戏 =====');

disp('位置编号与棋盘对应关系:');

disp('1(左上) 2(中上) 3(右上)');

disp('4(左中) 5(中心) 6(右中)');

disp('7(左下) 8(中下) 9(右下)');

disp('玩家1(X)请输入落子位置(1-9)');

pos_map = [

1 1; % 位置1 → (1,1)

1 2; % 位置2 → (1,2)

1 3; % 位置3 → (1,3)

2 1; % 位置4 → (2,1)

2 2; % 位置5 → (2,2)

2 3; % 位置6 → (2,3)

3 1; % 位置7 → (3,1)

3 2; % 位置8 → (3,2)

3 3]; % 位置9 → (3,3)

% 游戏主循环

while ~game_over

% 玩家1回合(输入验证优化)

while true

move_str = input('请输入位置(1-9):', 's');

if isempty(move_str) || ~all(ismember(move_str, '123456789'))

disp('请输入1-9的有效数字!');

continue;

end

move = str2double(move_str);

row = pos_map(move, 1);

col = pos_map(move, 2);

if board(row, col) ~= 0

disp('该位置已被占用!');

else

board(row, col) = 1;

break;

end

end

% 显示棋盘与得分

display_board(board);

[score, game_over] = evaluateBoard(board);

disp(['当前得分:玩家1: ' num2str(score(1)) ' | 玩家2:' num2str(score(2))]);

if game_over, break; end

% 玩家2回合(程序落子,优化提示)

disp('程序正在思考...');

pause(3);

best_move = minimax(board);

row = ceil(best_move / 3);

col = mod(best_move, 3);

if col == 0

col = 3;

end

board(row, col) = -1;

% 显示棋盘与得分

display_board(board);

[score, game_over] = evaluateBoard(board);

disp(['当前得分:玩家1:' num2str(score(1)) ' | 玩家2: ' num2str(score(2))]);

end

% 结局判断(简化逻辑)

if score(1) == 10

disp('玩家1获得MVP!');

elseif score(2) == 10

disp('菜就多练!');

else

disp('棋逢对手,将遇良才,本次平局!');

end

% 询问是否重启(新增功能)

if input('是否重新开始?(1=是,0=否):', 's') == '1'

tic_tac_toe();

end

end

% 显示棋盘(保持不变)

function display_board(board)

disp('当前棋盘状态:');

for i = 1:3

row_str = [];

for j = 1:3

if board(i,j) == 1

row_str = [row_str, ' X '];

elseif board(i,j) == -1

row_str = [row_str, ' O '];

else

row_str = [row_str, ' . '];

end

end

disp(row_str);

end

end

function [score, game_over] = evaluateBoard(board)

game_over = false;

score = zeros(1,2);

% 检查行、列、对角线(提前return)

for i = 1:3

if sum(board(i,:)) == 3 || sum(board(:,i)) == 3

score = [10, 0];

game_over = true;

return;

end

if sum(board(i,:)) == -3 || sum(board(:,i)) == -3

score = [0, 10];

game_over = true;

return;

end

end

if sum(diag(board)) == 3 || sum(diag(fliplr(board))) == 3

score = [10, 0];

game_over = true;

return;

end

if sum(diag(board)) == -3 || sum(diag(fliplr(board))) == -3

score = [0, 10];

game_over = true;

return;

end

% 检查平局

if sum(board(:) == 0) == 0

score = [0, 0];

game_over = true;

return;

end

% 计算非终局得分(仅在未结束时执行)

position_weights = [2,0,2;0,4,0;2,0,2];

lines = [board(1,:); board(2,:); board(3,:); board(:,1)'; board(:,2)'; board(:,3)'; diag(board)'; diag(fliplr(board))'];

player1_double = 0;

player2_double = 0;

for i = 1:8

if sum(lines(i,:)) == 2

player1_double = player1_double + 5;

end

if sum(lines(i,:)) == -2

player2_double = player2_double + 5;

end

end

board_1 = board;

board_2 = board;

board_1(board_1<0)=0;

board_2(board_2>0)=0;

player1_position = sum(sum(board_1.* position_weights)); % 向量化计算位置得分

player2_position = -sum(sum(board_2.* position_weights));

score(1) = player1_double + player1_position;

score(2) = player2_double + player2_position;

end

function best_move = minimax(board)

available_moves = find(board' == 0);

num_moves = length(available_moves);

best_score = inf;

best_move = available_moves(1);

pos_map = [

1 1; % 位置1 → (1,1)

1 2; % 位置2 → (1,2)

1 3; % 位置3 → (1,3)

2 1; % 位置4 → (2,1)

2 2; % 位置5 → (2,2)

2 3; % 位置6 → (2,3)

3 1; % 位置7 → (3,1)

3 2; % 位置8 → (3,2)

3 3]; % 位置9 → (3,3)

for i = 1:num_moves

move = available_moves(i);

row = pos_map(move, 1);

col = pos_map(move, 2);

new_board = board;

new_board(row, col) = -1; % AI落子推演

best_score_test = minimaxi(new_board);% 推演后,玩家1给出最佳方案时的净得分

if best_score_test < best_score

best_score = best_score_test;

best_move = move;

end

end

end

function best_score_test = minimaxi(new_board)

available_moves = find(new_board' == 0);

num_moves = length(available_moves);

best_score_test = -inf;

pos_map = [

1 1; % 位置1 → (1,1)

1 2; % 位置2 → (1,2)

1 3; % 位置3 → (1,3)

2 1; % 位置4 → (2,1)

2 2; % 位置5 → (2,2)

2 3; % 位置6 → (2,3)

3 1; % 位置7 → (3,1)

3 2; % 位置8 → (3,2)

3 3]; % 位置9 → (3,3)

for i = 1:num_moves

move = available_moves(i);

row = pos_map(move, 1);

col = pos_map(move, 2);

nnew_board = new_board;

nnew_board(row, col) = 1; % 玩家1落子推演

[best_score_tes, ~] = evaluateBoard(nnew_board);

best_score_testt = best_score_tes(1)-best_score_tes(2);

if best_score_testt > best_score_test

best_score_test = best_score_testt;

end

end

end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2396509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Baklib知识中台加速企业服务智能化实践

知识中台架构体系构建 Baklib 通过构建多层级架构体系实现知识中台的底层支撑&#xff0c;其核心包含数据采集层、知识加工层、服务输出层及智能应用层。在数据采集端&#xff0c;系统支持对接CRM、ERP等业务系统&#xff0c;结合NLP技术实现非结构化数据的自动抽取&#xff1…

VMware Tools 手动编译安装版

OWASPBWA安装VMware tools 安装时&#xff0c;显示如下提示 官方安装手册参考&#xff1a;https://knowledge.broadcom.com/external/article?legacyId1014294 按照提示&#xff0c;下载linux.iso文件&#xff0c;并连接到虚拟机的CDROM里&#xff0c;状态勾选已连接&#x…

android平台驱动开发(六)--Makefile和Kconfig简介

Makefile&#xff1a; 1.编译进内核&#xff0c;还是以模块方式加载 模块方式编译成ko,通常是自己添加脚本方式insmod ,android 平台通常默认有modprobe加载&#xff0c;不需要额外添加insmod脚本 lsmod |grep test 可以查看是否安装成功 rmmod test-m.ko 可以删除ko 2.多…

【手写系列】手写线程池

PS&#xff1a;本文的线程池为演示 Demo&#xff0c;皆在理解线程池的工作原理&#xff0c;并没有解决线程安全问题。 最简单一版的线程池 public class MyThreadPool {// 存放线程&#xff0c;复用已创建的线程List<Thread> threadList new ArrayList<>();publ…

Live Helper Chat 安装部署

Live Helper Chat(LHC)是一款开源的实时客服聊天系统,适用于网站和应用,帮助企业与访问者即时沟通。它功能丰富、灵活、可自托管,常被用于在线客户支持、销售咨询以及技术支持场景。 🧰 系统要求 安装要求 您提供的链接指向 Live Helper Chat 的官方安装指南页面,详细…

ARXML解析与可视化工具

随着汽车电子行业的快速发展,AUTOSAR标准在车辆软件架构中发挥着越来越重要的作用。然而,传统的ARXML文件处理工具往往存在高昂的许可费用、封闭的数据格式和复杂的使用门槛等问题。本文介绍一种基于TXT格式输出的ARXML解析方案,为开发团队提供了一个高效的替代解决方案。 …

PnP(Perspective-n-Point)算法 | 用于求解已知n个3D点及其对应2D投影点的相机位姿

什么是PnP算法&#xff1f; PnP 全称是 Perspective-n-Point&#xff0c;中文叫“n点透视问题”。它的目标是&#xff1a; 已知一些空间中已知3D点的位置&#xff08;世界坐标&#xff09;和它们对应的2D图像像素坐标&#xff0c;求解摄像机的姿态&#xff08;位置和平移&…

在日常管理服务器中如何防止SQL注入与XSS攻击?

在日常管理服务器时&#xff0c;防止SQL注入&#xff08;Structured Query Language Injection&#xff09;和XSS&#xff08;Cross-Site Scripting&#xff09;攻击是至关重要的&#xff0c;这些攻击可能会导致数据泄露、系统崩溃和信息泄露。以下是一份技术文章&#xff0c;介…

Wkhtmltopdf使用

Wkhtmltopdf使用 1.windows本地使用2.golangwindows环境使用3.golangdocker容器中使用 1.windows本地使用 官网地址 https://wkhtmltopdf.org/&#xff0c;直接去里面下载自己想要的版本&#xff0c;这里以windows版本为例2.golangwindows环境使用 1.安装扩展go get -u githu…

ArcGIS Pro 创建渔网格网过大,只有几个格网的解决方案

之前用ArcGIS Pro创建渔网的时候&#xff0c;发现创建出来格网过大&#xff0c;只有几个格网。 后来查阅资料&#xff0c;发现是坐标不对&#xff0c;导致设置格网大小时单位为度&#xff0c;而不是米&#xff0c;因此需要进行坐标系转换&#xff0c;网上有很多资料讲了ArcGIS …

重学计算机网络之以太网

一&#xff1a;历史发展进程 DIX EtherNet V2 战胜IEEE802.3成为主流版本。总线型交换机拓扑机构代替集线器星型拓扑机构 1990年IEEE制定出星形以太网10BASE-T的标准**802.3i**。“10”代表10 Mbit/s 的数据率&#xff0c;BASE表示连接线上的信号是基带信号&#xff0c;T代表…

《深度解构现代云原生微服务架构的七大支柱》

☁️《深度解构现代云原生微服务架构的七大支柱》 一线架构师实战总结&#xff0c;系统性拆解现代微服务架构中最核心的 7 大支柱模块&#xff0c;涵盖通信协议、容器编排、服务网格、弹性伸缩、安全治理、可观测性、CI/CD 等。文内附架构图、实操路径与真实案例&#xff0c;适…

使用SCSS实现随机大小的方块在页面滚动

目录 一、scss中的插值语法 二、方块在界面上滚动的动画 一、scss中的插值语法 插值语法 #{}‌ 是一种动态注入变量或表达式到选择器、属性名、属性值等位置的机制 .类名:nth-child(n) 表示需同时满足为父元素的第n个元素且类名为给定条件 效果图&#xff1a; <div class…

AI 眼镜新纪元:贴片式TF卡与 SOC 芯片的黄金组合破局智能穿戴

目录 一、SD NAND&#xff1a;智能眼镜的“记忆中枢”突破空间限制的存储革命性能与可靠性的双重保障 二、SOC芯片&#xff1a;AI眼镜的“智慧大脑”从性能到能效的全面跃升多模态交互的底层支撑 三、SD NANDSOC&#xff1a;11&#xff1e;2的协同效应数据流水线的高效协同成本…

论文阅读(六)Open Set Video HOI detection from Action-centric Chain-of-Look Prompting

论文来源&#xff1a;ICCV&#xff08;2023&#xff09; 项目地址&#xff1a;https://github.com/southnx/ACoLP 1.研究背景与问题 开放集场景下的泛化性&#xff1a;传统 HOI 检测假设训练集包含所有测试类别&#xff0c;但现实中存在大量未见过的 HOI 类别&#xff08;如…

算法学习--持续更新

算法 2025年5月24日 完成&#xff1a;快速排序、快速排序基数优化、尾递归优化 快排 public class QuickSort {public void sort(int[] nums, int left, int right) {if(left>right){return;}int partiton quickSort(nums,left,right);sort(nums,left,partiton-1);sort(nu…

Postman 发送 SOAP 请求步骤 归档

0.来源 https://apifox.com/apiskills/sending-soap-requests-with-postman/?utm_sourceopr&utm_mediuma2bobzhang&utm_contentpostman 再加上自己一点实践经验 1. 创建一个新的POST请求 postman 创建一个post请求, 请求url 怎么来的可以看第三步 2. post请求设…

Python Day39 学习(复习日志Day4)

复习Day4日志内容 浙大疏锦行 补充: 关于“类”和“类的实例”的通俗易懂的例子 补充&#xff1a;如何判断是用“众数”还是“中位数”填补空缺值&#xff1f; 今日复习了日志Day4的内容&#xff0c;感觉还是得在纸上写一写印象更深刻&#xff0c;接下来几日都采取“纸质化复…

[Python] Python自动化:PyAutoGUI的基本操作

初次学习&#xff0c;如有错误还请指正 目录 PyAutoGUI介绍 PyAutoGUI安装 鼠标相关操作 鼠标移动 鼠标偏移 获取屏幕分辨率 获取鼠标位置 案例&#xff1a;实时获取鼠标位置 鼠标点击 左键单击 点击次数 多次有时间间隔的点击 右键/中键点击 移动时间 总结 鼠…

应急响应靶机-web2-知攻善防实验室

题目&#xff1a; 前景需要&#xff1a;小李在某单位驻场值守&#xff0c;深夜12点&#xff0c;甲方已经回家了&#xff0c;小李刚偷偷摸鱼后&#xff0c;发现安全设备有告警&#xff0c;于是立刻停掉了机器开始排查。 这是他的服务器系统&#xff0c;请你找出以下内容&#…