From e5ca98faf619b84421b38a1cc3dc634f4ca0ce66 Mon Sep 17 00:00:00 2001 From: iorch Date: Sun, 10 Apr 2016 15:18:44 -0500 Subject: [PATCH] evaluate a simple ladder #17 --- include/amigo.h | 22 +++++++++- include/boardfeatures.h | 97 +++++++++++++++++++++++++++++++++-------- 2 files changed, 101 insertions(+), 18 deletions(-) diff --git a/include/amigo.h b/include/amigo.h index 0900fb9..77170dc 100644 --- a/include/amigo.h +++ b/include/amigo.h @@ -229,6 +229,14 @@ enum { int count(){ return layer_.count(); } + position first(){ + position p = position::A19; + do { + if (layer_[p.position_]) break; + p.next(); + } while (!p.is_none()); + return(p); + } }; ///// ............ stones .... liberties ////// typedef std::pair < board_layer, board_layer > group; @@ -430,6 +438,18 @@ enum { for (auto& g : white_groups_) update_liberties(g); } + group get_group_at(player pl,const position& p){ + auto contains_stone = [&](group g) { + return ( g.first[p] ); + }; + auto gr = white_groups_; + if (pl == player::black) { + auto gr = black_groups_; + } + auto it = std::find_if(gr.begin(), gr.end(), contains_stone); + return( *it ); + } + void draw_layer( board_layer _layer ){ std::printf("+--+---------------------------------------+\n"); std::printf("| move = %03d turn = %c |\n", moves_, turn_.as_char() ); @@ -455,7 +475,7 @@ enum { void move(const position& p) { move(turn_, p); - turn_.toggle(); + //turn_.toggle(); } void draw() { diff --git a/include/boardfeatures.h b/include/boardfeatures.h index fe11aed..390e07e 100644 --- a/include/boardfeatures.h +++ b/include/boardfeatures.h @@ -44,15 +44,16 @@ namespace amigo { //******** W I P ******* board_layer get_capture_ladders(){ /* - - [ * ] look for enemy groups with 2 liberties - - [] loop over those groups - - [] fill one liberty - - [] place the forced move - - [] count liberties - - [] check for following cases: - *) more than 2 liberties: escape, ladder fails - *) 2 liberties, fill one liberty, .... - *) 1 liberty, ladder succed + - [X] look for enemy groups with 2 liberties + - [X] loop over those groups and liberties + - [X] fill one liberty + - [] can enemy kill own stones? + - [X] place the forced move + - [X] count liberties + - [X] check for following cases: + * more than 2 liberties: escape, ladder fails + * 2 liberties, fill one liberty, .... + * 1 liberty, ladder succed */ board_layer ladder_; @@ -67,13 +68,15 @@ namespace amigo { own_layer_ = board_.white_; opponent_layer_ = board_.black_; empty_layer_ = board_.empty_; + player opponent = player::black; if (board_.turn_ == player::black) { + opponent = player::white; groups_ = board_.white_groups_; own_layer_ = board_.black_; opponent_layer_ = board_.white_; } - color_groups sg_(groups_.size()); // selected groups + color_groups ladders_;//(groups_.size()); // get possible ladders position p = position::A19; auto has_two_liberties = [&](group g) { @@ -82,22 +85,82 @@ namespace amigo { auto is_last_liberty = [&](group g){ return g.second[p] && g.second.count() ==1; }; - std::cout << "test" << std::endl; + //auto is_stone_in_group = [&](position p, group g){ + // return ( g.first[p] ); + //}; + auto is_liberty_group = [](position p, group g){ + return ( g.second[p] ); + }; + auto current_llberties = [](group g){ + std::vector _liberties; + position _p = position::A19; + do{ + if (g.second[_p]) _liberties.push_back(_p); + _p.next(); + } while (!_p.is_none()); + return (_liberties); + }; // look for threatened groups, and threatening positions - auto it = sg_.begin(); + //auto it = ladders_.begin(); + bool group_inc; do { - if (!empty_layer_[p]) { + group_inc = false; + for (auto& g: ladders_){ + group_inc = group_inc || is_liberty_group( p, g ); + } + if ( !empty_layer_[p] || group_inc) { p.next(); continue; } - it = std::copy_if(groups_.begin(),groups_.end(),sg_.begin(),has_two_liberties); + auto it = std::copy_if( groups_.begin(), + groups_.end(), + back_inserter(ladders_), + has_two_liberties ); threats.push_back(p); p.next(); } while (!p.is_none()); - sg_.resize(std::distance(sg_.begin(),it)); - std::cout << sg_.size() << std::endl; + //ladders_.resize( std::distance( ladders_.begin(), it ) ); + ladder_ = ladders_.begin()->first; + std::vector liberties; + std::vector liberties_tmp; + group _g; + for (auto& g: ladders_){ + auto tmp_board = board_; + auto _tmp_board_ = tmp_board; + auto lit = liberties.begin(); + auto lit_tmp = liberties.begin(); + _g = tmp_board.get_group_at(opponent,g.first.first()); + liberties = current_llberties(_g); + int nliberties = liberties.size(); + while (nliberties == 2){ + nliberties = 3; + _g = tmp_board.get_group_at(opponent,g.first.first()); + tmp_board.draw_layer(_g.first); + liberties = current_llberties(_g); + lit = liberties.begin(); + for (;lit != liberties.end(); ++lit){ + _tmp_board_ = tmp_board; + if ((*lit).is_none()) continue; + _g = _tmp_board_.get_group_at(opponent,g.first.first()); + _tmp_board_.move(*lit); + _g = _tmp_board_.get_group_at(opponent,g.first.first()); + liberties_tmp = current_llberties(_g); + lit_tmp = liberties_tmp.begin(); + _tmp_board_.move(*lit_tmp); + _g = _tmp_board_.get_group_at(opponent,g.first.first()); + liberties_tmp = current_llberties(_g); + if ( liberties_tmp.size()<=2){ + tmp_board = _tmp_board_; + liberties_tmp = current_llberties(_g); + liberties = liberties_tmp; + nliberties = liberties.size(); + break; + } + } + } + ladder_ = _g.first; + } - ladder_ = sg_[0].first; return ladder_; }