#### 算法 – 程序员拼图：在整个游戏中编码棋盘状态

EDIT2：只是为了更多的澄清…记住，编码器/解码器是规则感知。真正需要存储的唯一的事情是玩家的选择 – 任何其他可以假设为编码器/解码器知道。

> e4 e5
> Nf3 Nc6
> …

>白移动国王的棋子从e2到e4(它是唯一可以得到e4因此“e4”);
>黑色将国王的棋子从e7移动到e5;
>白色将骑士(N)移动到f3;
>黑色将骑士移动到c6。
> …

> e4 e5
> Nf3Nc6
> Bb5 a6
> Ba4 Bc5

En Passant

> e4 e5
> Nf3 Nc6
> Bb5 a6
> Ba4 Bc5
> O-O b5
> Bb3 b4
> c4

b4上的黑色棋子现在可以选择将他在pa4上的棋子移动到c4上的白棋子。这只发生在第一次机会意味着如果黑色传递的选项，现在他不能采取下一步。所以我们需要存储这个。

> h8 = Q

2256等于大约1.16e77。 1364等于大约1.96e71，这需要237位的存储空间。节省仅仅7.5％的代价是大大增加操纵成本。

Huffman编码

``````private static class Node {
private final Node left;
private final Node right;
private final String label;
private final int weight;

private Node(String label, int weight) {
this.left = null;
this.right = null;
this.label = label;
this.weight = weight;
}

public Node(Node left, Node right) {
this.left = left;
this.right = right;
label = "";
weight = left.weight + right.weight;
}

public boolean isLeaf() { return left == null && right == null; }

public Node getLeft() { return left; }

public Node getRight() { return right; }

public String getLabel() { return label; }

public int getWeight() { return weight; }
}
``````

``````private final static List<string> COLOURS;
private final static Map<string, integer> WEIGHTS;

static {
List<string> list = new ArrayList<string>();
COLOURS = Collections.unmodifiableList(list);
Map<string, integer> map = new HashMap<string, integer>();
for (String colour : COLOURS) {
map.put(colour + " " + "King", 1);
map.put(colour + " " + "Queen";, 1);
map.put(colour + " " + "Rook", 2);
map.put(colour + " " + "Knight", 2);
map.put(colour + " " + "Bishop";, 2);
map.put(colour + " " + "Pawn", 8);
}
map.put("Empty", 32);
WEIGHTS = Collections.unmodifiableMap(map);
}
``````

``````private static class WeightComparator implements Comparator<node> {
@Override
public int compare(Node o1, Node o2) {
if (o1.getWeight() == o2.getWeight()) {
return 0;
} else {
return o1.getWeight() < o2.getWeight() ? -1 : 1;
}
}
}

private static class PathComparator implements Comparator<string> {
@Override
public int compare(String o1, String o2) {
if (o1 == null) {
return o2 == null ? 0 : -1;
} else if (o2 == null) {
return 1;
} else {
int length1 = o1.length();
int length2 = o2.length();
if (length1 == length2) {
return o1.compareTo(o2);
} else {
return length1 < length2 ? -1 : 1;
}
}
}
}

public static void main(String args[]) {
PriorityQueue<node> queue = new PriorityQueue<node>(WEIGHTS.size(),
new WeightComparator());
for (Map.Entry<string, integer> entry : WEIGHTS.entrySet()) {
}
while (queue.size() > 1) {
Node first = queue.poll();
Node second = queue.poll();
}
Map<string, node> nodes = new TreeMap<string, node>(new PathComparator());
for (Map.Entry<string, node> entry : nodes.entrySet()) {
System.out.printf("%s %s%n", entry.getKey(), entry.getValue().getLabel());
}
}

public static void addLeaves(Map<string, node> nodes, Node node, String prefix) {
if (node != null) {
addLeaves(nodes, node.getLeft(), prefix + "0");
addLeaves(nodes, node.getRight(), prefix + "1");
if (node.isLeaf()) {
nodes.put(prefix, node);
}
}
}
``````

``````         White    Black
Empty          0
Pawn       110      100
Rook     11111    11110
Knight   10110    10101
Bishop   10100    11100
Queen   111010   111011
King    101110   101111
``````

>一个国王：6位的位置;
>有pawns：1(yes)，0(no);
>如果是，则典当数：3位(0-7 1 = 1-8);
>如果是，每个pawn的位置被编码：45位(见下文);
>非兵的数量：4位(0-15);
>对于每件：类型(2位为皇后，车，骑士，bishop)和位置(6位)

> Bb5！ Nc4？

White的举动由两个惊叹号标记为辉煌，而Black的被视为错误。见Chess punctuation

http://stackoverflow.com/questions/1831386/programmer-puzzle-encoding-a-chess-board-state-throughout-a-game