ADA* added
[schiebespiel.git] / MinSchritte.java
blob0b0de07d14ef5d0e17689fb2e15b69666dfe730e
1 import java.util.*;
2 import java.lang.*;
3 import java.math.BigInteger;
6 class MinSchritte {
7 class SteinCoords {
8 int x,y;
9 SteinCoords(int x, int y) {
10 this.x = x;
11 this.y = y;
13 public int distanz(SteinCoords sc) {
14 return Math.abs(x - sc.x) + Math.abs(y - sc.y);
18 /* Index 0 -> Leere
19 Index 1 -> Einer
20 Index 2 -> Zweier horizontal
21 Index 3 -> Zweier vertikal
22 Index 4 -> Vierer */
23 ArrayList< ArrayList<SteinCoords> > zielCoords = new ArrayList< ArrayList<SteinCoords> >();
25 ArrayList< ArrayList<SteinCoords> > findCoords(Knoten k) {
27 ArrayList<SteinCoords> einer = new ArrayList<SteinCoords>();
28 ArrayList<SteinCoords> zweier_horiz = new ArrayList<SteinCoords>();
29 ArrayList<SteinCoords> zweier_vertik = new ArrayList<SteinCoords>();
30 ArrayList<SteinCoords> vierer = new ArrayList<SteinCoords>();
31 SteinCoords sc;
33 int[][] feld = k.get_spielfeld();
34 for(int x = 0; x < feld.length; ++x) {
35 for(int y = 0; y < feld[0].length; ++y) {
36 switch(feld[x][y]) {
37 case Knoten.einer:
38 sc = new SteinCoords(x,y);
39 einer.add(sc);
40 break;
41 case Knoten.zweier_links:
42 sc = new SteinCoords(x,y);
43 zweier_horiz.add(sc);
44 break;
45 case Knoten.zweier_oben:
46 sc = new SteinCoords(x,y);
47 zweier_vertik.add(sc);
48 break;
49 case Knoten.vierer_ro:
50 sc = new SteinCoords(x,y);
51 vierer.add(sc);
52 break;
53 default:
54 break;
58 ArrayList<ArrayList<SteinCoords>> coords = new ArrayList<ArrayList<SteinCoords>>();
59 coords.add(einer);
60 coords.add(zweier_horiz);
61 coords.add(zweier_vertik);
62 coords.add(vierer);
64 return coords;
67 MinSchritte(Knoten ziel) {
68 setZielCoords(ziel);
71 void setZielCoords(Knoten ziel) {
72 zielCoords = findCoords(ziel);
75 int computeLuftlinie(Knoten k) {
77 PermutationGenerator x;
78 int[] indices;
79 int luftlinie = 0;
80 ArrayList<ArrayList<SteinCoords>> kCoords = findCoords(k);
81 ArrayList<SteinCoords> scList, zscList;
83 for (int i=0; i<4; ++i) {
84 int minSum = 0;
85 scList = kCoords.get(i);
86 zscList = zielCoords.get(i);
87 x = new PermutationGenerator(scList.size());
88 for (int j=0; j<scList.size(); ++j) {
89 minSum += scList.get(j).distanz(zscList.get(j));
91 while(x.hasMore()) {
92 int tmpSum = 0;
93 indices = x.getNext();
94 for (int j=0; j<scList.size(); ++j) {
95 tmpSum += scList.get(j).distanz(zscList.get(indices[j]));
97 // System.out.println(i + " " + tmpSum);
98 if (minSum > tmpSum) {
99 minSum = tmpSum;
102 if(i==4) {
103 minSum *= 1;
105 luftlinie += minSum;
108 return luftlinie;
113 //--------------------------------------
114 // Systematically generate permutations.
115 //--------------------------------------
117 class PermutationGenerator {
119 private int[] a;
120 private BigInteger numLeft;
121 private BigInteger total;
123 //-----------------------------------------------------------
124 // Constructor. WARNING: Don't make n too large.
125 // Recall that the number of permutations is n!
126 // which can be very large, even when n is as small as 20 --
127 // 20! = 2,432,902,008,176,640,000 and
128 // 21! is too big to fit into a Java long, which is
129 // why we use BigInteger instead.
130 //----------------------------------------------------------
132 public PermutationGenerator (int n) {
133 if (n < 1) {
134 throw new IllegalArgumentException ("Min 1");
136 a = new int[n];
137 total = getFactorial (n);
138 reset ();
141 //------
142 // Reset
143 //------
145 public void reset () {
146 for (int i = 0; i < a.length; i++) {
147 a[i] = i;
149 numLeft = new BigInteger (total.toString ());
152 //------------------------------------------------
153 // Return number of permutations not yet generated
154 //------------------------------------------------
156 public BigInteger getNumLeft () {
157 return numLeft;
160 //------------------------------------
161 // Return total number of permutations
162 //------------------------------------
164 public BigInteger getTotal () {
165 return total;
168 //-----------------------------
169 // Are there more permutations?
170 //-----------------------------
172 public boolean hasMore() {
173 return numLeft.compareTo (BigInteger.ZERO) == 1;
176 //------------------
177 // Compute factorial
178 //------------------
180 private static BigInteger getFactorial (int n) {
181 BigInteger fact = BigInteger.ONE;
182 for (int i = n; i > 1; i--) {
183 fact = fact.multiply (new BigInteger (Integer.toString (i)));
185 return fact;
188 //--------------------------------------------------------
189 // Generate next permutation (algorithm from Rosen p. 284)
190 //--------------------------------------------------------
192 public int[] getNext () {
194 if (numLeft.equals (total)) {
195 numLeft = numLeft.subtract (BigInteger.ONE);
196 return a;
199 int temp;
201 // Find largest index j with a[j] < a[j+1]
203 int j = a.length - 2;
204 while (a[j] > a[j+1]) {
205 j--;
208 // Find index k such that a[k] is smallest integer
209 // greater than a[j] to the right of a[j]
211 int k = a.length - 1;
212 while (a[j] > a[k]) {
213 k--;
216 // Interchange a[j] and a[k]
218 temp = a[k];
219 a[k] = a[j];
220 a[j] = temp;
222 // Put tail end of permutation after jth position in increasing order
224 int r = a.length - 1;
225 int s = j + 1;
227 while (r > s) {
228 temp = a[s];
229 a[s] = a[r];
230 a[r] = temp;
231 r--;
232 s++;
235 numLeft = numLeft.subtract (BigInteger.ONE);
236 return a;