/// <summary> /// 碁盤の指定の交点 i,j にある石を起点に、つながっている同じ色の(1つ、または連の)石(color piece)の総リバーティを数えます。 /// /// Gnugo1.2 では、countlib関数です。 /// </summary> /// <param name="out_count">Gnugo1.2 では、グローバル変数 lib でした。</param> /// <param name="startLocation_inPiece">Gnugo1.2では、 行番号 m = 0〜18、列番号 n = 0〜18。</param> /// <param name="color">黒 or 白</param> public static void Count ( out int out_count, GobanPoint startLocation_inPiece, StoneColor color, Taikyoku taikyoku ) { out_count = 0;// Gnugo1.2 では、countlib関数の呼び出し元で グローバル変数を lib = 0 していました。 // 全てのピースを数えなおせるように、リセットします。 taikyoku.CountedBoard.FillAll_WeCan(taikyoku.GobanBounds.BoardSize); // カレント・ピースのリバティーを数えます。 Util_CountLiberty.Count_Recursive(ref out_count, startLocation_inPiece, color, taikyoku); }
/// <summary> /// 碁盤の指定の交点 i,j にある石を起点に、つながっている同じ色の石の(1つ、または連の)総リバーティを数えます。 /// 再帰的に呼び出されます。 /// Countlib関数から呼び出してください。 /// /// Gnugo1.2 では、count関数です。 /// </summary> /// <param name="count">Gnugo1.2 では、グローバル変数 lib でした。</param> /// <param name="location">Gnugo1.2では、行番号 i = 0〜18、列番号 j = 0〜18。</param> /// <param name="color">黒 or 白</param> /// <param name="taikyoku"></param> private static void Count_Recursive( ref int count, GobanPoint location, StoneColor color, Taikyoku taikyoku ) { //---------------------------------------- // 実装の解説 //---------------------------------------- // 石の周り4方向について、 // 数えていない空き交点であれば リバティーを 1加算します。 // 数えていなくて、指定した色(主に同じ色)の石であれば、その石から同メソッドを再帰呼び出しします。 // // 指定した位置は、調査済みとしてマークします。 taikyoku.CountedBoard.Done_Current(location); // 北隣の石を調べます。 if (!location.IsNorthEnd())//北端でなければ { if ( taikyoku.Goban.NorthOf(location) == StoneColor.Empty && taikyoku.CountedBoard.CanDo_North(location) ) { // 北隣が空いていて まだ数えていないなら、 // リバティーを1つ数え上げます。次からは重複して数えません。 ++count; taikyoku.CountedBoard.Done_North(location); } else if ( taikyoku.Goban.NorthOf(location) == color && taikyoku.CountedBoard.CanDo_North(location) ) { // 北隣に 指定色の石が置いてあり、まだ数えていないなら、 // その石からさらにカウントを続けます。 Util_CountLiberty.Count_Recursive(ref count, location.ToNorth(), color, taikyoku); } // 指定した色でない石が置いてあれば何もしない。 } // 南隣を調べます。 if (!location.IsSouthEnd(taikyoku.GobanBounds))//南端でなければ { // もう、だいたい分かるだろう☆(^▽^) if ( taikyoku.Goban.SouthOf(location) == StoneColor.Empty && taikyoku.CountedBoard.CanDo_South(location) ) { ++count; taikyoku.CountedBoard.Done_South(location); } else if ( taikyoku.Goban.SouthOf(location) == color && taikyoku.CountedBoard.CanDo_South(location) ) { Util_CountLiberty.Count_Recursive(ref count, location.ToSouth(), color, taikyoku); } } // 西隣を調べます。 if (!location.IsWestEnd())//西端でなければ { if ( taikyoku.Goban.WestOf(location) == StoneColor.Empty && taikyoku.CountedBoard.CanDo_West(location) ) { ++count; taikyoku.CountedBoard.Done_West(location); } else if ( taikyoku.Goban.WestOf(location) == color && taikyoku.CountedBoard.CanDo_West(location) ) { Util_CountLiberty.Count_Recursive(ref count, location.ToWest(), color, taikyoku); } } // 東隣を調べます。 if (!location.IsEastEnd(taikyoku.GobanBounds))//東端でなければ { if ( (taikyoku.Goban.EastOf(location) == StoneColor.Empty) && taikyoku.CountedBoard.CanDo_East(location) ) { ++count; taikyoku.CountedBoard.Done_East(location); } else if ( taikyoku.Goban.EastOf(location) == color && taikyoku.CountedBoard.CanDo_East(location) ) { Util_CountLiberty.Count_Recursive(ref count, location.ToEast(), color, taikyoku); } } }