144 lines
3.9 KiB
C
144 lines
3.9 KiB
C
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
||
|
* 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 <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#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:
|
||
|
*/
|