]>
git.zerfleddert.de Git - FreeShisen/blob - src/de/cwde/shisensho/Board.java
146b1d8ae6669d6523dd738489fbe6fd148774b7
1 package de
.cwde
.shisensho
;
3 import java
.util
.ArrayList
;
4 import java
.util
.LinkedList
;
8 private static String charpieces
= " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
10 public int difficulty
=1; // 1=Hard ... N=Easy
11 public boolean gravity
=true;
12 public int [] boardSize
;
13 public char[][] board
;
14 public LinkedList
<Move
> history
;
16 // ----------------------
18 // ----------------------
23 // The board always has a 1-square width free rectangle that has
24 // to be taken into account when specifying the size
25 public void initialize(int sizeI
, int sizeJ
) {
26 boardSize
= new int[2];
29 board
= new char[boardSize
[0]][boardSize
[1]];
30 for (int i
=0;i
<boardSize
[0];i
++)
31 for (int j
=0;j
<boardSize
[1];j
++)
33 history
=new LinkedList
<Move
>();
36 public static String
pieceToString(char piece
) {
37 return charpieces
.substring(piece
,1);
40 public static char StringToPiece(String piece
) {
42 long charpiecesLen
=charpieces
.length();
43 for(upiece
=0;(upiece
<charpiecesLen
&& charpieces
.substring(upiece
,1)!=piece
);upiece
++);
44 if (upiece
<charpiecesLen
) return upiece
;
48 public String
toString() {
50 for (int j
=0;j
<boardSize
[1];j
++) {
54 result
+="\n "+StringRepeat("--",boardSize
[1]);
55 for (int i
=0;i
<boardSize
[0];i
++) {
56 result
+="\n"+(i
%10)+"|";
57 for (int j
=0;j
<boardSize
[1];j
++) {
59 result
+=charpieces
.substring(board
[i
][j
],board
[i
][j
]+1);
63 result
+=" |"+StringRepeat(" ",boardSize
[1])+"|";
65 result
+=" "+StringRepeat("--",boardSize
[1])+"\n";
69 public void buildRandomBoard(int sizeI
, int sizeJ
, int difficulty
, boolean gravity
) {
70 initialize(sizeI
,sizeJ
);
71 this.difficulty
=difficulty
;
74 int numDifferentPieces
=((boardSize
[0]-2)*(boardSize
[1]-2)/((4-difficulty
)*2))+1;
75 for (int n
=0; n
<((4-difficulty
)*2); n
++) {
76 for (int k
=0; k
<numDifferentPieces
; k
++) {
79 j
=(myrand() % (boardSize
[1]-2))+1;
82 // ShisenSho.log("numDifferentPieces="+numDifferentPieces+", n="+n+", k="+(int)k+", i="+i+", j="+j);
83 // ShisenSho.log(toString());
90 ALGORITHM TO COMPUTE CONNECTION PATH BETWEEN PIECES A (IA,JA) AND B (IB,JB)
92 - Delete A and B from the board (consider them as blank spaces)
93 - Calculate the set H of possible horizontal lines in the board (lines through blank spaces)
94 - Calculate the set V of possible vertical lines in the board
95 - Find HA, VA, HB, VB in the sets
96 - If HA=HB, result is a straight horizontal line A-B
97 - If VA=VB, result is a straight vertical line A-B
98 - If HA cuts VB, the result is an L line A-(IA,JB)-B
99 - If VA cuts HB, the result is an L line A-(IB,JA)-B
100 - If exists an V line that cuts HA and HB, the result is a Z line A-(IA,JV)-(IB-JV)-B
101 - If exists an H line that cuts VA and VB, the result is a Z line A-(IV,JA)-(IV,JB)-B
103 The following data types are defined:
106 - Point(int i, int j)
107 - Line(Point a, Point b)
108 - LineSet(Line l1, ..., Line lN)
110 The following operations are defined
112 - LineSet getHorizontalLines(Board board, Point a, Point b) // a and b needed to consider them as blank
113 - LineSet getVerticalLines(Board board, Point a, Point b)
114 - boolean lineIsHorizontal(Line l)
115 - boolean lineIsVertical(Line l)
116 - boolean lineContainsPoint(Line l, Point p)
117 - boolean lineEqualsLine(Line l1, Line l2)
118 - boolean lineCutsLine(Line l1, Line l2)
120 public List
<Point
> getPath(Point a
, Point b
) {
121 List
<Point
> result
=new ArrayList
<Point
>();
123 if (getPiece(a
)!=getPiece(b
)) return result
;
125 List
<Line
> h
=getHorizontalLines(a
,b
);
126 List
<Line
> v
=getVerticalLines(a
,b
);
127 Line ha
=null, va
=null, hb
=null, vb
=null;
130 if (l
.contains(a
)) ha
=l
;
131 if (l
.contains(b
)) hb
=l
;
132 if (ha
!=null && hb
!=null) break;
136 if (l
.contains(a
)) va
=l
;
137 if (l
.contains(b
)) vb
=l
;
138 if (va
!=null && vb
!=null) break;
141 // stdout.printf("va=%s, ha=%s, vb=%s, hb=%s\n",va.toString(),ha.toString(),vb.toString(),hb.toString());
143 if ((ha
==null && va
==null) || (hb
==null && vb
==null))
146 if (ha
.equals(hb
) || va
.equals(vb
)) {
155 // stdout.printf("(ha cuts vb) ab=%s\n",ab.toString());
165 // stdout.printf("(va cuts hb) ab=%s\n",ab.toString());
178 // stdout.printf("(%s cuts ha) al=%s\n",l.toString(),al.toString());
179 // stdout.printf("(%s cuts hb) bl=%s\n",l.toString(),bl.toString());
181 if (al
!=null && bl
!=null) {
194 // stdout.printf("(%s cuts va) al=%s\n",l.toString(),al.toString());
195 // stdout.printf("(%s cuts vb) bl=%s\n",l.toString(),bl.toString());
197 if (al
!=null && bl
!=null) {
209 public char getPiece(Point p
) {
210 return board
[p
.i
][p
.j
];
213 public void setPiece(Point p
, char piece
) {
214 board
[p
.i
][p
.j
]=piece
;
217 public String
getStrPiece(Point p
) {
218 char piece
=board
[p
.i
][p
.j
];
219 return charpieces
.substring(piece
,1);
222 public void setStrPiece(Point p
, String piece
) {
224 long charpiecesLen
=charpieces
.length();
225 for(upiece
=0;(upiece
<charpiecesLen
&& charpieces
.substring(upiece
,1)!=piece
);upiece
++);
226 if (upiece
<charpiecesLen
) board
[p
.i
][p
.j
]=upiece
;
229 public void play(Point a0
, Point b0
) {
230 // It's important to sink the upper piece first
231 Point a
=(a0
.i
<b0
.i
)?a0
:b0
;
232 Point b
=(a0
.i
<b0
.i
)?b0
:a0
;
233 Move m
=new Move(a
,b
,getPiece(a
));
241 public boolean getCanUndo() {
242 return !history
.isEmpty();
246 if (!getCanUndo()) return;
247 Move m
=history
.remove(0);
249 setPiece(m
.b
,m
.piece
);
251 setPiece(m
.a
,m
.piece
);
254 public List
<Line
> getPairs(int maxResults
) {
255 List
<Line
> result
=new ArrayList
<Line
>();
256 List
<Integer
> pieces
=new ArrayList
<Integer
>();
257 List
<List
<Point
>> piecePoints
=new ArrayList
<List
<Point
>>();
258 for (int i
=0;i
<boardSize
[0];i
++)
259 for (int j
=0;j
<boardSize
[1];j
++) {
260 int piece
=(int)board
[i
][j
];
261 if (piece
==0) continue;
262 int key
=pieces
.indexOf(piece
);
263 Point p
=new Point(i
,j
);
265 List
<Point
> points0
=new ArrayList
<Point
>();
268 piecePoints
.add(points0
);
270 key
=pieces
.indexOf(piece
);
271 piecePoints
.get(key
);
273 List
<Point
> points1
=piecePoints
.get(key
);
279 for (List
<Point
> points
: piecePoints
) {
280 int n
=(int)points
.size();
281 for (int i
=0;i
<n
;i
++) {
282 Point a
=points
.get(i
);
283 for (int j
=i
+1;j
<n
;j
++) {
284 Point b
=points
.get(j
);
285 List
<Point
> path
=getPath(a
.copy(),b
.copy());
286 if (path
!=null && path
.size()>0) {
287 result
.add(new Line(a
,b
));
288 if (nresults
++==maxResults
) break;
291 if (nresults
==maxResults
) break;
293 if (nresults
==maxResults
) break;
298 public int getNumPieces() {
300 for (int j
=0;j
<boardSize
[1];j
++) {
301 for (int i
=0;i
<boardSize
[0];i
++) {
302 if (board
[i
][j
]!=0) result
++;
308 // ----------------------
310 // ----------------------
312 /* RAND_MAX assumed to be 32767 */
313 private int myrand() {
314 return (int)Math
.floor(Math
.random()*32768);
317 private String
StringRepeat(String s
, int n
) {
319 for (int i
=0;i
<n
;i
++)
324 private int findFreeRow(int j
) {
325 for (int i
=1;i
<boardSize
[0]-1;i
++) {
326 if (board
[i
][j
]!=0) return (i
-1);
328 return (boardSize
[0]-1-1);
331 private List
<Line
> getHorizontalLines(Point excludeA
, Point excludeB
) {
332 List
<Line
> result
=new ArrayList
<Line
>();
333 for (int i
=0;i
<boardSize
[0];i
++) {
336 for (int j
=0;j
<boardSize
[1];j
++) {
337 empty
=(board
[i
][j
]==0 || (i
==excludeA
.i
&& j
==excludeA
.j
)
338 || (i
==excludeB
.i
&& j
==excludeB
.j
));
339 if (j0
==-1 && empty
) {
341 } else if (j0
!=-1 && !empty
) {
342 result
.add(new Line(new Point(i
,j0
), new Point(i
,j
-1)));
346 if (j0
!=-1) result
.add(new Line(new Point(i
,j0
), new Point(i
,boardSize
[1]-1)));
349 // stdout.printf("\ngetHorizontalLines( %s, %s ): ",excludeA.toString(),excludeB.toString());
350 // for (Line line : result) stdout.printf("%s ",line.toString());
351 // stdout.printf("\n");
356 private List
<Line
> getVerticalLines(Point excludeA
, Point excludeB
) {
357 List
<Line
> result
=new ArrayList
<Line
>();
358 for (int j
=0;j
<boardSize
[1];j
++) {
361 for (int i
=0;i
<boardSize
[0];i
++) {
362 empty
=(board
[i
][j
]==0 || (i
==excludeA
.i
&& j
==excludeA
.j
)
363 || (i
==excludeB
.i
&& j
==excludeB
.j
));
364 if (i0
==-1 && empty
) {
366 } else if (i0
!=-1 && !empty
) {
367 result
.add(new Line(new Point(i0
,j
), new Point(i
-1,j
)));
371 if (i0
!=-1) result
.add(new Line(new Point(i0
,j
), new Point(boardSize
[0]-1,j
)));
374 // stdout.printf("\ngetVerticalLines( %s, %s ): ",excludeA.toString(),excludeB.toString());
375 // for (Line line : result) stdout.printf("%s ",line.toString());
376 // stdout.printf("\n");
381 private void processGravity(Point p
) {
382 if (gravity
) for (int i
=p
.i
;i
>0;i
--) board
[i
][p
.j
]=board
[i
-1][p
.j
];
385 private void undoGravity(Point p
) {
386 if (gravity
) for (int i
=0;i
<p
.i
;i
++) board
[i
][p
.j
]=board
[i
+1][p
.j
];