Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/adorphuye/othello/player/AIPlayer.java


1   package com.adorphuye.othello.player;
2   
3   import com.adorphuye.othello.gui.board.*;
4   import com.adorphuye.othello.*;
5   import java.awt.*;
6   import java.util.*;
7   import java.io.*;
8   
9   public class AIPlayer extends Player implements BoardListener
10  {  
11    private int maxlevel;
12    
13    /**
14     * @return  */  
15    public String toString()
16    {
17      return "Computer "+getIndex();
18    }
19    
20    int[][] weight= new int[][]
21    {
22      {8, 0,-7, 2,-8},
23      {2, 0,-2, 1,-6},
24      {2, 3, 1,-2, 1},
25      {1,-2, 0,-1, 0},
26      {1,-2,-1, 4, 3}
27    };
28    
29    /**
30     * @param l  */  
31    public void setDepth(int l)
32    {
33      if(l<MIN_DEPTH || l>MAX_DEPTH)
34      {
35        throw new IllegalArgumentException("Illegal ai thinking depth: "+l);
36      }
37      maxlevel=l;
38    }
39    
40    /**
41     * set the weight vector this player should use.
42     * @param w  */
43    public void setweight(int[][] w)
44    {
45      weight=w;
46    }
47      
48    /**
49     * @param mod
50     * @param num  */  
51    public AIPlayer(BoardDataModel mod, int num)
52    {
53      super(mod,num);
54      setDepth(DEFAULT_DEPTH);
55    }
56    
57    private boolean shouldMove = true;
58        
59    /**
60     */  
61    public void play()
62    {
63      Thread t = new Thread()
64      {
65        public void run()
66        {
67          try
68          {
69            long ll = System.currentTimeMillis();
70            Point move = bestmove(getSide());
71            sleep(Math.max(250,250-(System.currentTimeMillis()-ll)));
72            if(!shouldMove)
73            {
74              shouldMove = true;
75              getModel().nextSide();
76              return;
77            }
78            if(move!=null)
79            {            
80              java.util.Vector hs = getModel().flips(move,getSide());
81  
82              getModel().setDataAt(move,getSide());
83  
84              for(int i=0;i<hs.size();i++)
85              {
86                Point pos = (Point)hs.elementAt(i);
87                getModel().setDataAt(pos,getSide());              
88              }
89            }
90            else
91            {
92              getModel().pass(AIPlayer.this);
93            }
94            getModel().nextSide();
95          }
96          catch(InterruptedException e)
97          {
98          }
99          
100       }
101     };
102     
103     t.start();
104   }
105   
106   /**
107    * @param ob
108    * @return  */  
109   public Point bestmove(int ob)
110   {
111 
112     Vector k=getModel().getPossibleMoves(getSide());
113 
114     BoardDataModel workarea = (BoardDataModel)getModel().clone();
115 
116     if(k.size()==0)
117     {
118       return null;
119     }
120     
121     int best = -1;
122     int s = best;
123     
124     int alpha=-100000;
125     Point tmp = null;
126     for(int i=0;i<k.size();i++)
127     {
128       tmp = (Point)k.elementAt(i);
129       //workarea.setDataAt(tmp,getSide());
130       //s=-prognosis(workarea,-100000,-alpha,1);
131       
132       s = -(int)((double)worth(tmp)*((double)(workarea.flips(tmp,getSide()).size())));
133       //System.out.println("EVAL: "+tmp+" worth="+s);  
134       //workarea.setDataAt(tmp,DefaultBoardDataModel.EMPTY);
135       
136       
137       if(s>alpha)
138       {
139         alpha=s;
140         best=i;
141       }
142     }
143     tmp = (Point)k.elementAt(best);
144     //System.out.println("Choosing "+tmp+" with worth "+worth(tmp));  
145     return tmp;
146   }
147   
148   /**
149    * @param workarea
150    * @param alpha
151    * @param beta
152    * @param level
153    * @return  */  
154   private int prognosis(BoardDataModel workarea, int alpha, int beta, int level)
155   {
156     if(level>maxlevel || workarea.getPossibleMoves(getSide()).size()==0)
157     {
158       return simplescore();
159     }
160     
161     int s;
162 
163     Vector k = workarea.getPossibleMoves(getSide());
164     
165     for(int i=0;i<k.size();i++)
166     {
167       Point tmp = (Point)k.elementAt(i);
168       workarea.setDataAt(tmp,getSide());
169       
170       s=-prognosis(workarea,-beta,-alpha,level+1);
171 
172       workarea.setDataAt(tmp,DefaultBoardDataModel.EMPTY);
173       
174       if(s>beta)
175       {
176         return s;
177       }
178       
179       if(s>alpha)
180       {
181         alpha=s;
182       }
183     }
184     
185     return alpha;
186   }
187 
188   /**
189    * @param location
190    * @return  */  
191   private int worth(Point location)
192   {
193     try
194     {
195       return positionalValues[location.x][location.y];
196       }
197       catch(Exception e)
198       {
199         return 0;
200       }
201   }
202     
203   private int[] out;
204   
205   /**
206    * @return  */  
207   private int simplescore()
208   {
209     int score=0;
210     
211     int[][] out = (int[][])positionalValues.clone();
212     
213     for(int i=0;i<out.length;i++)
214     {
215       for(int j = 0;j<out[0].length;j++)
216       {
217         int o = getModel().getDataAt(new Point(i,j));
218         
219         if(o != DefaultBoardDataModel.EMPTY) // if it's empty - no change in worth
220         {
221           if(o == getSide())
222           {
223             // one for us!
224             out[i][j]++;
225           }
226           else
227           {
228             // one for them :-(
229             out[i][j]--;
230           }
231           score+=out[i][j];
232         }
233       }
234     }
235 
236     return score;
237   }
238   
239   /**
240    * @param evt  */  
241   public void boardChanged(BoardEvent evt)
242   {
243   }
244   
245   public void reset()
246   {
247     shouldMove = false;
248   }
249   
250   private static final int[][] positionalValues = new int[][]
251   {
252     {-10,  8,  3,  3,  3,  3,  8,-10},
253     {  8,  9,  4,  7,  7,  4,  9,  8},
254     {  3,  4,  5,  8,  8,  5,  4,  3},
255     {  3,  7,  8,  9,  9,  8,  7,  3},
256     {  3,  7,  8,  9,  9,  8,  7,  3},
257     {  3,  4,  5,  8,  8,  5,  4,  3},
258     {  8,  9,  4,  7,  7,  4,  9,  8},
259     {-10,  8,  3,  3,  3,  3,  8,-10}
260   };
261 }