Updated README: Equal sign not required with `--mode` flag.
[sgk-go] / engine / movelist.c
CommitLineData
7eeb782e
AT
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
3 * http://www.gnu.org/software/gnugo/ for more information. *
4 * *
5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
6 * 2008 and 2009 by the Free Software Foundation. *
7 * *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation - version 3 or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License in file COPYING for more details. *
17 * *
18 * You should have received a copy of the GNU General Public *
19 * License along with this program; if not, write to the Free *
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
21 * Boston, MA 02111, USA. *
22\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23
24#include "gnugo.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include "liberty.h"
31
32
33static void movelist_sort_points(int max_points, int points[], int codes[]);
34static void swap_points_and_codes(int points[], int codes[], int m, int n);
35
36
37/* Return the code for the move if it is known.
38 */
39int
40movelist_move_known(int move, int max_points, int points[], int codes[])
41{
42 int k;
43
44 for (k = 0; k < max_points; k++) {
45 if (codes[k] == 0)
46 return 0;
47 if (points[k] == move)
48 return codes[k];
49 }
50 return 0;
51}
52
53
54/*
55 * This function does the real work for change_attack(),
56 * change_defense(), change_attack_threat(), and
57 * change_defense_threat().
58 */
59
60void
61movelist_change_point(int move, int code, int max_points,
62 int points[], int codes[])
63{
64 int k;
65
66 /* First see if we already know about this point. */
67 for (k = 0; k < max_points; k++)
68 if (points[k] == move)
69 break;
70
71 /* Yes, we do. */
72 if (k < max_points) {
73 if (codes[k] <= code)
74 return; /* Old news. */
75
76 codes[k] = code;
77 movelist_sort_points(max_points, points, codes);
78 return;
79 }
80
81 /* This tactical point is new to us. */
82 if (code > codes[max_points - 1]) {
83 points[max_points - 1] = move;
84 codes[max_points - 1] = code;
85 movelist_sort_points(max_points, points, codes);
86 }
87}
88
89
90/* Sort the tactical points so we have it sorted in falling order on
91 * the code values.
92 *
93 * We use shaker sort because we prefer a stable sort and in all use
94 * cases we can expect it to suffice with one turn through the outer
95 * loop.
96 */
97
98static void
99movelist_sort_points(int max_points, int points[], int codes[])
100{
101 int start = 0;
102 int end = max_points - 1;
103 int new_start;
104 int new_end;
105 int k;
106
107 while (start < end) {
108 new_start = end;
109 for (k = end; k > start; k--)
110 if (codes[k] > codes[k-1]) {
111 swap_points_and_codes(points, codes, k, k-1);
112 new_start = k;
113 }
114 start = new_start;
115 new_end = start;
116 for (k = start; k < end - 1; k++)
117 if (codes[k] < codes[k+1]) {
118 swap_points_and_codes(points, codes, k, k+1);
119 new_end = k;
120 }
121 end = new_end;
122 }
123}
124
125static void
126swap_points_and_codes(int points[], int codes[], int m, int n)
127{
128 int tmp = points[m];
129 points[m] = points[n];
130 points[n] = tmp;
131 tmp = codes[m];
132 codes[m] = codes[n];
133 codes[n] = tmp;
134}
135
136
137
138/*
139 * Local Variables:
140 * tab-width: 8
141 * c-basic-offset: 2
142 * End:
143 */