static inline analyse_result apply(Turn const& turn, Piece const& piece) { typedef typename Turn::robust_point_type point_type; analyse_result code = check_helper_segments(turn, piece); if (code != analyse_continue) { return code; } geometry::equal_to<point_type> comparator; if (piece.offsetted_count > 8) { // If the offset contains some points and is monotonic, we try // to avoid walking all points linearly. // We try it only once. if (piece.is_monotonic_increasing[0]) { code = check_monotonic(turn, piece, geometry::less<point_type, 0>()); if (code != analyse_continue) return code; } else if (piece.is_monotonic_increasing[1]) { code = check_monotonic(turn, piece, geometry::less<point_type, 1>()); if (code != analyse_continue) return code; } else if (piece.is_monotonic_decreasing[0]) { code = check_monotonic(turn, piece, geometry::greater<point_type, 0>()); if (code != analyse_continue) return code; } else if (piece.is_monotonic_decreasing[1]) { code = check_monotonic(turn, piece, geometry::greater<point_type, 1>()); if (code != analyse_continue) return code; } } // It is small or not monotonic, walk linearly through offset // TODO: this will be combined with winding strategy for (int i = 1; i < piece.offsetted_count; i++) { point_type const& previous = piece.robust_ring[i - 1]; point_type const& current = piece.robust_ring[i]; // The robust ring can contain duplicates // (on which any side or side-value would return 0) if (! comparator(previous, current)) { code = check_segment(previous, current, turn, false); if (code != analyse_continue) { return code; } } } return analyse_unknown; }
int main (int argc, char **argv) { tests_start (); check_onebit (); check_monotonic (argc, argv); check_random (argc, argv); tests_end (); exit (0); }