当前位置: 首页 > article >正文

小程序黑白棋AI:从零实现一个简单的游戏AI

1. 黑白棋游戏基础与小程序环境搭建黑白棋又称翻转棋是经典的策略型棋盘游戏使用8x8方格棋盘和双色圆形棋子。游戏规则简单却充满策略性玩家轮流落子将对手棋子夹在己方棋子之间时可将其翻转成己方颜色最终以棋盘上棋子数量多者获胜。在小程序中实现黑白棋需要解决三个核心问题棋盘渲染用二维数组存储棋盘状态0表示空位1和2分别代表黑白棋子游戏规则实现包括落子合法性判断、棋子翻转逻辑、胜负判定等用户交互处理点击事件并更新棋盘状态先搭建基础开发环境// app.json 配置 { pages: [pages/game/game], window: { navigationBarTitleText: 黑白棋AI } }游戏页面基础结构!-- game.wxml -- view classcontainer view classscore-board text黑棋{{blackScore}}/text text白棋{{whiteScore}}/text text{{title}}/text /view view classchessboard block wx:for{{nowChess}} wx:for-itemrow wx:for-indexi view classrow block wx:for{{row}} wx:for-itemcell wx:for-indexj view classcell {{cell 1 ? black : (cell 2 ? white : )}} bindtapclickButton >// game.js resume() { this.setData({ nowChess: Array(8).fill().map(() Array(8).fill(0)), blackScore: 2, whiteScore: 2 }) // 设置初始棋子 this.setData({ [nowChess[3][3]]: 2, [nowChess[4][4]]: 2, [nowChess[3][4]]: 1, [nowChess[4][3]]: 1 }) }2.2 落子合法性检测关键实现是checkDirect方法检测某个方向是否满足翻转条件checkDirect(x, y, dx, dy) { let hasOpponent false x dx y dy // 沿方向查找对手棋子 while (x 0 x 8 y 0 y 8) { const cell this.data.nowChess[x][y] if (cell 0) return false if (cell this.data.notOperate) { hasOpponent true } else if (cell this.data.operate) { return hasOpponent } x dx y dy } return false }2.3 棋子翻转逻辑当落子合法时需要翻转被夹住的对手棋子changeDirect(x, y, dx, dy) { if (!this.checkDirect(x, y, dx, dy)) return let cx x dx let cy y dy const changes [] // 收集需要翻转的棋子 while (this.data.nowChess[cx][cy] this.data.notOperate) { changes.push([cx, cy]) cx dx cy dy } // 批量更新棋子状态 const updates {} changes.forEach(([i, j]) { updates[nowChess[${i}][${j}]] this.data.operate }) updates[nowChess[${x}][${y}]] this.data.operate this.setData(updates) }3. 基础AI实现方案3.1 随机落子AI最简单的AI实现是随机选择合法位置落子AIgo() { const validMoves [] // 收集所有合法位置 for (let i 0; i 8; i) { for (let j 0; j 8; j) { if (this.data.nowChess[i][j] 0 this.canGo(i, j)) { validMoves.push([i, j]) } } } if (validMoves.length 0) { // 随机选择一个合法位置 const [x, y] validMoves[Math.floor(Math.random() * validMoves.length)] this.go(x, y) } else { // 无合法位置时跳过回合 this.passTurn() } }3.2 基于权重的策略改进给棋盘位置赋予权重让AI优先选择中心位置// 棋盘位置权重表 const WEIGHT_MAP [ [100, -20, 10, 5, 5, 10, -20, 100], [-20, -50, -2, -2, -2, -2, -50, -20], [10, -2, -1, -1, -1, -1, -2, 10], [5, -2, -1, -1, -1, -1, -2, 5], [5, -2, -1, -1, -1, -1, -2, 5], [10, -2, -1, -1, -1, -1, -2, 10], [-20, -50, -2, -2, -2, -2, -50, -20], [100, -20, 10, 5, 5, 10, -20, 100] ] AIgo() { let bestScore -Infinity let bestMove null for (let i 0; i 8; i) { for (let j 0; j 8; j) { if (this.data.nowChess[i][j] 0 this.canGo(i, j)) { const score WEIGHT_MAP[i][j] if (score bestScore) { bestScore score bestMove [i, j] } } } } if (bestMove) { this.go(...bestMove) } else { this.passTurn() } }4. 高级AI策略实现4.1 极小化极大算法实现带有简单评估函数的Minimax算法// 评估函数 evaluateBoard() { let score 0 // 棋子数量差 score (this.data.blackScore - this.data.whiteScore) * 10 // 加上位置权重 for (let i 0; i 8; i) { for (let j 0; j 8; j) { if (this.data.nowChess[i][j] 1) { score WEIGHT_MAP[i][j] } else if (this.data.nowChess[i][j] 2) { score - WEIGHT_MAP[i][j] } } } return score } // Minimax算法 minimax(depth, isMaximizing) { if (depth 0) { return this.evaluateBoard() } let bestValue isMaximizing ? -Infinity : Infinity const currentPlayer isMaximizing ? this.data.operate : this.data.notOperate for (let i 0; i 8; i) { for (let j 0; j 8; j) { if (this.data.nowChess[i][j] 0 this.canGo(i, j)) { // 模拟落子 const changes this.simulateMove(i, j) const value this.minimax(depth - 1, !isMaximizing) // 撤销落子 this.undoMove(i, j, changes) bestValue isMaximizing ? Math.max(bestValue, value) : Math.min(bestValue, value) } } } return bestValue }4.2 Alpha-Beta剪枝优化在Minimax基础上加入剪枝优化minimax(depth, alpha, beta, isMaximizing) { if (depth 0) { return this.evaluateBoard() } let bestValue isMaximizing ? -Infinity : Infinity const validMoves this.getValidMoves() for (const [i, j] of validMoves) { const changes this.simulateMove(i, j) const value this.minimax(depth - 1, alpha, beta, !isMaximizing) this.undoMove(i, j, changes) if (isMaximizing) { bestValue Math.max(bestValue, value) alpha Math.max(alpha, bestValue) } else { bestValue Math.min(bestValue, value) beta Math.min(beta, bestValue) } if (beta alpha) { break // 剪枝 } } return bestValue }5. 小程序性能优化技巧5.1 数据更新优化避免频繁setData导致的性能问题// 不好的做法 for (let i 0; i changes.length; i) { this.setData({ [nowChess[${changes[i][0]}][${changes[i][1]}]]: newValue }) } // 优化做法 const updateData {} changes.forEach(([i, j]) { updateData[nowChess[${i}][${j}]] newValue }) this.setData(updateData)5.2 AI计算时间控制将AI计算放入Worker中避免阻塞UI// 创建Worker const worker wx.createWorker(workers/ai.js) // 主线程发送计算任务 worker.postMessage({ board: this.data.nowChess, player: this.data.operate, depth: 3 }) // 监听Worker返回结果 worker.onMessage((res) { if (res.move) { this.go(res.move[0], res.move[1]) } })5.3 动画效果实现添加棋子翻转动画提升体验/* 棋子样式 */ .cell { transition: transform 0.3s, background-color 0.3s; } .cell.flipping { transform: scale(0); }// 实现翻转动画 async flipAnimation(cells) { // 第一阶段缩小消失 const updates1 {} cells.forEach(([i, j]) { updates1[nowChess[${i}][${j}].flipping] true }) this.setData(updates1) // 等待动画完成 await new Promise(resolve setTimeout(resolve, 300)) // 第二阶段改变颜色并放大显示 const updates2 {} cells.forEach(([i, j]) { updates2[nowChess[${i}][${j}].flipping] false updates2[nowChess[${i}][${j}].value] newValue }) this.setData(updates2) }

相关文章:

小程序黑白棋AI:从零实现一个简单的游戏AI

1. 黑白棋游戏基础与小程序环境搭建 黑白棋(又称翻转棋)是经典的策略型棋盘游戏,使用8x8方格棋盘和双色圆形棋子。游戏规则简单却充满策略性:玩家轮流落子,将对手棋子夹在己方棋子之间时,可将其翻转成己方颜…...

智能宠物喂食器项目复盘:那些硬件选型与软件调试中踩过的坑

智能宠物喂食器项目复盘:硬件选型与软件调试的实战避坑指南 去年夏天,我接手了一个看似简单却暗藏玄机的项目——为朋友开发一款能远程控制的智能宠物喂食器。本以为用常见的STM32加几个传感器就能轻松搞定,没想到从硬件选型到软件调试处处是…...

别再踩坑了!在Rancher里用Deployment部署Redis集群,Pod重启IP变动的终极解决方案

在Kubernetes中稳定部署Redis集群的实战指南 为什么Deployment不适合部署Redis集群? Redis作为典型的有状态服务,在Kubernetes环境中部署时面临着独特的挑战。许多开发者习惯性地使用Deployment控制器来部署Redis,这其实是一个常见的误区。问…...

Windows Server 操作主机管理实验文档

实验概述 实验目的 本实验旨在帮助学员掌握Active Directory域环境中操作主机(FSMO)的相关知识,熟练掌握操作主机角色的查看、转移和夺取方法,能够独立处理域环境中操作主机故障相关的运维问题。 前置知识 实验开始前请掌握以下知识点: 操作主机(FSMO,灵活单一主机操作)…...

40岁单身妈妈做装修监理16年:月入过万的真相与生活方式的选择

看到那个‘40岁单身妈妈扛楼16年月入过万’的新闻,我第一反应不是收入,是‘16年’。在这个行业里,能坚持16年,还是一位妈妈,她扛的绝对不是几袋水泥那么简单。我自己接触过不少从一线做起来的监理,尤其是女…...

2026年AI超级员工系统品牌大比拼,谁是行业口碑王?

随着人工智能技术的飞速发展,越来越多的企业开始关注并采用AI超级员工系统来提升工作效率和降低成本。在众多品牌中,广州向日葵互联网有限公司(以下简称“向日葵”)凭借其卓越的产品和服务,逐渐成为行业的佼佼者。本文…...

Redis 实现接口幂等性的三种高效策略

1. 接口幂等性基础认知 第一次听说"幂等性"这个词时,我正盯着生产环境里两条完全相同的订单记录发愁。用户只是抱怨页面卡顿多点了两次提交按钮,结果系统就产生了重复数据。这种场景就像你去ATM机取钱,输入密码后机器没反应&#…...

投资成本(容量相关)

基于多目标粒子群算法的储能容量配置 基于IEEE33节点电网,多目标 分布式电源,配网规划 基于多目标粒子群算法的储能容量配置 基于IEEE33节点电网,建立以储能投资成本 网损成本 峰谷套利收益为成本目标,以电压最小最小为安全指标的…...

[Refactor]CPP Learn Data Day 信

一、什么是urllib3? urllib3 是一个用于处理 HTTP 请求和连接池的强大、用户友好的 Python 库。 它可以帮助你: 发送各种 HTTP 请求(GET, POST, PUT, DELETE等)。 管理连接池,提高网络请求效率。 处理重试和重定向。 支…...

ESP-IDF项目中的CMakeLists.txt配置:如何高效管理.c和.h文件

1. 为什么需要高效管理.c和.h文件 在ESP-IDF项目中,随着功能模块不断增加,代码文件会越来越多。想象一下,如果你的项目里有几十个.c文件和对应的.h文件,每次新增或修改文件都要手动调整编译配置,那简直是场噩梦。我刚开…...

PX4无人机调参实战:从滤波到PID的飞行优化指南

1. 从振动分析到滤波调参:PX4飞控的降噪基础 刚接触PX4飞控调参的新手常会遇到这样的场景:无人机起飞后出现高频抖动,电机异常发热,甚至出现不受控的随机偏转。这些问题往往源于一个共同敌人——振动噪声。去年调试一架轴距650mm的…...

台达PLC伺服追剪程序及电子凸轮技术,含DVP15MC源代码与触摸屏程序一体化解决方案

台达PLC伺服追剪程序,电子凸轮,全部源代码,PLC程序和触摸屏程序,DVP15MC。最近在搞台达PLC的追剪项目,发现里面电子凸轮的设计挺有意思。直接上干货,咱们先看这个追剪系统的核心逻辑——电子凸轮的参数配置…...

语言的边界,与软件的命运憾

1. 引入 在现代 AI 工程中,Hugging Face 的 tokenizers 库已成为分词器的事实标准。不过 Hugging Face 的 tokenizers 是用 Rust 来实现的,官方只提供了 python 和 node 的绑定实现。要实现与 Hugging Face tokenizers 相同的行为,最好的办法…...

交换机堆叠技术实战:从原理到配置的全面解析

1. 为什么需要交换机堆叠? 想象一下你管理着一个中型企业的网络,核心机房里有5台独立工作的交换机。每次新增设备都要手动配置每台交换机,故障时得逐台排查,升级系统更是要一台台操作——这种场景下,交换机堆叠技术就像…...

PNGenc:面向MCU的45KB轻量级PNG编码器

1. PNGenc:面向资源受限MCU的轻量级PNG编码器深度解析1.1 设计背景与工程动因PNGenc并非对标准libpng的移植或裁剪,而是在“零依赖、零堆内存、零规格妥协”原则下,从PNG规范(ISO/IEC 15948:2003)和DEFLATE压缩算法&am…...

微信与支付宝退款接口典型错误排查与实战优化策略

1. 微信支付退款接口典型错误解析 微信支付的退款功能是电商平台必备能力&#xff0c;但很多开发者在对接时都踩过"订单号非法"这个坑。去年我们团队处理过一个紧急case&#xff1a;某跨境电商平台凌晨爆发大量退款失败&#xff0c;日志里清一色的<err_code_des&g…...

从本地到云端:FastAPI服务器部署的5个必知要点(避坑指南)

从本地到云端&#xff1a;FastAPI服务器部署的5个必知要点&#xff08;避坑指南&#xff09; 当你兴奋地完成了一个FastAPI应用的开发&#xff0c;准备将它从本地环境迁移到云端服务器时&#xff0c;可能会遇到各种意想不到的问题。接口无法访问、性能突然下降、请求超时...这些…...

2026年硕士论文AI率15%以下怎么保证?实测工具推荐附操作指南

硕士论文AI率15%以下&#xff0c;这条线现在是很多学校的硬要求。比本科的30%严多了&#xff0c;但处理起来也有方法。 写这篇的起因是帮导师组里的一个师弟处理论文AI率问题。他的论文8万多字&#xff0c;知网AIGC检测给出AI率22%&#xff0c;需要降到15%以下才能送盲审。用嘎…...

LwJSON:嵌入式轻量级JSON解析器深度解析

1. LwJSON&#xff1a;面向嵌入式系统的轻量级 JSON 解析器深度解析在资源受限的嵌入式系统中&#xff0c;JSON 数据交换正从“可选能力”演变为“基础能力”。从 STM32F0 系列微控制器上的传感器配置下发&#xff0c;到 ESP32 模组与云平台的 OTA 参数同步&#xff1b;从 LoRa…...

东南亚电商支付方式有哪些?2026最新整

东南亚电商支付方式以电子钱包、信用卡支付、实时转账和国家统一二维码为核心。印尼常用GoPay、DANA、QRIS&#xff0c;泰国 以PromptPay和TrueMoney为主&#xff0c;马来西亚主流是DuitNow和TouchnGo&#xff0c;新加坡则以PayNow和GrabPay覆盖核心场景。 对于独立站卖家而言…...

SpringCloud进阶--Sentinel 流量防卫兵衅

一、项目背景与核心价值 1. 解决的核心痛点 Navicat的数据库连接密码并非明文存储&#xff0c;而是通过AES算法加密后写入.ncx格式的XML配置文件中。一旦用户忘记密码&#xff0c;常规方式只能重新配置连接&#xff0c;效率极低。本项目只作为学习研究使用&#xff0c;不做其他…...

SenseBoxBLE库详解:phyphox协议下的Arduino BLE透传实践

1. SenseBoxBLE 库深度解析&#xff1a;面向嵌入式工程师的 BLE 数据透传实践指南1.1 库定位与工程价值SenseBoxBLE 是一个专为 senseBox 生态设计的轻量级 Arduino 兼容 BLE 通信库&#xff0c;其核心目标并非构建通用 BLE 协议栈&#xff0c;而是实现传感器数据到 phyphox 移…...

Android10剪贴板限制下的高效适配策略与实践

1. Android10剪贴板限制的背景与影响 Android10引入的剪贴板访问限制是近年来系统安全策略升级的重要一环。简单来说&#xff0c;当你的应用处于后台时&#xff0c;系统会禁止它读取剪贴板内容。这个变化看似微小&#xff0c;却让很多依赖剪贴板监听功能的应用不得不重新思考实…...

Sourcetree实战指南:从零上手代码克隆、高效合并与冲突化解

1. 为什么你需要Sourcetree这款Git可视化工具 刚接触Git版本控制时&#xff0c;命令行操作总是让人望而生畏。记得我第一次用git merge时&#xff0c;不小心把同事的代码覆盖了&#xff0c;整个下午都在手忙脚乱地恢复文件。直到发现了Sourcetree这个神器&#xff0c;才真正体会…...

CMake变量实战:从基础引用到高级构建控制

1. CMake变量基础&#xff1a;从入门到精通 CMake变量是构建系统的核心元素&#xff0c;就像编程语言中的变量一样&#xff0c;它们可以存储和传递各种信息。我第一次接触CMake变量时&#xff0c;完全被各种前缀和命名规则搞晕了&#xff0c;直到踩过几次坑后才真正理解它们的运…...

wso~.升级到.需要更新的数据表戳

1. 架构背景与演进动力 1.1 从单体到碎片化&#xff1a;.NET 的开源征程 在.NET Framework 时代&#xff0c;构建系统主要围绕 Windows 操作系统紧密集成&#xff0c;采用传统的封闭式开发模式。然而&#xff0c;随着.NET Core 的推出&#xff0c;微软开启了彻底的开源与跨平台…...

emGUI:嵌入式轻量级Widget GUI框架解析

1. 项目概述 ESP8266 emGUI 是一款专为资源受限嵌入式平台设计的轻量级 C 语言图形用户界面&#xff08;GUI&#xff09;库&#xff0c;其核心目标并非替代成熟的 GUI 框架&#xff08;如 LVGL 或 TouchGFX&#xff09;&#xff0c;而是提供一套高度可裁剪、零依赖、可深度集成…...

个人开发者如何评估一个AI Token代理服务商的技术实力?

作为个人开发者&#xff0c;评估 AI Token 代理服务商&#xff08;API 中转平台&#xff09;的技术实力&#xff0c;核心是“把黑盒变灰盒”。不要只看价格和宣传&#xff0c;要通过可观测性、兼容性、容错机制三个维度进行实战验证。一、基础兼容性&#xff1a;接口规范与模型…...

OpenClaw模型热切换:Qwen3.5-9B-AWQ-4bit与其他模型动态调用

OpenClaw模型热切换&#xff1a;Qwen3.5-9B-AWQ-4bit与其他模型动态调用 1. 为什么需要模型热切换 去年冬天&#xff0c;我正用OpenClaw处理一批产品截图的分析任务。当时只配置了Qwen3.5-9B-AWQ-4bit这一个模型&#xff0c;结果发现——简单图片描述消耗了过多算力&#xff…...

R语言农业预测代码开源泄露?3个被90%农科院忽略的产量建模陷阱(附可复现代码)

第一章&#xff1a;R语言农业产量预测代码开源泄露事件全景剖析 2023年夏季&#xff0c;某国家级农业大数据平台在GitHub公开仓库中意外暴露了包含真实县域气象、土壤与历史产量数据的R语言建模脚本&#xff0c;引发行业级安全震动。该仓库原意为教学示范&#xff0c;但因.giti…...