第二个游戏 —— 连连看

今天又写了一个游戏 ——连连看,这个是个很经典的游戏,

我也想来试试看,如何实现它。

关键部分在于如何判定两个选中单元格是可以相连的。

经过分析,可以看到,连接的方式为一下几种模式

不管上述的哪种模式,都可以总结为如下的公式:


沿着x方向的所有x进行遍历,对于任何一个x来说,y1-y2之间的连接线如果是可以连接的,

而且,x1,y1~x,y1和x2,y2, x, y2之间都是可以连通的,那么这两个点就是可以连接的。


具体算法实现如下:

 1 package org.stephen.connecty.control;
 2 
 3 import org.stephen.connecty.model.Cell;
 4 import org.stephen.connecty.model.Game;
 5 import org.stephen.connecty.model.Grid;
 6 import org.stephen.connecty.model.Position;
 7 import org.stephen.connecty.model.Route;
 8 
 9 public class RouteFinder {
10 
11     public Grid grid = new Grid();
12 
13     public void before() {
14         Game game = Game.getInstance();
15         for (int x = 0; x < Game.COLUMN_COUNT; x++) {
16             for (int y = 0; y < Game.ROW_COUNT; y++) {
17                 grid.cells[y][x] = new Cell();
18                 grid.cells[y][x].type = game.grid.cells[y][x].type;
19                 grid.cells[y][x].selected = game.grid.cells[y][x].selected;
20                 grid.cells[y][x].destroyed = game.grid.cells[y][x].destroyed;
21                 grid.cells[y][x].marked = false;
22             }
23         }
24     }
25 
26     public Route find(Position first, Position second) {
27 
28         Route vertical = findVertical(first, second);
29         if (vertical != null) {
30             return vertical;
31         }
32 
33         Route horizontal = findHorizontal(first, second);
34         if (horizontal != null) {
35             return horizontal;
36         }
37 
38         return null;
39     }
40 
41     private Route findHorizontal(Position first, Position second) {
42         for (int x = 0; x < Game.COLUMN_COUNT; x++) {
43             boolean firstOk = false;
44             boolean secondOk = false;
45             boolean connectorOk = false;
46 
47             firstOk = checkHorizontalEmpty(first.x, x, first.y);
48             secondOk = checkHorizontalEmpty(second.x, x, second.y);
49             connectorOk = checkVerticalEmpty(first.y, second.y, x);
50             if (firstOk && secondOk && connectorOk) {
51                 return new Route(first, new Position(x, first.y), new Position(
52                         x, second.y), second);
53             }
54         }
55         return null;
56     }
57 
58     private Route findVertical(Position first, Position second) {
59         for (int y = 0; y < Game.ROW_COUNT; y++) {
60             boolean firstOk = false;
61             boolean secondOk = false;
62             boolean connectorOk = false;
63 
64             firstOk = checkVerticalEmpty(first.y, y, first.x);
65             secondOk = checkVerticalEmpty(second.y, y, second.x);
66             connectorOk = checkHorizontalEmpty(first.x, second.x, y);
67             if (firstOk && secondOk && connectorOk) {
68                 return new Route(first, new Position(first.x, y), new Position(
69                         second.x, y), second);
70             }
71         }
72         return null;
73     }
74 
75     private boolean checkVerticalEmpty(int y, int y2, int x) {
76         int start = Math.min(y, y2);
77         int end = Math.max(y, y2);
78 
79         for (int i = start; i <= end; i++) {
80             if (!grid.cells[i][x].destroyed && !grid.cells[i][x].selected) {
81                 return false;
82             }
83         }
84         return true;
85     }
86 
87     private boolean checkHorizontalEmpty(int x, int x2, int y) {
88         int start = Math.min(x, x2);
89         int end = Math.max(x, x2);
90 
91         for (int i = start; i <= end; i++) {
92             if (!grid.cells[y][i].destroyed && !grid.cells[y][i].selected) {
93                 return false;
94             }
95         }
96         return true;
97     }
98 
99 }

上述算法的代码实现了描述中的搜索。但是搜索最佳路径时,可以把所有的可行路径都列出,然后寻找最短的那条。

另外,本次实现的代码中包含了,计时、皮肤等功能,

预留了模式(向左移动,向右移动等)、设置(难度,声音等)等的扩展接口,有兴趣的读者,可以自行完成。

但是,该代码的MouseListener.onClick反应不是很灵敏,导致操作上的问题。 —— 这是一个已知的Bug。

同时,由于Java书写的,也看到了性能问题,以后可以考虑改为Android来书写。

 源代码位置:https://files.cnblogs.com/stephen-wang/Connecty.zip

 

 

 

 

 

 

posted @ 2012-11-29 22:02  史蒂芬.王  阅读(255)  评论(0编辑  收藏  举报