针对2048游戏,有人实现了一个AI程序,可以以较大概率(高于90%)赢得游戏,并且作者在
stackoverflow上简要介绍了AI的算法框架和实现思路。

有博客介绍了其中涉及的算法,讲的很好

其中算法的主要是在ai.js文件中。我加了很多的注释在其中,方便大家理解。

function AI(grid) {this.grid = grid;
}// static evaluation function
AI.prototype.eval = function() {var emptyCells = this.grid.availableCells().length;//各种计算的权重,可以自己手动的调试var smoothWeight = 0.1,//monoWeight   = 0.0,//islandWeight = 0.0,mono2Weight  = 1.0,emptyWeight  = 2.7,maxWeight    = 1.0;return this.grid.smoothness() * smoothWeight//+ this.grid.monotonicity() * monoWeight//- this.grid.islands() * islandWeight+ this.grid.monotonicity2() * mono2Weight+ Math.log(emptyCells) * emptyWeight+ this.grid.maxValue() * maxWeight;
};// alpha-beta depth first search
AI.prototype.search = function(depth, alpha, beta, positions, cutoffs) {var bestScore;var bestMove = -1;var result;// the maxing playerif (this.grid.playerTurn) {bestScore = alpha;//遍历四个方向for (var direction in [0, 1, 2, 3]) {var newGrid = this.grid.clone();//逐一搜寻方向if (newGrid.move(direction).moved) {positions++;//如果已经赢了直接返回if (newGrid.isWin()) {return { move: direction, score: 10000, positions: positions, cutoffs: cutoffs };}//如果还没有赢得话就继续想下走var newAI = new AI(newGrid);//当深度为0的时候停止if (depth == 0) {result = { move: direction, score: newAI.eval() };} else {//继承父节点的alpha//递归的搜寻  注意每移动一次轮次翻转 player->computer->player->computer->....result = newAI.search(depth-1, bestScore, beta, positions, cutoffs);if (result.score > 9900) { // winresult.score--; // to slightly penalize higher depth from win} positions = result.positions;cutoffs = result.cutoffs;}//如果返回的分数>当前最好分数则给bestScore和bestMove重新赋值if (result.score > bestScore) {bestScore = result.score;bestMove = direction;}//如果最好的分数大于beta也即意味着上一层节点不会继续向下走 切分if (bestScore > beta) {cutoffs++//既然不会往这儿走,那么分数还是你上层的betareturn { move: bestMove, score: beta, positions: positions, cutoffs: cutoffs };}}}}else { // computer's turn, we'll do heavy pruning to keep the branching factor lowbestScore = beta;// try a 2 and 4 in each cell and measure how annoying it is// with metrics from evalvar candidates = [];//得到可以填充块的坐标var cells = this.grid.availableCells();//分数为2 或者 4var scores = { 2: [], 4: [] };for (var value in scores) {for (var i in cells) {scores[value].push(null);var cell = cells[i];var tile = new Tile(cell, parseInt(value, 10));this.grid.insertTile(tile);//算出分数,下面的计算可以看出要算出分数最大的,我们知道min节点是使游戏变得更难//那么smoothness要越小越好,所以加上符号(越大越好) islands意味着有数字的格子,当然越多越好//通俗理解就是不能合并在一起的越多越好scores[value][i] = -this.grid.smoothness() + this.grid.islands();this.grid.removeTile(cell);}}// now just pick out the most annoying movesvar maxScore = Math.max(Math.max.apply(null, scores[2]), Math.max.apply(null, scores[4]));for (var value in scores) { // 2 and 4//将最大分数的候选者选出来(满足最大分数的可能不止一个)for (var i=0; i<scores[value].length; i++) {if (scores[value][i] == maxScore) {candidates.push( { position: cells[i], value: parseInt(value, 10) } );}}}// search on each candidatefor (var i=0; i<candidates.length; i++) {var position = candidates[i].position;var value = candidates[i].value;var newGrid = this.grid.clone();var tile = new Tile(position, value);newGrid.insertTile(tile);newGrid.playerTurn = true;positions++;newAI = new AI(newGrid);//min节点往下的alpha还是上层的,beta是最好的分数,也就是说下层节点如果你取得的最大值只能是beta,//如果大于beta我会把你pass掉result = newAI.search(depth, alpha, bestScore, positions, cutoffs);positions = result.positions;cutoffs = result.cutoffs;//竟然有比beta还小的分数,好,我选择你if (result.score < bestScore) {bestScore = result.score;}//如果最好的分数小于上层的下界 意味着上层节点肯定不会继续向下走if (bestScore < alpha) {cutoffs++;//返回的分数是还是上层的值也就是说你反正不会走我这条路,那你的分数还是你原来的分数//关于此处的move:null 注意上面的result的depth是继承父节点的,意味着depth>0//也就是说最后一步必为max节点,min节点是不会有move操作的,所以直接返回nullreturn { move: null, score: alpha, positions: positions, cutoffs: cutoffs };}}}
//计算到最好返回这些计算的值return { move: bestMove, score: bestScore, positions: positions, cutoffs: cutoffs };
}// performs a search and returns the best move
AI.prototype.getBest = function() {return this.iterativeDeep();
}// performs iterative deepening over the alpha-beta search
AI.prototype.iterativeDeep = function() {var start = (new Date()).getTime();var depth = 0;var best;//没有规定固定的depth 而是规定了计算时间,在规定时间内能计算到的深度do {var newBest = this.search(depth, -10000, 10000, 0 ,0);if (newBest.move == -1) {break;} else {best = newBest;}depth++;} while ( (new Date()).getTime() - start < minSearchTime);return best
}AI.prototype.translate = function(move) {return {0: 'up',1: 'right',2: 'down',3: 'left'}[move];
}

以上就是根据我的理解所做的注释,供大家参考如果有错误请大家指正!

转载于:https://www.cnblogs.com/dshale/p/6919080.html

AI-2048 注释相关推荐

  1. 【cocos2d-x 手游研发----怪物智能AI】

    原创文章,转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2d-xARPG4.html 谈到怪物AI,我觉得就比较话多了,首先理解一下(Artificial I ...

  2. 死宅福音:乐高不怕多,智能分拣机帮你归类

    作者 | 神经小兮 来源 |  HyperAI超神经(ID:HyperAI) [导读]乐高现在几乎已经是优质玩具的代名词,该品牌旗下最为知名的,莫过于乐高积木.其丰富的形状与多样的玩法,无论大人小孩都 ...

  3. 《强化学习周刊》第38期:DreamingV2、Shadow-price DRL、离线强化学习

    No.38 智源社区 强化学习组 强 化 学  习 研究 观点 资源 活动 关于周刊 强化学习作为人工智能领域研究热点之一,其研究进展与成果也引发了众多关注.为帮助研究与工程人员了解该领域的相关进展和 ...

  4. 要闻君说:台积电将为iPhone生产5纳米A系列芯片?腾讯云TStack与银河麒麟完成互认证……...

    关注并标星星CSDN云计算 极客头条:速递.最新.绝对有料.这里有企业新动.这里有业界要闻,打起十二分精神,紧跟fashion你可以的! 每周三次,打卡即read 更快.更全了解泛云圈精彩news g ...

  5. 模拟赛 10-14考试再次翻车记

    10-14 考试 7点开始考试,第一题傻逼题啊,直接取模过程中加上商就可以了,切掉切掉. 1.光剑 (sword.pas/c/cpp) [题目描述] 小林和亮亮各有一把光剑,长度分别为 a 和 b,他 ...

  6. Linux篇 | 磁盘存储和文件系统

    磁盘存储和文件系统 分区 文件系统 挂载设备 管理虚拟内存 RAID管理 LVM管理 我们从一个新硬盘安装到Linux系统,期间的配置,一直到正常使用的角度,来学习磁盘存储和文件系统,过程如下: 选择 ...

  7. 基于Nginx的Wesocket负载均衡

    分享一个基于NginxWesocket的负载均衡. 1.在mac电脑安装nginx brew install nginx 2.安装完成以后nginx的配置文件路径 /usr/local/etc/ngi ...

  8. 乐高太多没处放?解放女朋友双手,1 个顶 100 个的乐高智能分拣机来了!

    原创:HyperAI超神经 关键词:乐高分拣机 计算机视觉 如果你没有玩过乐高,也可能听过乐高.乐高集团于 1932 年诞生于丹麦,此后很快,「LEGO」这个商标就成为了优质玩具的代名词. 1934 ...

  9. js破解 X笔网登录

    https://fenbi.com/page/home 首先登录抓包 直接搜索 persistent 因为 password  比较大众 断点调试 把整个js 复制出来 node.js 调用 然后缺什 ...

  10. unity 解决乱码_unity3d 中文乱码解决方法——cs代码文件格式批量转化UTF8

    在Unity3d中经常会碰到中文乱码的问题,比如代码中的[AddComponentMenu("GameDef/AI/战机AI")],注释,中文文本等等 其原因在于,unity本身是 ...

最新文章

  1. 在Eclipse上搭建Android C开发环境
  2. 如何成立一家私募基金公司
  3. RecyclerView的版本要和appcompat 的版本不一致 引发的错误
  4. dataset__getitem___[PyTorch 学习笔记] 2.1 DataLoader 与 DataSet
  5. ELK5.3+Kafka集群配置
  6. Java NIO vs IO
  7. nginx配置websocket_Ingress-nginx代理websocket
  8. ArrayList和Vector的异同
  9. java abstract类和abstract方法
  10. mysql手机客户端_图解MySQL索引--B-Tree(B+Tree)
  11. Java微信消息推送(二)
  12. 远程连接软件TeamViewer
  13. java 添加jbutton_在java中怎样在JLabel上添加JButton呢
  14. 经典问题之约瑟夫问题_C语言实现
  15. 程序员那些必须掌握的排序算法(上)
  16. OCCT里的Mesh网格计算流程
  17. MySQL必知必会——实践习题
  18. 三星Galaxy十周年,它给了你一款能买到的折叠手机
  19. 自动升降压PD快充方案 30W快充TYPE-C方案
  20. Matlab笔记(台大郭彦甫14课)

热门文章

  1. 原来这才是 Kafka!(多图+深入)
  2. 大公司为什么都有API网关?没你想的那么简单!
  3. 强化学习教程来啦!贡献者来自中科院、清华、北大3位男神!
  4. 特征工程学习,19项实践Tips!代码已开源!
  5. 只需2040张图片,训练视觉Transformer:南大吴建鑫团队提出IDMM
  6. 数据科学中常见的9种距离度量方法
  7. 训练一个130亿参数的模型要用几个GPU?微软:一个就够
  8. 套上这个壳,手机自己“跑步”去充电
  9. 深度学习的多个 loss 是如何平衡的?
  10. Django REST framework 简介