·您当前的位置:首页 > 技术教程 > AS2与AS3技术 >

[AS3]as3.0中国麻将算法中国牌技算法源代码实例

时间:2013-12-02 17:29oschina.net
as3.0中国麻将算法中国牌技算法源代码实例,看着头大。as3麻将算法,as3牌技算法

as3.0中国麻将算法中国牌技算法源代码实例,看着头大。

  1. /** 
  2. * 麻将算法 
  3. * @author Michael 
  4. * @home http://hi.baidu.com/wwwanq/ 
  5. * @E-mail xuzhenhui0425@163.com 
  6. * @qq 444153452 
  7. */ 
  8.  
  9. package { 
  10.  public class Search { 
  11.   private static const HASH_ALPHA:int = 1
  12.   private static const HASH_BETA:int = 2
  13.   private static const HASH_PV:int = 3
  14.   private static const LIMIT_DEPTH:int = 64
  15.   private static const NULL_DEPTH:int = 2
  16.   private static const RANDOM_MASK:int = 7
  17.   private static const MAX_GEN_MOVES:int = Position.MAX_GEN_MOVES; 
  18.   private static const MATE_VALUE:int = Position.MATE_VALUE; 
  19.   private static const BAN_VALUE:int = Position.BAN_VALUE; 
  20.   private static const WIN_VALUE:int = Position.WIN_VALUE; 
  21.   private static const NO_NULL:Boolean = true
  22.  
  23.   private var nHashMask:int, mvResult:int, nAllNodes:int, nAllMillis:int; 
  24.   private var hshTable:Array; 
  25.  
  26.   public var pos:Position; 
  27.   public var nHistoryTable = new Array(4096); 
  28.   public var mvKiller1 = new Array(LIMIT_DEPTH); 
  29.   public var mvKiller2 = new Array(LIMIT_DEPTH); 
  30.  
  31.   public function Search(pos_:Position, nHashLevel:int) { 
  32.    pos = pos_
  33.    nHashMask = (1 << nHashLevel) - 1; 
  34.    hshTable = new Array(nHashMask + 1); 
  35.    var i:int; 
  36.    for (i = 0; i <= nHashMask; i ++) { 
  37.     hshTable[i] = new HashItem(); 
  38.    } 
  39.   } 
  40.  
  41.   private function getHashItem():HashItem { 
  42.    return hshTable[pos.dwKey & nHashMask]; 
  43.   } 
  44.  
  45.   private function probeHash(vlAlpha:int, vlBeta:int, nDepth:int, mv:Array):int { 
  46.    var hsh:HashItem = getHashItem(); 
  47.    if (hsh.dwLock != pos.dwLock) { 
  48.     mv[0] = 0; 
  49.     return -MATE_VALUE; 
  50.    } 
  51.    mv[0] = hsh.mv; 
  52.    var bMate:Boolean = false
  53.    if (hsh.vl > WIN_VALUE) { 
  54.     if (hsh.vl <= BAN_VALUE) { 
  55.      return -MATE_VALUE; 
  56.     } 
  57.     hsh.vl -pos.nDistance; 
  58.     bMate = true
  59.    } else if (hsh.vl < -WIN_VALUE) { 
  60.     if (hsh.vl >= -BAN_VALUE) { 
  61.      return -MATE_VALUE; 
  62.     } 
  63.     hsh.vl += pos.nDistance; 
  64.     bMate = true
  65.    } else if (hsh.vl == pos.drawValue()) { 
  66.     return -MATE_VALUE; 
  67.    } 
  68.    if (hsh.nDepth >= nDepth || bMate) { 
  69.     if (hsh.nFlag == HASH_BETA) { 
  70.      return (hsh.vl >= vlBeta ? hsh.vl : -MATE_VALUE); 
  71.     } else if (hsh.nFlag == HASH_ALPHA) { 
  72.      return (hsh.vl <= vlAlpha ? hsh.vl : -MATE_VALUE); 
  73.     } 
  74.     return hsh.vl; 
  75.    } 
  76.    return -MATE_VALUE; 
  77.   } 
  78.  
  79.   private function recordHash(nFlag:int, vl:int, nDepth:int, mv:int):void { 
  80.    var hsh:HashItem = getHashItem(); 
  81.    if (hsh.nDepth > nDepth) { 
  82.     return; 
  83.    } 
  84.    hsh.nFlag = nFlag; 
  85.    hsh.nDepth = nDepth; 
  86.    if (vl > WIN_VALUE) { 
  87.     if (mv == 0 && vl <= BAN_VALUE) { 
  88.      return; 
  89.     } 
  90.     hsh.vl = vl + pos.nDistance; 
  91.    } else if (vl < -WIN_VALUE) { 
  92.     if (mv == 0 && vl >= -BAN_VALUE) { 
  93.      return; 
  94.     } 
  95.     hsh.vl = vl - pos.nDistance; 
  96.    } else if (vl == pos.drawValue() && mv == 0) { 
  97.     return; 
  98.    } else { 
  99.     hsh.vl = vl; 
  100.    } 
  101.    hsh.mv = mv; 
  102.    hsh.dwLock = pos.dwLock; 
  103.   } 
  104.  
  105.   private function setBestMove(mv:int, nDepth:int):void { 
  106.    nHistoryTable[pos.historyIndex(mv)] += nDepth * nDepth; 
  107.    if (mvKiller1[pos.nDistance] != mv) { 
  108.     mvKiller2[pos.nDistance] = mvKiller1[pos.nDistance]; 
  109.     mvKiller1[pos.nDistance] = mv; 
  110.    } 
  111.   } 
  112.  
  113.   private function searchQuiesc(vlAlpha:int, vlBeta:int):int { 
  114.    nAllNodes ++; 
  115.    var vl:int = pos.nDistance - MATE_VALUE; 
  116.    if (vl >= vlBeta) { 
  117.     return vl; 
  118.    } 
  119.    var vlRep:int = pos.repStatus(); 
  120.    if (vlRep > 0) { 
  121.     return pos.repValue(vlRep); 
  122.    } 
  123.    if (pos.nDistance == LIMIT_DEPTH) { 
  124.     return pos.evaluate(); 
  125.    } 
  126.    var vlBest:int = -MATE_VALUE; 
  127.    var i:int, nGenMoves:int; 
  128.    var mvs:Array = new Array(MAX_GEN_MOVES); 
  129.    var vls:Array = new Array(MAX_GEN_MOVES); 
  130.    if (pos.inCheck()) { 
  131.     nGenMoves = pos.generateMoves(mvs); 
  132.     for (i = 0; i < nGenMoves; i ++) { 
  133.      vls[i] = nHistoryTable[pos.historyIndex(mvs[i])]; 
  134.     } 
  135.     Util.shellSort(mvs, vls, 0, nGenMoves); 
  136.    } else { 
  137.     vl = pos.evaluate(); 
  138.     if (vl > vlBest) { 
  139.      if (vl >= vlBeta) { 
  140.       return vl; 
  141.      } 
  142.      vlvlBest = vl; 
  143.      if (vl > vlAlpha) { 
  144.       vlvlAlpha = vl; 
  145.      } 
  146.     } 
  147.     nGenMoves = pos.generateMoves(mvs, vls); 
  148.     Util.shellSort(mvs, vls, 0, nGenMoves); 
  149.     for (i = 0; i < nGenMoves; i ++) { 
  150.      if (vls[i] < 10 || (vls[i] < 20 && Position.HOME_HALF(Position.DST(mvs[i]), pos.sdPlayer))) { 
  151.       nGenMoves = i
  152.       break; 
  153.      } 
  154.     } 
  155.    } 
  156.    for (i = 0; i < nGenMoves; i ++) { 
  157.     if (!pos.makeMove(mvs[i])) { 
  158.      continue; 
  159.     } 
  160.     vl = -searchQuiesc(-vlBeta, -vlAlpha); 
  161.     pos.undoMakeMove(); 
  162.     if (vl > vlBest) { 
  163.      if (vl >= vlBeta) { 
  164.       return vl; 
  165.      } 
  166.      vlvlBest = vl; 
  167.      if (vl > vlAlpha) { 
  168.       vlvlAlpha = vl; 
  169.      } 
  170.     } 
  171.    } 
  172.    return vlBest == -MATE_VALUE ? pos.nDistance - MATE_VALUE: vlBest; 
  173.   } 
  174.  
  175.   private function searchFull(vlAlpha:int, vlBeta:int, nDepth:int, bNoNull:Boolean = false):int { 
  176.    if (nDepth <= 0) { 
  177.     return searchQuiesc(vlAlpha, vlBeta); 
  178.    } 
  179.    nAllNodes ++; 
  180.    var vl:int = pos.nDistance - MATE_VALUE; 
  181.    if (vl >= vlBeta) { 
  182.     return vl; 
  183.    } 
  184.    var vlRep:int = pos.repStatus(); 
  185.    if (vlRep > 0) { 
  186.     return pos.repValue(vlRep); 
  187.    } 
  188.    var mvHash:Array = new Array(1); 
  189.    vl = probeHash(vlAlpha, vlBeta, nDepth, mvHash); 
  190.    if (vl > -MATE_VALUE) { 
  191.     return vl; 
  192.    } 
  193.    if (pos.nDistance == LIMIT_DEPTH) { 
  194.     return pos.evaluate(); 
  195.    } 
  196.    if (!bNoNull && !pos.inCheck() && pos.nullOkay()) { 
  197.     pos.nullMove(); 
  198.     vl = -searchFull(-vlBeta, 1 - vlBeta, nDepth - NULL_DEPTH - 1, NO_NULL); 
  199.     pos.undoNullMove(); 
  200.     if (vl >= vlBeta && (pos.nullSafe() && searchFull(vlAlpha, vlBeta, nDepth, NO_NULL) >= vlBeta)) { 
  201.      return vl; 
  202.     } 
  203.    } 
  204.    var nHashFlag:int = HASH_ALPHA
  205.    var vlBest:int = -MATE_VALUE; 
  206.    var mvBest:int = 0
  207.    var sort:SortItem = new SortItem(this, mvHash[0]); 
  208.    var mv:int; 
  209.    while ((mv = sort.nextMove()) > 0) { 
  210.     if (!pos.makeMove(mv)) { 
  211.      continue; 
  212.     } 
  213.     var nNewDepth:int = pos.inCheck() ? nDepth : nDepth - 1; 
  214.     if (vlBest == -MATE_VALUE) { 
  215.      vl = -searchFull(-vlBeta, -vlAlpha, nNewDepth); 
  216.     } else { 
  217.      vl = -searchFull(-vlAlpha - 1, -vlAlpha, nNewDepth); 
  218.      if (vl > vlAlpha && vl < vlBeta) { 
  219.       vl = -searchFull(-vlBeta, -vlAlpha, nNewDepth); 
  220.      } 
  221.     } 
  222.     pos.undoMakeMove(); 
  223.     if (vl > vlBest) { 
  224.      vlvlBest = vl; 
  225.      if (vl >= vlBeta) { 
  226.       nHashFlag = HASH_BETA
  227.       mvmvBest = mv; 
  228.       break; 
  229.      } 
  230.      if (vl > vlAlpha) { 
  231.       vlvlAlpha = vl; 
  232.       nHashFlag = HASH_PV
  233.       mvmvBest = mv; 
  234.      } 
  235.     } 
  236.    } 
  237.    if (vlBest == -MATE_VALUE) { 
  238.     return pos.nDistance - MATE_VALUE; 
  239.    } 
  240.    recordHash(nHashFlag, vlBest, nDepth, mvBest); 
  241.    if (mvBest > 0) { 
  242.     setBestMove(mvBest, nDepth); 
  243.    } 
  244.    return vlBest; 
  245.   } 
  246.  
  247.   private function searchRoot(nDepth):int { 
  248.    var vlBest:int = -MATE_VALUE; 
  249.    var sort:SortItem = new SortItem(this, mvResult); 
  250.    var mv:int; 
  251.    while ((mv = sort.nextMove()) > 0) { 
  252.     if (!pos.makeMove(mv)) { 
  253.      continue; 
  254.     } 
  255.     var nNewDepth = pos.inCheck() ? nDepth : nDepth - 1; 
  256.     var vl:int; 
  257.     if (vlBest == -MATE_VALUE) { 
  258.      vl = -searchFull(-MATE_VALUE, MATE_VALUE, nNewDepth, NO_NULL); 
  259.     } else { 
  260.      vl = -searchFull(-vlBest - 1, -vlBest, nNewDepth); 
  261.      if (vl > vlBest) { 
  262.       vl = -searchFull(-MATE_VALUE, -vlBest, nNewDepth, NO_NULL); 
  263.      } 
  264.     } 
  265.     pos.undoMakeMove(); 
  266.     if (vl > vlBest) { 
  267.      vlvlBest = vl; 
  268.      mvmvResult = mv; 
  269.      if (vlBest > -WIN_VALUE && vlBest < WIN_VALUE) { 
  270.       vlBest += int(Math.random() * RANDOM_MASK) - int(Math.random() * RANDOM_MASK); 
  271.       vlBest = (vlBest == pos.drawValue() ? vlBest - 1 : vlBest); 
  272.      } 
  273.     } 
  274.    } 
  275.    setBestMove(mvResult, nDepth); 
  276.    return vlBest; 
  277.   } 
  278.  
  279.   public function searchMain(nMillis:int, nDepth:int = LIMIT_DEPTH):int { 
  280.    mvResult = pos.bookMove(); 
  281.    if (mvResult > 0) { 
  282.     pos.makeMove(mvResult); 
  283.     if (pos.repStatus(3) == 0) { 
  284.      pos.undoMakeMove(); 
  285.      return mvResult; 
  286.     } 
  287.     pos.undoMakeMove(); 
  288.    } 
  289.    var vl:int = 0
  290.    var mvs:Array = new Array(MAX_GEN_MOVES); 
  291.    var nGenMoves:int = pos.generateMoves(mvs); 
  292.    var i:int; 
  293.    for (i = 0; i < nGenMoves; i ++) { 
  294.     if (pos.makeMove(mvs[i])) { 
  295.      pos.undoMakeMove(); 
  296.      mvResult = mvs[i]; 
  297.      vl ++; 
  298.     } 
  299.    } 
  300.    if (vl == 1) { 
  301.     return mvResult; 
  302.    } 
  303.    for (i = 0; i <= nHashMask; i ++) { 
  304.     var hsh:HashItem = hshTable[i]; 
  305.     hshhsh.nDepth = hsh.nFlag = hsh.vl = hsh.mv = 0
  306.     hsh.dwLock = 0
  307.    } 
  308.    for (i = 0; i < LIMIT_DEPTH; i ++) { 
  309.     mvKiller1[i] = mvKiller2[i] = 0; 
  310.    } 
  311.    for (i = 0; i < 4096; i ++) { 
  312.     nHistoryTable[i] = 0; 
  313.    } 
  314.    mvResult = 0
  315.    nAllNodes = 0
  316.    pos.nDistance = 0
  317.    var t:Number = new Date().getTime(); 
  318.    for (i = 1; i <= nDepth; i ++) { 
  319.     vl = searchRoot(i); 
  320.     if (vl > WIN_VALUE || vl < -WIN_VALUE) { 
  321.      break; 
  322.     } 
  323.     nAllMillis = new Date().getTime() - t; 
  324.     if (nAllMillis > nMillis) { 
  325.      break; 
  326.     } 
  327.    } 
  328.    return mvResult; 
  329.   } 
  330.  
  331.   public function getKNPS():int { 
  332.    return nAllNodes / nAllMillis; 
  333.   } 
  334.  } 

 

热门文章推荐

请稍候...

保利威视云平台-轻松实现点播直播视频应用

酷播云数据统计分析跨平台播放器