×

关注微信公众号

免备案网站空间虚拟主机双线空间域名查询PS数码后期
photoshop互助课堂数百G视频教程下载英语培训机构初中英语如何学随时随地聆听大师开讲/课堂
软件安装教程 远程服务 超值!手绘教程抠图教程路径专辑photoshop cs3视频教程
查看: 5188|回复: 2

[教程] as3版俄罗斯方块AI④@张志晨as3实例教程91

[复制链接]
发表于 2014-3-25 18:16:02 | 显示全部楼层 |阅读模式
本帖最后由 dqxxx 于 2014-4-7 12:39 编辑

as3版俄罗斯方块AI④@张志晨as3实例教程91



Ai的组成部分,作为虚拟地图,它记忆方块的变化,负责局面数据的提供与统计、评估:
  1. package as3{
  2.         import flash.geom.Rectangle;
  3.         import flash.geom.Point;

  4.         public class Map {
  5.                 public static const LEFT:int=-1;
  6.                 public static const RIGHT:int=1;
  7.                 public static const DOWN:int=12;
  8.                 const ONE:String="1";
  9.                 var area:Rectangle=new Rectangle(1,4,10,20);
  10.                 var width:int;
  11.                 var height:int;
  12.                 var _maps:Array=[];
  13.                 var four:Array=[];

  14.                 public function Map(_width:int=12,_height:int=25) {
  15.                         width=_width;
  16.                         height=_height;
  17.                 }

  18.                 //----获取外部地图副本------------------------
  19.                 public function getMap(map:Array):String {
  20.                         return map.join("");
  21.                 }

  22.                 //----复制地图------------------------
  23.                 public function copyMap(mapStr:String):Array {
  24.                         return mapStr.split("") as Array;
  25.                 }

  26.                 //----移动---------
  27.                 public function isMove(dir:int):Boolean {//dir=1|-1|12
  28.                         for (var i:int =0; i<4; i++) {
  29.                                 var id:int=four[i]+dir;
  30.                                 if (_maps[id]==ONE) {
  31.                                         return false;
  32.                                 }
  33.                         }
  34.                         return true;
  35.                 }

  36.                 public function move(dir:int) {//dir=1|-1|12
  37.                         for (var i:int =0; i<4; i++) {
  38.                                 four[i]+=dir;
  39.                         }
  40.                         //trace(four);
  41.                 }

  42.                 public function moveX(column:int):Boolean {
  43.                         var px=getBL().x;
  44.                         if (px==column) {
  45.                                 return true;
  46.                         }
  47.                         var f:int=px<column?1:-1;
  48.                         for (var i:int =px; i!=column; i+=f) {
  49.                                 if (isMove(f)) {
  50.                                         move(f);
  51.                                 } else {
  52.                                         return false;
  53.                                 }
  54.                         }
  55.                         return true;
  56.                 }
  57.                 public function moveY() {
  58.                         while (isMove(DOWN)) {
  59.                                 move(DOWN);
  60.                         }
  61.                 }


  62.                 //----评估------------------
  63.                 public function assess(map:Array,delLine1:int,delLine2:int=0,oldLowestLine:int=0):int {

  64.                         var top:int=1024;
  65.                         var space:int=0;
  66.                         var topLast:int=0;
  67.                         var topLLast:int=0;
  68.                         var deep:int=0;
  69.                         var alp:int=0;
  70.                         var diff:int=0;
  71.                         var topAvg:Number=0;

  72.                         var h:int=0;
  73.                         var r:int;
  74.                         var c:int;

  75.                         var _id:int;
  76.                         for (c=area.left; c<area.right; c++) {
  77.                                 topLLast=topLast;//上上一列高度
  78.                                 topLast=h;//上一列高度
  79.                                 for (h=area.top; h<area.bottom; h++) {
  80.                                         //本列高度h
  81.                                         _id=h*width+c;
  82.                                         if (map[_id]==ONE) {
  83.                                                 break;
  84.                                         }
  85.                                 }

  86.                                 //本列在全局是否最高:
  87.                                 if (h<top) {
  88.                                         top=h;
  89.                                 }
  90.                                 //本列有多少w个洞
  91.                                 for (r=h+1; r<area.bottom; r++) {
  92.                                         _id=r*width+c;
  93.                                         if (map[_id]!=ONE) {
  94.                                                 space++;
  95.                                         }
  96.                                 }

  97.                                 var h1:int=topLast-topLLast;
  98.                                 var h2:int=topLast-h;
  99.                                 if (h1>1&&h2>1) {//凹
  100.                                         ++deep;
  101.                                 } else if (h1<-1&&h2<-1) {//凸
  102.                                         ++alp;
  103.                                 }
  104.                                 diff+=Math.abs(h2);//累积坡度
  105.                                 topAvg+=h;//累积高度

  106.                         }
  107.                         topAvg/=10;//平均高度
  108.                         if (h2<-1) {//挨着右界的坑
  109.                                 deep++;
  110.                         }
  111.                         //trace("top,topAvg,delLine1,delLine2,space,deep,alp,diff");
  112.                         //trace(top,topAvg,delLine1,delLine2,space,deep,alp,diff);
  113.                         return top*19+topAvg*15+delLine1*2+delLine2-space*7-deep*4-alp*2-diff;
  114.                 }

  115.                 //得到当前方块
  116.                 public function getTetris() {
  117.                         var d:int=0;
  118.                         if (Tetris.id==1) {
  119.                                 d=2;
  120.                         } else if (Tetris.id==2) {
  121.                                 d=4;
  122.                         } else {
  123.                                 d=3;
  124.                         }

  125.                         for (var i:int =0; i<4; i++) {
  126.                                 four[i]=Tetris.square[Tetris.id][i]+d*12;
  127.                         }
  128.                 }

  129.                 //----旋转-----------------------------------------------------------
  130.                 public function getBL():Point {
  131.                         /*var L:int=12;
  132.                         var B:int=0;
  133.                         for (var i:int =0; i<4; i++) {
  134.                                 var xx:int=four[i]%width;
  135.                                 var yy:int=(four[i]/width)>>0;
  136.                                 if (xx<L) {
  137.                                         L=xx;
  138.                                 }
  139.                                 if (yy>B) {
  140.                                         B=yy;
  141.                                 }
  142.                         }*/
  143.                                 var xx:int=four[3]%width;
  144.                                 var yy:int=(four[3]/width)>>0;
  145.                        
  146.                         return (new Point(xx-1,yy+1));
  147.                 }

  148.                 function isRota():Boolean {
  149.                         var sx:int,sy:int,tx:int,ty:int;
  150.                         if (Tetris.id==1) {
  151.                                 sx=0,tx=3;
  152.                                 sy=-2,ty=1;
  153.                         } else if (Tetris.id==2) {
  154.                                 sx=-1,tx=2;
  155.                                 sy=-3,ty=0;
  156.                         } else {
  157.                                 sx=0,tx=2;
  158.                                 sy=0,ty=-2;
  159.                         }
  160.                         var p:Point=getBL();
  161.                         for (var r:int =p.y+sy; r<=p.y+ty; r++) {
  162.                                 for (var c:int =p.x+sx; c<=p.x+tx; c++) {
  163.                                         var _id:int=r*width+c;
  164.                                         if (_maps[_id]==ONE) {
  165.                                                 return false;
  166.                                         }
  167.                                 }
  168.                         }
  169.                         return true;
  170.                 }
  171.                 public function rotation() {
  172.                         if (Tetris.id==0) {
  173.                                 trace("无需旋转");
  174.                                 return false;
  175.                         }
  176.                         if (isRota()) {
  177.                                 var id:int=Tetris.id;
  178.                                 var offset:Array=Tetris.offset();
  179.                                 for (var i:int =0; i<4; i++) {
  180.                                         four[i]+=offset[i];
  181.                                 }
  182.                                 Tetris.change();

  183.                         } else {
  184.                                 trace("旋转空间不足");
  185.                         }
  186.                 }

  187.                 //---落地--------------------------------------------------------
  188.                 public function stop() {
  189.                         for (var i:int =0; i<4; i++) {
  190.                                 _maps[four[i]]=ONE;
  191.                         }
  192.                 }

  193.                 public function delLineNum():int {
  194.                         //过滤看行号相同的项
  195.                         var sqY:Array=[];
  196.                         sqY[0]=getY(four[0]);
  197.                         var yy:int;
  198.                         for (var k=1; k<4; k++) {
  199.                                 yy=getY(four[k]);
  200.                                 if (sqY.indexOf(yy)==-1) {
  201.                                         sqY.push(yy);
  202.                                 }
  203.                         }

  204.                         //因小方块并不是从小到大排列的
  205.                         sqY.sort(Array.NUMERIC)
  206.                        
  207.                         var n=0;
  208.                         var leng:int=sqY.length;
  209.                         //四个小方块依靠在哪些行,就检测哪些行能在消行:
  210.                         for (var r:int=0; r<leng; r++) {
  211.                                 var isTen:Boolean=true;
  212.                                 for (var c:int=area.left; c<area.right; c++) {
  213.                                         var _id:int=sqY[r]*width+c;
  214.                                         if (_maps[_id]!=ONE) {
  215.                                                 isTen=false;
  216.                                                 break;
  217.                                         }
  218.                                 }
  219.                                 if (isTen) {
  220.                                         clear(sqY[r]);
  221.                                         n++;
  222.                                 }
  223.                         }
  224.                         //返回消行总数:
  225.                         return (n);
  226.                 }
  227.                 //计算局面高度
  228.                 public function tallest():int {
  229.                         //先行后列,第一个不为0的格,就是最高的
  230.                         for (var r:int =area.top; r<area.bottom; r++) {
  231.                                 for (var c:int =area.left; c<area.right; c++) {
  232.                                         var _id:int=r*width+c;
  233.                                         if (_maps[_id]==ONE) {
  234.                                                 return (r);
  235.                                         }
  236.                                 }
  237.                         }
  238.                         return area.bottom;
  239.                 }
  240.                 function clear(row:int) {
  241.                         trace("clear:",row);
  242.                         var c:int;
  243.                         var r:int;
  244.                         if (row==4) {
  245.                                 for (c=49; c<59; c++) {
  246.                                         _maps[c]="0";
  247.                                 }
  248.                                 return;
  249.                         }
  250.                         var tall:int=tallest();//最高行
  251.                         for (r=row; r>tall-1; r--) {
  252.                                 for (c =area.left; c<area.right; c++) {
  253.                                         var _id:int=r*width+c;
  254.                                         _maps[_id]=_maps[_id-width];
  255.                                 }
  256.                         }
  257.                         if (tall==4) {//很少用到
  258.                                 for (c=49; c<59; c++) {
  259.                                         _maps[c]="0";
  260.                                 }
  261.                         }
  262.                 }

  263.                 var best:Array;//[id,c,value,mapStr]
  264.                 public function Evaluate(mapStr:String) {//Strmap是外部地图复本
  265.                         best=[0,0,-10000,""];
  266.                         //有几种变形
  267.                         var more:int;
  268.                         if (Tetris.id==0) {
  269.                                 more=1;
  270.                         } else if (Tetris.id<7) {
  271.                                 more=2;
  272.                         } else {
  273.                                 more=4;
  274.                         }

  275.                         var id:int=Tetris.id;
  276.                         for (var r:int =0; r<more; r++) {//变形 0-4种
  277.                                 if (r>0) {
  278.                                         //变形(相当于旋转)
  279.                                         Tetris.id=id;
  280.                                         Tetris.change();
  281.                                         id=Tetris.id;
  282.                                 }
  283.                                 for (var c:int =area.left; c<area.right; c++) {//一列一列的尝试
  284.                                         _maps=copyMap(mapStr);//地图副本
  285.                                         getTetris();//直接放在地图第4行

  286.                                         if (moveX(c)) {//平移到c列
  287.                                                 moveY();//下落
  288.                                                 stop();//停止

  289.                                                 //show();
  290.                                                 var hang:int=delLineNum();//消行并返回行数
  291.                                                 //show();

  292.                                                 var value:int=assess(_maps,hang);//评估
  293.                                                 if (value >best[2]) {//记忆最佳值
  294.                                                         best[0]=id;
  295.                                                         best[1]=c;
  296.                                                         best[2]=value;
  297.                                                         best[3]=_maps.join("");
  298.                                                 }
  299.                                                 trace("Tetris.id+c+value=",id,c,value);
  300.                                         } else {
  301.                                                 //trace("无法平移到目标列");
  302.                                         }
  303.                                 }
  304.                         }
  305.                         return best;
  306.                 }
  307.                 public function getX(id:int=0) {
  308.                         return id%width;
  309.                 }
  310.                 public function getY(id:int=0) {
  311.                         return (id/width)>>0;
  312.                 }

  313.         }

  314. }
复制代码
//代码先发在这里,有时间我会来注释

as3版俄罗斯方块AI①@张志晨as3实例教程91
as3版俄罗斯方块AI②@张志晨as3实例教程91
as3版俄罗斯方块AI③@张志晨as3实例教程91
as3版俄罗斯方块AI④@张志晨as3实例教程91

as3版俄罗斯方块AI⑤@张志晨as3实例教程91
本帖的地址:http://bbs.jcwcn.com/forum.php?mod=viewthread&tid=539505
跟着教程做一遍,做完的图要到这里评论交作业,教程有看不懂的地方,可以在贴子下面评论
 楼主| 发表于 2014-3-25 18:16:56 | 显示全部楼层
酷素材
我能发帖子,自己却一点也看不见。 这是怎么回事???
回复 支持 反对

使用道具 举报

发表于 2014-4-19 22:21:39 | 显示全部楼层
受教了!感谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | [立即注册]

本版积分规则

2345