-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoardScorer.java
63 lines (53 loc) · 1.88 KB
/
BoardScorer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package algs.blog.graph.freeCell;
import algs.model.searchtree.INode;
import algs.model.searchtree.IScore;
/**
* Evaluation function for FreeCell boards used by Staged Deepening
* that doesn't take into account distance g(n) from initial state.
*
* @author George Heineman
*/
public class BoardScorer implements IScore {
/**
* @see algs.model.searchtree.IScore#score(INode)
*/
public void score(INode state) {
state.score(eval(state));
}
/**
*
* @see algs.model.searchtree.IScore#score(INode)
* @param state
*/
public int eval(INode state) {
FreeCellNode node = (FreeCellNode) state;
// what are we looking for. For now, only look for ACES.
int neededCards[] = new int[4];
neededCards[0] = node.foundationEncoding[0]+1;
neededCards[1] = node.foundationEncoding[1]+1;
neededCards[2] = node.foundationEncoding[2]+1;
neededCards[3] = node.foundationEncoding[3]+1;
// simple computation: How buried are the aces? Estimate that is
// the number of moves we need
int numBuried = 0;
for (int c = 0; c < 8; c++) {
int nc = node.cols[c].num;
for (int i = 0; i < nc; i++) {
int card = node.cols[c].cards[i];
int suit = ((card-1)%4); // subtract 1 since '0' is invalid card.
int rank = 1 + ((card-1)>>2); // rank extracted this way.
for (int s = 0; s < 4; s++) {
if ((s == suit) && (neededCards[s] == rank)) {
// found it. Now count how many
numBuried += nc-i-1;
}
}
}
}
// all of our vacancies can be deducted as bonus.
int numVacancies = node.numberVacant();
if (numVacancies == 0) { numBuried *= 2; } // just got harder!
// add moves for each of the piles still needing cards.
return numBuried + (26 - neededCards[0] - neededCards[1] - neededCards[2] - neededCards[3]);
}
}