/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see * * http://www.gnu.org/software/gnugo/ for more information. * * * * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008 and 2009 by the Free Software Foundation. * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation - version 3 or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License in file COPYING for more details. * * * * You should have received a copy of the GNU General Public * * License along with this program; if not, write to the Free * * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02111, USA. * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "gnugo.h" #include #include #include #include "liberty.h" static void movelist_sort_points(int max_points, int points[], int codes[]); static void swap_points_and_codes(int points[], int codes[], int m, int n); /* Return the code for the move if it is known. */ int movelist_move_known(int move, int max_points, int points[], int codes[]) { int k; for (k = 0; k < max_points; k++) { if (codes[k] == 0) return 0; if (points[k] == move) return codes[k]; } return 0; } /* * This function does the real work for change_attack(), * change_defense(), change_attack_threat(), and * change_defense_threat(). */ void movelist_change_point(int move, int code, int max_points, int points[], int codes[]) { int k; /* First see if we already know about this point. */ for (k = 0; k < max_points; k++) if (points[k] == move) break; /* Yes, we do. */ if (k < max_points) { if (codes[k] <= code) return; /* Old news. */ codes[k] = code; movelist_sort_points(max_points, points, codes); return; } /* This tactical point is new to us. */ if (code > codes[max_points - 1]) { points[max_points - 1] = move; codes[max_points - 1] = code; movelist_sort_points(max_points, points, codes); } } /* Sort the tactical points so we have it sorted in falling order on * the code values. * * We use shaker sort because we prefer a stable sort and in all use * cases we can expect it to suffice with one turn through the outer * loop. */ static void movelist_sort_points(int max_points, int points[], int codes[]) { int start = 0; int end = max_points - 1; int new_start; int new_end; int k; while (start < end) { new_start = end; for (k = end; k > start; k--) if (codes[k] > codes[k-1]) { swap_points_and_codes(points, codes, k, k-1); new_start = k; } start = new_start; new_end = start; for (k = start; k < end - 1; k++) if (codes[k] < codes[k+1]) { swap_points_and_codes(points, codes, k, k+1); new_end = k; } end = new_end; } } static void swap_points_and_codes(int points[], int codes[], int m, int n) { int tmp = points[m]; points[m] = points[n]; points[n] = tmp; tmp = codes[m]; codes[m] = codes[n]; codes[n] = tmp; } /* * Local Variables: * tab-width: 8 * c-basic-offset: 2 * End: */