計算機圍棋/處理落子
外觀
< 計算機圍棋
現在我們已經能夠檢測合法落子,下一步就是實際處理合法落子,透過將新棋子新增到棋盤上,移除任何被吃掉的棋子,並更新禁手點。我們已經能夠檢測到何時發生吃子
} else if (getColor(neighbor) == c.opposite()) {
// if any neighbor is an enemy
// and that enemy is in atari
if (inAtari(neighbor)) {
suicide = false;
}
}
現在我們只需要更新這段程式碼以移除被吃掉的棋子。到目前為止,應該很明顯,表示鏈的方式將非常有用。讓我們修改之前getLiberties()程式碼,以返回一個鏈而不是一組氣
private Set<Point> getChainPoints(Board b, Point p) {
Set<Point> stones = new HashSet<Point>();
stones.add(p);
Color myColor = b.getColor(p);
Color floodfillColor = myColor.opposite();
b.setColor(p, floodfillColor);
List<Point> neighbors = b.getNeighbors(p);
for (Point neighbor : neighbors) {
if (b.getColor(neighbor) == myColor) {
if (!stones.contains(neighbor)) {
stones.addAll(getChainPoints(b, neighbor));
}
}
}
return stones;
}
給定構成特定鏈的一組棋子,我們也可以很容易地獲得與該鏈相鄰的空點的集合,並構造一個包含這兩個集合的物件。
private Chain getChain(Point p) {
Set<Point> stones = getChainPoints(clone(), p);
Set<Point> liberties = new HashSet<Point>();
for (Point stone : stones) {
for (Point point : getNeighbors(stone)) {
if (getColor(point) == EMPTY) {
liberties.add(point);
}
}
}
return new Chain(stones, liberties);
}
修改後的從棋盤上移除被吃掉棋子的程式碼現在變得非常簡單
} else if (getColor(neighbor) == c.opposite()) {
// if any neighbor is an enemy
// and that enemy is in atari
Chain enemy = getChain(neighbor);
if (enemy.inAtari()) {
suicide = false;
// remove the enemy stones from the board
for (Point point : enemy) {
setColor(point, EMPTY);
capturedStones.add(point);
}
}
}
透過將被吃掉的棋子儲存在一個集合中,我們現在可以輕鬆地更新禁手點。
// If this move captured exactly one stone, that stone is the new ko point
if (capturedStones.size() == 1) {
koPoint = capturedStones.iterator().next();
} else {
koPoint = null;
}
如果您想要本章中使用的所有原始碼的副本,這些程式碼已準備好編譯和執行,您可以從這裡下載示例程式碼副本。