1 /* list.cpp
2 
3    GNU Chess protocol adapter
4 
5    Copyright (C) 2001-2011 Free Software Foundation, Inc.
6 
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 
22 // list.cpp
23 
24 // includes
25 
26 #include "board.h"
27 #include "list.h"
28 #include "move.h"
29 #include "util.h"
30 
31 namespace adapter {
32 
33 // functions
34 
35 // list_is_ok()
36 
list_is_ok(const list_t * list)37 bool list_is_ok(const list_t * list) {
38 
39    if (list == NULL) return false;
40 
41    if (list->size >= ListSize) return false;
42 
43    return true;
44 }
45 
46 // list_clear()
47 
list_clear(list_t * list)48 void list_clear(list_t * list) {
49 
50    ASSERT(list!=NULL);
51 
52    list->size = 0;
53 }
54 
55 // list_add()
56 
list_add(list_t * list,int move,int value)57 void list_add(list_t * list, int move, int value) {
58 
59    ASSERT(list_is_ok(list));
60    ASSERT(move_is_ok(move));
61    ASSERT(value>=-32767&&value<=+32767);
62 
63    ASSERT(list->size<ListSize-1);
64 
65    list->move[list->size] = move;
66    list->value[list->size] = value;
67    list->size++;
68 }
69 
70 // list_remove()
71 
list_remove(list_t * list,int index)72 void list_remove(list_t * list, int index) {
73 
74    int i;
75 
76    ASSERT(list_is_ok(list));
77    ASSERT(index>=0&&index<list->size);
78 
79    for (i = index; i < list->size-1; i++) {
80       list->move[i] = list->move[i+1];
81       list->value[i] = list->value[i+1];
82    }
83 
84    list->size--;
85 }
86 
87 // list_is_empty()
88 
list_is_empty(const list_t * list)89 bool list_is_empty(const list_t * list) {
90 
91    ASSERT(list_is_ok(list));
92 
93    return list->size == 0;
94 }
95 
96 // list_size()
97 
list_size(const list_t * list)98 int list_size(const list_t * list) {
99 
100    ASSERT(list_is_ok(list));
101 
102    return list->size;
103 }
104 
105 // list_move()
106 
list_move(const list_t * list,int index)107 int list_move(const list_t * list, int index) {
108 
109    ASSERT(list_is_ok(list));
110    ASSERT(index>=0&&index<list->size);
111 
112    return list->move[index];
113 }
114 
115 // list_value()
116 
list_value(const list_t * list,int index)117 int list_value(const list_t * list, int index) {
118 
119    ASSERT(list_is_ok(list));
120    ASSERT(index>=0&&index<list->size);
121 
122    return list->value[index];
123 }
124 
125 // list_copy()
126 
list_copy(list_t * dst,const list_t * src)127 void list_copy(list_t * dst, const list_t * src) {
128 
129    int i;
130 
131    ASSERT(dst!=NULL);
132    ASSERT(list_is_ok(src));
133 
134    dst->size = src->size;
135 
136    for (i = 0; i < src->size; i++) {
137       dst->move[i] = src->move[i];
138       dst->value[i] = src->value[i];
139    }
140 }
141 
142 // list_move_to_front()
143 
list_move_to_front(list_t * list,int index)144 void list_move_to_front(list_t * list, int index) {
145 
146    int i;
147    int move, value;
148 
149    ASSERT(list_is_ok(list));
150    ASSERT(index>=0&&index<list->size);
151 
152    if (index != 0) {
153 
154       move = list->move[index];
155       value = list->value[index];
156 
157       for (i = index; i > 0; i--) {
158          list->move[i] = list->move[i-1];
159          list->value[i] = list->value[i-1];
160       }
161 
162       list->move[0] = move;
163       list->value[0] = value;
164    }
165 }
166 
167 // list_note()
168 
list_note(list_t * list)169 void list_note(list_t * list) {
170 
171    int i, move;
172 
173    ASSERT(list_is_ok(list));
174 
175    for (i = 0; i < list->size; i++) {
176       move = list->move[i];
177       ASSERT(move_is_ok(move));
178       list->value[i] = -move_order(move);
179    }
180 }
181 
182 // list_sort()
183 
list_sort(list_t * list)184 void list_sort(list_t * list) {
185 
186    int i, j;
187    int best_index, best_move, best_value;
188 
189    ASSERT(list_is_ok(list));
190 
191    for (i = 0; i < list->size-1; i++) {
192 
193       best_index = i;
194       best_value = list->value[i];
195 
196       for (j = i+1; j < list->size; j++) {
197          if (list->value[j] > best_value) {
198             best_index = j;
199             best_value = list->value[j];
200          }
201       }
202 
203       if (best_index != i) {
204 
205          best_move = list->move[best_index];
206          ASSERT(best_value==list->value[best_index]);
207 
208          for (j = best_index; j > i; j--) {
209             list->move[j] = list->move[j-1];
210             list->value[j] = list->value[j-1];
211          }
212 
213          list->move[i] = best_move;
214          list->value[i] = best_value;
215       }
216    }
217 
218    if (DEBUG) {
219       for (i = 0; i < list->size-1; i++) {
220          ASSERT(list->value[i]>=list->value[i+1]);
221       }
222    }
223 }
224 
225 // list_contain()
226 
list_contain(const list_t * list,int move)227 bool list_contain(const list_t * list, int move) {
228 
229    int i;
230 
231    ASSERT(list_is_ok(list));
232    ASSERT(move_is_ok(move));
233 
234    for (i = 0; i < list->size; i++) {
235       if (list->move[i] == move) return true;
236    }
237 
238    return false;
239 }
240 
241 // list_equal()
242 
list_equal(list_t * list_1,list_t * list_2)243 bool list_equal(list_t * list_1, list_t * list_2) {
244 
245    list_t copy_1[1], copy_2[1];
246    int i;
247 
248    ASSERT(list_is_ok(list_1));
249    ASSERT(list_is_ok(list_2));
250 
251    if (list_1->size != list_2->size) return false;
252 
253    list_copy(copy_1,list_1);
254    list_note(copy_1);
255    list_sort(copy_1);
256 
257    list_copy(copy_2,list_2);
258    list_note(copy_2);
259    list_sort(copy_2);
260 
261    for (i = 0; i < copy_1->size; i++) {
262       if (copy_1->move[i] != copy_2->move[i]) return false;
263    }
264 
265    return true;
266 }
267 
268 // list_disp()
269 
list_disp(const list_t * list,const board_t * board)270 void list_disp(const list_t * list, const board_t * board) {
271 
272    int i, move, value;
273    char string[256];
274 
275    ASSERT(list_is_ok(list));
276    ASSERT(board_is_ok(board));
277 
278    for (i = 0; i < list->size; i++) {
279 
280       move = list->move[i];
281       value = list->value[i];
282 
283       if (!move_to_can(move,board,string,256)) ASSERT(false);
284       my_log("POLYGLOT %-5s %04X %+4d\n",string,move,value);
285    }
286 
287    my_log("POLYGLOT\n");
288 }
289 
290 }  // namespace adapter
291 
292 // end of list.cpp
293 
294