目指せ!第14回UEC杯コンピューター囲碁大会<本編> Step [O22o6o0] 死に石の連の打ち上げ
連載の目次
Step [O22o6o0] 死に石の連の打ち上げ - Captured
石Aを盤上に置いて指を離したばかりの盤面とする。
石Aに隣接する相手の石の連のうち、呼吸点が0のものは打ち上げる。
このとき、 OpponentEye
のルールと相反することがある
Step [O22o6o1o0] ファイル編集 - play.go
👇 以下の既存ファイルを編集してほしい
📂 kifuwarabe-uec14
├── 📂 data
│ └── 📄 board1.txt
├── 📂 kernel
│ ├── 📂 play_rule
│ ├── 📄 board_area.go
│ ├── 📄 board_coord.go
│ ├── 📄 o12o__11o1o0_board.go
│ ├── 📄 check_board.go
│ ├── 📄 color.go
│ ├── 📄 go.mod
│ ├── 📄 go.sum
│ ├── 📄 kernel_facade.go
│ ├── 📄 kernel.go
│ ├── 📄 liberty.go
│ ├── 📄 logger.go
│ ├── 📄 masonry.go
👉 │ ├── 📄 play.go
│ ├── 📄 o12o__10o1o0_point.go
│ ├── 📄 ren.go
│ └── 📄 stone.go
├── 📄 .gitignore
├── 📄 engine_config.go
├── 📄 engine.toml
├── 📄 go.mod
├── 📄 go.work
└── 📄 main.go
👇 がんばって挿入してほしい
// func (k *Kernel) Play(stoneA Stone, pointB Point, logg *Logger,
// [O22o6o1o0] Captured ルール
var isExists4rensToRemove = false
var o4rensToRemove [4]*Ren
var isChecked4rensToRemove = false
// ...略...
// [O22o3o1o0]
// var renC, isFound = k.GetLiberty(pointB)
// if isFound && renC.GetArea() == 1 { // 石Aを置いた交点を含む連Cについて、連Cの面積が1である(眼)
// if stoneA.GetColor() == renC.adjacentColor.GetOpponent() {
// * 以下を追加
// [O22o6o1o0] 打ちあげる死に石の連を取得
k.Board.SetStoneAt(pointB, stoneA) // いったん、石を置く
isExists4rensToRemove, o4rensToRemove = k.GetRenToCapture(pointB)
isChecked4rensToRemove = true
k.Board.SetStoneAt(pointB, Stone_Space) // 石を取り除く
if !isExists4rensToRemove {
// `Captured` ルールと被らなければ
return onOpponentEye()
}
// * 以下を削除
// onOpponentEye()
// } else if k.CanNotPutOnMyEye && stoneA.GetColor() == renC.adjacentColor {
// ...略...
// }
// }
// ...略...
// 石を置く
// k.Board.SetStoneAt(pointB, stoneA)
// * 以下を追加
// [O22o6o1o0] 打ちあげる死に石の連を取得
if !isChecked4rensToRemove {
isExists4rensToRemove, o4rensToRemove = k.GetRenToCapture(pointB)
}
// [O22o6o1o0] 死に石を打ちあげる
if isExists4rensToRemove {
for dir := 0; dir < 4; dir++ {
var ren = o4rensToRemove[dir]
if ren != nil {
k.RemoveRen(ren)
}
}
}
// return true
// }
// GetRenToCapture - 現在、着手後の盤面とする。打ち上げられる石の連を返却
//
// Returns
// -------
// isExists : bool
// renToRemove : [4]*Ren
// 隣接する東、北、西、南にある石を含む連
func (k *Kernel) GetRenToCapture(placePlay Point) (bool, [4]*Ren) {
// [O22o6o1o0]
var isExists bool
var rensToRemove [4]*Ren
var renIds = [4]Point{math.MaxInt, math.MaxInt, math.MaxInt, math.MaxInt}
var setAdjacentPoint = func(dir Cell_4Directions, adjacentP Point) {
var adjacentR, isFound = k.GetLiberty(adjacentP)
if isFound {
// 同じ連を数え上げるのを防止する
var renId = adjacentR.GetMinimumLocation()
for i := Cell_4Directions(0); i < dir; i++ {
if renIds[i] == renId { // Idが既存
return
}
}
// 取れる石を見つけた
if adjacentR.GetLibertyArea() < 1 {
isExists = true
rensToRemove[dir] = adjacentR
}
}
}
// 隣接する4方向
k.Board.ForeachNeumannNeighborhood(placePlay, setAdjacentPoint)
return isExists, rensToRemove
}
Step [O22o6o2o0] 動作確認
👇 以下のコマンドをコピーして、ターミナルに貼り付けてほしい
Input:
go run .
これで、思考エンジン内の入力待機ループに入った
👇 以下のコマンドをコピーして、ターミナルに貼り付けてほしい
Input:
board_set file data/board2.txt
play black D4
Output > Console:
[2022-09-17 14:35:58] # play black D4
[2022-09-17 14:35:58] =