java版数独游戏

闲来无事,想到了手机里面有的数独游戏,感觉太简单,所以我就想着自己写一个,设定不同的难度,正好熟悉一下swing编程,练练手

  1 import java.awt.Color;
  2 import java.awt.Font;
  3 import java.awt.GridLayout;
  4 import java.util.ArrayList;
  5 import java.util.HashMap;
  6 import java.util.List;
  7 import java.util.Map;
  8 import java.util.Random;
  9 import java.util.regex.Pattern;
 10 
 11 import javax.swing.BorderFactory;
 12 import javax.swing.JFrame;
 13 import javax.swing.JPanel;
 14 import javax.swing.JTextField;
 15 import javax.swing.event.DocumentEvent;
 16 import javax.swing.event.DocumentListener;
 17 import javax.swing.text.BadLocationException;
 18 import javax.swing.text.Document;
 19 
 20 public class SudokuGame extends JFrame implements DocumentListener {
 21 
 22     private static final long serialVersionUID = 1L;
 23     private JPanel[] pnlGame;
 24     private JTextField[][][] txtGame;
 25     private Map<JTextField, JTextField> warnFiledMap = new HashMap<JTextField, JTextField>();
 26     private Document doc;
 27     private static final int YES = 1;// 单元格可取值存在 ; 已回滚;已冲突
 28     private static final int NO = 0;// 单元格可取值不存在 ;未回滚;未冲突
 29     private static final int NEED_ROLLBACK = 10;// 需要回滚
 30     private int is_num = YES; //输入的是不是数字标记
 31     private int is_remove_by_insert = NO;//remove是不是在已有值的前提下insert一个新值导致的
 32     
 33     private Grid[][][] grids = new Grid[9][3][3];
 34 
 35     public SudokuGame() {
 36         pnlGame = new JPanel[9];
 37         txtGame = new JTextField[9][3][3];
 38         gameInit();
 39     }
 40 
 41     /**
 42      * 游戏初始化
 43      */
 44     @SuppressWarnings("static-access")
 45     public void gameInit() {
 46         this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
 47         this.setSize(300, 300);
 48         this.setResizable(false);
 49         this.setTitle("数独游戏");
 50         this.setLayout(new GridLayout(3, 3));
 51         for (int i = 0; i < 9; i++) {
 52             pnlGame[i] = new JPanel();
 53             pnlGame[i].setBorder(BorderFactory.createLineBorder(Color.black));
 54             pnlGame[i].setLayout(new GridLayout(3, 3));
 55             this.add(pnlGame[i]);
 56         }
 57 
 58         for (int z = 0; z < 9; z++) {
 59             for (int x = 0; x < 3; x++) {
 60                 for (int y = 0; y < 3; y++) {
 61                     txtGame[z][x][y] = new JTextField();
 62                     txtGame[z][x][y].setBorder(BorderFactory
 63                             .createEtchedBorder());
 64                     txtGame[z][x][y]
 65                             .setFont(new Font("Dialog", Font.ITALIC, 20));// 设置字体大小
 66                     txtGame[z][x][y].setHorizontalAlignment(JTextField.CENTER);// 设置字体居中
 67                     pnlGame[z].add(txtGame[z][x][y]);
 68                 }
 69             }
 70 
 71         }
 72         this.init();// 九宫格数据初始化,生成完整正确的九宫格
 73         this.setGameLevel(3);// 根据完整的九宫格生成不同难度的数独游戏
 74         for (int z = 0; z < 9; z++) {// 9宫格的行
 75             for (int x = 0; x < 3; x++) {// 9宫格的列
 76                 for (int y = 0; y < 3; y++) {
 77                     if (grids[z][x][y].getValue() != 10) {
 78                         txtGame[z][x][y].setText(grids[z][x][y].getValue() + "");
 79                         txtGame[z][x][y].setEditable(false);
 80                     } else {
 81                         txtGame[z][x][y].getDocument().addDocumentListener(this);
 82 
 83                     }
 84                 }
 85             }
 86         }
 87         this.setVisible(true);
 88     }
 89 
 90     /**
 91      * 生成完整的正确填完的九宫格
 92      */
 93     void init() {
 94         int value = 0;
 95         int[] backlocation;
 96         int i = 0, j = 0;
 97         int tag_rollback = NO, tag_validValues_exist;// 是否回滚到上一个单元格的标记,单元格的可取值是否已过滤过,可取值是否存在
 98         back: for (int z = 0; z < 9; z++) {// 9宫格的行
 99             for (int x = i; x < 3; x++) {// 9宫格的列
100                 for (int y = j; y < 3; y++) {
101                     if (tag_rollback == 1) {
102                         i = 0;
103                         j = 0;
104                         tag_rollback = NO;// 回滚了一次之后,回归正常状态继续遍历
105                     }
106                     if (null == grids[z][x][y]) {
107                         grids[z][x][y] = new Grid(z, x, y);
108                         tag_validValues_exist = NO;// 表示单元格的值是刚初始化的,需要过滤
109                     } else {
110                         tag_validValues_exist = YES;// 表示单元格的值是过滤过的
111                     }
112                     value = getValidValue(grids[z][x][y], tag_validValues_exist);
113                     if (value == NEED_ROLLBACK) {
114 
115                         backlocation = backlocation(z, x, y);
116                         reset(grids[z][x][y]);// 将该单元格重置
117 
118                         z = backlocation[0] - 1;// 这里z-2是因为跳到back之后,z会直接自增一次,所以减去2个才能跳转成上一个单元格
119                         i = backlocation[1];
120                         j = backlocation[2];
121                         tag_rollback = YES;// 从i,j,k指定的位置开始再次遍历
122                         continue back;// 重新开始前一个单元格的遍历
123                     } else {
124                         grids[z][x][y].setValue(value);
125                     }
126                 }
127             }
128         }
129     }
130 
131     // 游戏难度分级 0-3 分别为:简单、中等、困难、骨灰级
132     void setGameLevel(int level) {
133 
134         int blank_max, blank_min;// blank代表每个单元格最多和最少空几个让玩家填,
135 
136         switch (level) {
137         case 0:
138             blank_max = 4;
139             blank_min = 2;
140             blankInit(blank_max, blank_min);
141             break;
142         case 1:
143             blank_max = 6;
144             blank_min = 4;
145             blankInit(blank_max, blank_min);
146             break;
147         case 2:
148             blank_max = 8;
149             blank_min = 6;
150             blankInit(blank_max, blank_min);
151             break;
152         case 3:
153             blank_max = 9;
154             blank_min = 6;
155             blankInit(blank_max, blank_min);
156             break;
157         }
158     }
159 
160     void blankInit(int blank_max, int blank_min) {
161         Random rd = new Random();
162         List<Integer> list = new ArrayList<Integer>();
163         int count, index;// count代表实际的空白数,index代表空白的单元格位置
164 
165         for (int z = 0; z < 9; z++) {
166             count = 0;
167             while (count < blank_min) {// 每个小9宫格随机出现最大和最小空白之间的空白个数
168                 count = rd.nextInt(blank_max + 1);
169             }
170             for (int i = 1; i <= count; i++) {
171                 index = rd.nextInt(9);
172                 if (list.contains(index)) {// 如果空白选项里已经含有当前位置就重新取
173                     i--;
174                 } else {// 如果空白选项里已经没有含有当前位置就添加
175                     list.add(index);
176                 }
177             }
178             for (int j : list) {
179                 grids[z][j / 3][j % 3].setValue(10);// 根据j让一个小9宫格里面的9个格子随机空白
180                                                     // 10就代表这个格子空白
181             }
182             list.clear();
183         }
184     }
185 
186     /**
187      * 每个单元格的类 坐标 取值 可取值队列
188      * 
189      * @author yhd
190      * 
191      */
192     class Grid {
193         private int x;// 对应每个小单元格的横坐标
194         private int y;// 对应每个小单元格的纵坐标
195         private int z;// 对应每个小9宫格
196         private int value;// 最终取得值
197         private List<Integer> validValues;// 可以取的值
198 
199         public Grid(int z, int x, int y) {
200             this.x = x;
201             this.y = y;
202             this.z = z;
203             if (validValues == null) {
204                 validValues = new ArrayList<Integer>();
205                 for (int i = 1; i < 10; i++) {
206                     validValues.add(i);
207                 }
208             }
209         }
210 
211         public int getX() {
212             return x;
213         }
214 
215         public void setX(int x) {
216             this.x = x;
217         }
218 
219         public int getY() {
220             return y;
221         }
222 
223         public void setY(int y) {
224             this.y = y;
225         }
226 
227         public int getZ() {
228             return z;
229         }
230 
231         public void setZ(int z) {
232             this.z = z;
233         }
234 
235         public List<Integer> getValidValues() {
236             return validValues;
237         }
238 
239         public void setValidValues(List<Integer> validValues) {
240             this.validValues = validValues;
241         }
242 
243         public int getValue() {
244             return value;
245         }
246 
247         public void setValue(int value) {
248             this.value = value;
249         }
250 
251     }
252 
253     // 0 1 2 z的布局 整体布局
254     // 3 4 5
255     // 6 7 8
256     // 0 1
257     // (0,0,0) (0,0,1) (0,0,2) (1,0,0)
258     // (0,1,0) (0,1,1) (0,1,2) (1,1,0)
259     // (0,2,0) (0,2,1) (0,2,2) (1,2,0)
260     // 3 4
261     // (3,0,0) (3,0,1) (3,0,2) (4,0,0) 详细布局
262 
263     // 当某单元格没有可取值时,回到上一个单元格
264     int[] backlocation(int z, int x, int y) {
265         int[] location = new int[3];// 存贮上一个单元格的位置信息 z x y
266         switch (x + y) {// 根据当前单元格的坐标和找到上一个元素的坐标
267         case 0:
268             location[0] = z - 1;
269             location[1] = 2;
270             location[2] = 2;
271             break;
272         case 1:
273             if (x < y) {
274                 location[0] = z;
275                 location[1] = 0;
276                 location[2] = 0;
277                 break;
278             } else {
279                 location[0] = z;
280                 location[1] = 0;
281                 location[2] = 2;
282                 break;
283             }
284         case 2:
285             if (x < y) {
286                 location[0] = z;
287                 location[1] = 0;
288                 location[2] = 1;
289                 break;
290             } else if (x > y) {
291                 location[0] = z;
292                 location[1] = 1;
293                 location[2] = 2;
294                 break;
295             } else {
296                 location[0] = z;
297                 location[1] = 1;
298                 location[2] = 0;
299                 break;
300             }
301         case 3:
302             if (x < y) {
303                 location[0] = z;
304                 location[1] = 1;
305                 location[2] = 1;
306                 break;
307             } else {
308                 location[0] = z;
309                 location[1] = 2;
310                 location[2] = 0;
311                 break;
312             }
313         case 4:
314             location[0] = z;
315             location[1] = 2;
316             location[2] = 1;
317             break;
318         }
319         return location;
320     }
321 
322     /**
323      * 一旦无数字可填,就回溯到上一个单元格,当前单元格的可取值列表和值重置
324      * 
325      * @param grid
326      */
327     // 这里开发时遇到了java引用传递的问题,之前的代码如:grid=null
328     // 结果发现只要有回溯,就会一直回溯到0 0 0,不是回溯一次改个值继续下面的遍历
329     // 原来是这里的问题,引用地址传递过来后,这个grid副本存的地址清空了,并不是传进来的那个
330     // grid清空了,所以导致了回溯的那些单元格一直没有被重置,无值可取,才会不断回溯的
331     void reset(Grid grid) {
332         int z = grid.getZ();
333         int x = grid.getX();
334         int y = grid.getY();
335         grids[z][x][y] = null;
336     }
337 
338     /**
339      * 获取某个单元格可以取的值
340      */
341     int getValidValue(Grid grid, int tag_validValues_exist) {
342         Random rd = new Random();
343         int index, grid_validValues_isExist = YES, last;
344 
345         int existValue, value;
346 
347         int zx_index = 0;// 以z为标准,x轴方向的遍历起点
348         int zy_index = 0;// 以z为标准,y轴方向的遍历起点
349 
350         if (tag_validValues_exist == NO) {
351             switch (grid.getZ() % 3) {
352             case 0:
353                 zx_index = grid.getZ();
354                 break; // 表示如果是0 3 6对应的小九宫格
355             case 1:
356                 zx_index = grid.getZ() - 1;
357                 break; // 同理表示 1 4 7
358             case 2:
359                 zx_index = grid.getZ() - 2;
360                 break; // 同理表示2 5 8
361             }
362 
363             if (grid.getZ() >= 6) {
364                 zy_index = grid.getZ() - 6; // 对应6 7 8 y轴方向起点为0 1 2
365             } else if (grid.getZ() >= 3) {
366                 zy_index = grid.getZ() - 3; // 对应3 4 5 y轴方向起点为0 1 2
367             } else {
368                 zy_index = grid.getZ(); // 对应0 1 2 y轴方向起点为0 1 2
369             }
370 
371             for (; zx_index < grid.getZ(); zx_index++) {
372                 // 去除同一行已存在的数据
373                 for (int y = 0; y < 3; y++) {
374                     existValue = grids[zx_index][grid.getX()][y].getValue();// 获取该单元格之前同一行的不同列的值
375                     grid_validValues_isExist = removeExistValue(grid,
376                             existValue);
377                 }
378             }
379             if (grid_validValues_isExist == NO) {
380                 return NEED_ROLLBACK;
381             }
382             // 去除同一列已存在的数据
383             for (; zy_index < grid.getZ(); zy_index += 3) {
384                 for (int x = 0; x < 3; x++) {
385                     existValue = grids[zy_index][x][grid.getY()].getValue();// 获取该单元格之前同一列的不同列的值
386                     grid_validValues_isExist = removeExistValue(grid,
387                             existValue);
388                 }
389             }
390             if (grid_validValues_isExist == NO) {
391                 return NEED_ROLLBACK;
392             }
393             // 去除同一个小九宫格里面的不同的值
394             for (int x = 0; x <= grid.getX(); x++) {
395                 if (x == grid.getX()) {// 如果已经遍历到和该单元格一行时
396                     for (int y = 0; y < grid.getY(); y++) {
397                         existValue = grids[grid.getZ()][x][y].getValue();
398                         grid_validValues_isExist = removeExistValue(grid,
399                                 existValue);
400                     }
401                 } else {// 在这单元格所在行之前行时就完全遍历列
402                     for (int y = 0; y < 3; y++) {
403                         existValue = grids[grid.getZ()][x][y].getValue();
404                         grid_validValues_isExist = removeExistValue(grid,
405                                 existValue);
406                     }
407                 }
408             }
409             if (grid_validValues_isExist == NO) {
410                 return NEED_ROLLBACK;
411             }
412         }
413         if (grid.getValidValues().size() == 0) {
414             return NEED_ROLLBACK;
415         } else {
416             last = grid.getValidValues().size();
417         }
418         if (last == 0) {
419             index = 0;
420         } else {
421             index = rd.nextInt(last);// 返回该单元格的值
422                                         // 因为random的nextInt范围必须是[0,last),size和index有区别,index从0开始
423         }
424         value = grid.getValidValues().get(index);
425         removeExistValue(grid, value);// 一旦取过该值,就把这个值从该单元格中去掉
426         // System.out.println(grid.getZ()+" "+grid.getX()+" "+grid.getY()+" "+value);
427         return value;
428     }
429 
430     /**
431      * 移除单元格不能取得值和已经取过的值
432      * 
433      * @param grid
434      * @param existValue
435      * @return
436      */
437     int removeExistValue(Grid grid, int existValue) {
438         int index, grid_validValues_isExist = YES;
439         if (grid.getValidValues().size() == 0) {
440             grid_validValues_isExist = NO;
441         }
442 
443         if (grid.getValidValues().contains(existValue))// 如果同一列已存在该数据,则去除
444         {
445             index = grid.getValidValues().indexOf(existValue);// 找到该值存在的index
446             grid.getValidValues().remove(index);
447         }
448         return grid_validValues_isExist;
449     }
450 /**
451  * 检查输入的数字是否有冲突
452  * @param z1
453  * @param x1
454  * @param y1
455  */
456     private void checkValue(int z1, int x1, int y1) {
457         int[] zx = new int[2];// 以z为标准,x轴方向的遍历
458         int[] zy = new int[2];// 以z为标准,y轴方向的遍历
459         String value = txtGame[z1][x1][y1].getText();
460         value = value.substring(value.length()-1, value.length());
461         switch (z1 % 3) {
462         case 0:
463             zx[0] = z1 + 1;
464             zx[1] = z1 + 2;
465             break; // 表示如果是0 3 6对应的小九宫格,检查右边2个小九宫格
466         case 1:
467             zx[0] = z1 - 1;
468             zx[1] = z1 + 1;
469             break; // 同理表示 1 4 7 检查两侧小九宫格
470         case 2:
471             zx[0] = z1 - 2;
472             zx[1] = z1 - 1;
473             ;
474             break; // 同理表示2 5 8 检查左侧两个小九宫格
475         }
476 
477         if (z1 >= 6) {
478             zy[0] = z1 - 6; // 对应6 7 8 检查它上面2个小九宫格
479             zy[1] = z1 - 3;
480         } else if (z1 >= 3) {
481             zy[0] = z1 - 3; // 对应3 4 5 检查它上面和下面2个小九宫格
482             zy[1] = z1 + 3;
483         } else {
484             zy[0] = z1 + 3; // 对应0 1 2 检查它下面2个小九宫格
485             zy[1] = z1 + 6;
486         }
487 
488         int z;
489 
490         // 检查同一列已存在的数据
491         for (int i = 0; i < 2; i++) {
492             z = zy[i];
493             for (int x = 0; x < 3; x++) {
494                 if (txtGame[z][x][y1].getText().equals(value)) {
495                     txtGame[z][x][y1].setForeground(Color.red);
496                     txtGame[z1][x1][y1].setForeground(Color.red);
497                     //将冲突的两个文本框的值交替放入map
498                      warnFiledMap.put(txtGame[z][x][y1],txtGame[z1][x1][y1]);
499                      warnFiledMap.put(txtGame[z1][x1][y1],txtGame[z][x][y1]);
500                     return;
501                 }
502             }
503         }
504 
505         // 检查同一行已存在的数据
506         for (int i = 0; i < 2; i++) {
507             z = zx[i];
508             for (int y = 0; y < 3; y++) {
509                 if (txtGame[z][x1][y].getText().equals(value)) {
510                     txtGame[z][x1][y].setForeground(Color.red);
511                     txtGame[z1][x1][y1].setForeground(Color.red);
512                     //将冲突的两个文本框的值交替放入map
513                     warnFiledMap.put(txtGame[z][x1][y],txtGame[z1][x1][y1]);
514                     warnFiledMap.put(txtGame[z1][x1][y1],txtGame[z][x1][y]);
515                     return;
516                 }
517             }
518         }
519 
520         // 检查同一个小九宫格里面的不同的值
521         for (int x = 0; x < 3; x++) {
522             for (int y = 0; y < 3; y++) {
523                 if (!(x == x1 && y == y1)
524                         && txtGame[z1][x][y].getText().equals(value)) {
525 
526                     txtGame[z1][x][y].setForeground(Color.red);
527                     txtGame[z1][x1][y1].setForeground(Color.red);
528                     //将冲突的两个文本框的值交替放入map
529                     warnFiledMap.put(txtGame[z1][x][y],txtGame[z1][x1][y1]);
530                     warnFiledMap.put(txtGame[z1][x1][y1],txtGame[z1][x][y]);
531                     return;
532                 }
533             }
534         }
535 
536     }
537 
538     // 文本属性的变化
539     public void changedUpdate(DocumentEvent documentEvent) {
540     }
541     //插入了新数据
542     public void insertUpdate(DocumentEvent documentEvent) {
543         int[] location = new int[3];
544         int x,y,z;
545         String value;
546         doc = (Document) documentEvent.getDocument();
547         // 控制文本框显示的数字始终1个并且是刚键入的数字,没有冲突
548         this.validateInput(NO);
549         //如果是数字继续下面的操作
550         if(is_num == YES){
551             //当存在冲突的时候接收不能冲突field以外的输入
552             if (warnFiledMap.size() != 0) {
553                 // 根据触发的docment找到填充这个docment的field坐标
554                 this.findFeildLocationByDoc(location);
555                 z = location[0];
556                 x = location[1];
557                 y = location[2];
558                 //如果修改的是冲突域的值
559                 if(warnFiledMap.get(txtGame[z][x][y])!=null){
560                     value = txtGame[z][x][y].getText();
561                     value = value.substring(value.length()-1, value.length());
562                     if(!value.equals(warnFiledMap.get(txtGame[z][x][y]).getText())){
563                         txtGame[z][x][y].setForeground(Color.black);
564                         warnFiledMap.get(txtGame[z][x][y]).setForeground(Color.black);
565                         warnFiledMap.clear();//清空冲突域
566                     }            
567                     // 根据坐标去检查填入数字是否正确
568                     this.checkValue(location[0], location[1], location[2]);
569                 }
570                 //禁止其它文本域输入
571                 else{
572                     // 有冲突存在,无法输入
573                     this.validateInput(YES);
574                 }
575             }
576             else{
577                 this.findFeildLocationByDoc(location);
578                 // 根据坐标去检查填入数字是否正确
579                 this.checkValue(location[0], location[1], location[2]);
580             }
581         }
582         else{
583             is_num = YES;//将数字开关重置,等待下次重新输入
584         }
585     }
586 
587     /**
588      * 控制文本框只能输入数字,并且是1个    并且显示当前刚输入的数字
589      */
590     void validateInput(int conflict) {
591         String value;
592         // 下面都是开启线程来重置输入的值 否则insertUpdate的写锁会导致无法控制输入
593 
594         //如果不是数字就禁止输入    
595         try {
596             value = doc.getText(0, doc.getLength());
597             value = value.substring(value.length()-1, value.length());
598             if(!Pattern.matches("\\d*", value)){
599                 new Thread(new Thread() {
600                     public void run() {
601                         try {
602                             doc.remove(doc.getLength()-1, 1);// 这里会触发一个removeUpdate事件 将刚输入的非法字符清空
603                         } catch (Exception exp) {
604                             System.out.println("Error: " + exp.toString());
605                         }
606                     }
607                 }).start();
608                 is_num = NO;//输入的不是数字
609                 is_remove_by_insert = YES;//remove由insert导致
610                 return ;//不是数字就直接返回
611             }
612         } catch (BadLocationException e) {
613             e.printStackTrace();
614         }
615         
616         if(conflict==YES && doc.getLength() > 0){
617             try {
618                 new Thread(new Thread() {
619                     public void run() {
620                         try {
621                             doc.remove(0, doc.getLength());// 这里会触发一个removeUpdate事件,输入全部清空
622                         } catch (Exception exp) {
623                             System.out.println("Error: " + exp.toString());
624                         }
625                     }
626                 }).start();
627                 is_remove_by_insert = YES;//remove由insert导致
628             } catch (Exception ex) {
629                 System.out.println("Error: " + ex.toString());
630             }
631         }
632         
633         if (doc.getLength() > 1 && conflict==NO) {
634             try {
635                 new Thread(new Thread() {
636                     public void run() {
637                         try {
638                             doc.remove(0, doc.getLength() - 1);// 这里会触发一个removeUpdate事件
639                         } catch (Exception exp) {
640                             System.out.println("Error: " + exp.toString());
641                         }
642                     }
643                 }).start();
644                 is_remove_by_insert = YES;//remove由insert导致
645             } catch (Exception ex) {
646                 System.out.println("Error: " + ex.toString());
647             }
648         }
649         
650         int z;
651         //检验所有是否都填完并且无冲突
652         if(conflict==NO){
653             for(z=0;z<9;z++){
654                 for(int x=0;x<3;x++){
655                     for(int y=0;y<3;y++){
656                         if(txtGame[z][x][y].getText().equals("")){
657                             return;
658                         }
659                     }
660                 }
661             }
662             //如果所有的都填完就代表通关
663             if(z==9){
664                 System.out.println("恭喜通关!");
665             }
666         }
667     }
668     
669     /**
670      * 根据doc找到doc所在的field
671      * @param location
672      */
673     void findFeildLocationByDoc(int[] location) {
674         for (int z = 0; z < 9; z++) {
675             for (int x = 0; x < 3; x++) {
676                 for (int y = 0; y < 3; y++) {
677                     if (txtGame[z][x][y].getDocument() == doc) {
678                         location[0] = z;
679                         location[1] = x;
680                         location[2] = y;
681                     }
682                 }
683             }
684         }
685     }
686     /**
687      * 移除数字的时候更新
688      */
689     public void removeUpdate(DocumentEvent documentEvent) {
690         doc = (Document) documentEvent.getDocument();
691         int[] location = new int[3];
692         int x,y,z;
693         
694         if(is_remove_by_insert == NO){
695             this.findFeildLocationByDoc(location);
696             z = location[0];
697             x = location[1];
698             y = location[2];
699             if(warnFiledMap.get(txtGame[z][x][y])!=null){
700                 txtGame[z][x][y].setForeground(Color.black);
701                 warnFiledMap.get(txtGame[z][x][y]).setForeground(Color.black);
702             }
703         }        
704     }
705 
706     public static void main(String[] args) {
707         new SudokuGame();
708     }
709 }

 

 

posted @ 2012-07-06 16:57  cocohxq  阅读(2082)  评论(2编辑  收藏  举报