01.var AI = {}; 
02.new function(){ 
03.AI.Pattern= pattern; 
04.// 定义了 8 个偏移量 
05.// 可以简单通过加法得到任一点周围 8 个点的坐标 
06.// -11 -10 -9 
07.//  -1  x  1 
08.//  9  10 11 
09.// 如左上角的坐标为 x + (-11) 
10.var directions=[-11,-10,-9,-1,1,9,10,11]; 
11.function pattern() 
12.{ 
13.    // 把整个棋盘填满
14.    for(var i=0;i<100;i++)this[i]=0; 
15.    // 中间的 4 个格子,先放上两黑两白的棋子 
16.    this[54]=this[45]=1;this[55]=this[44]=2; 
17.    // 黑净胜外围子数目(黑减去白),估值时用。   
18.    this.divergence=0; 
19.    // 当前可走棋方为黑棋 
20.    lor=1; 
21.    // 已经走了几步棋 
22.    ves=0; 
23.    // 稳定原型 
24.    // 0 是空白,1 是黑棋,2 是白棋,3 是边界 
25.    // 8 * 8 的棋盘扩展成 10 * 10,是一种技巧 
26.    // 可以简化坐标有效性的判断 
27.    var stableProto = [   
28.        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
29.        3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
30.        3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
31.        3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
32.        3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
33.        3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
34.        3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
35.        3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
36.        3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
37.        3, 3, 3, 3, 3, 3, 3, 3, 3, 3 
38.    ] 
39.    // 从一个 8 * 8 的棋盘载入状态 
40.    this.load=function(arr) 
41.    { 
42.        for(var y=1;y<=8;y++) 
43.        { 
44.            for(var x=1;x<=8;x++) 
45.            { 
46.                this[y*10+x]=arr[y-1][x-1];       
47.            } 
48.        } 
49.    } 
50.    // 判断能不能 pass 
51.    // 如果能,则当前可走棋方变更 
52.    this.pass=function() 
53.    { 
54.        for(var y=1;y<=8;y++) 
55.        { 
56.            for(var x=1;x<=8;x++) 
57.            { 
58.                if(this[y*10+x]==0)   
59.                { 
60.                    // 有任何一步棋可走,都不可以 Pass 
61.                    ve(x,lor)) 
62.                    { 
63.                        return false; 
64.                    } 
65.                }                 
66.            } 
67.        } 
68.        //alert("pass"); 
69.        // 这是一个技巧,因为 lor 的值域是 {1, 2} 
70.        // 所以当 color 1 时,执行完下一语句后就是
71.        // lol洞主 color 2 时,执行完下一语句后就是
72.        lor = 3 - lor; 
73.        return true; 
74.    } 
75.    this.clone=function() 
76.    { 
77.        function pattern(){} 
78.        pattern.prototype=this; 
79.        return new pattern(); 
80.    } 
81.    String=function() 
82.    { 
83.        var icon=[" ","*","o"] 
84.        var r=""; 
85.        for(var y=1;y<=8;y++) 
86.        { 
87.            for(var x=1;x<=8;x++) 
88.            { 
89.                r+=icon[this[y*10+x]]+" "; 
90.                //r+=stableDiscs[y*10+x]+" "; 
91.            } 
92.            r+="\n"; 
93.        } 
94.        return act(); 
95.    } 
96.     
97.    // 净胜子数 
98.    act=function() 
99.    { 
100.        // 这里是一个技巧, r[0] 是不使用的,r[1] r[2] 对应黑白棋子的个数 
101.        var r=[0,0,0]; 
102.        for(var y=1;y<=8;y++) 
103.        { 
104.            for(var x=1;x<=8;x++) 
105.            { 
106.                r[this[y*10+x]]++; // 数目加一 
107.            } 
108.        } 
109.        // 当前颜的数量 0,输了,返回负极值 
110.        if(lor]==0) return -64; 
111.        // 敌对颜的数量为 0,赢了,返回极值 
112.        if(lor]==0) return 64; 
113.        // 返回当前走棋方比对方多的数量 
114.        return lor]-lor]; 
115.    } 
116.    // 对棋盘的估值 
117.    this.calculate=function() 
118.    { 
119.        // 基本估值方法: 
120.        // 1、能占棋盘四角是很有价值的 
121.        // 2、邻近棋盘四角的位子是很差的 
122.        // 3、稳定子 
123.        // 4、外围子净胜数 
124.        var r=[0,0,0]; 
125.        var r=this.divergence; 
126.        // 如果左上角有棋子,自己的,就+30分,敌方的,-30    
127.        if(this[11])    r+=((this[11]==lor)?1:-1)*30; 
128.    // 次左上角,分值是 -15 
129.        else if(this[22]==lor)r-=15; 
130.        // 右上角,分值 30 
131.        if(this[18])r+=((this[18]==lor)?1:-1)*30; 
132.        // 次右上角,分值 -15 
133.        else if(this[27]==lor)r-=15;