Diffstat (limited to 'noncore/games/zsame/StoneField.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/games/zsame/StoneField.cpp | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/noncore/games/zsame/StoneField.cpp b/noncore/games/zsame/StoneField.cpp index 49d8eca..56e9dc5 100644 --- a/noncore/games/zsame/StoneField.cpp +++ b/noncore/games/zsame/StoneField.cpp | |||
@@ -1,390 +1,394 @@ | |||
1 | /* | 1 | /* |
2 | * ksame 0.4 - simple Game | 2 | * ksame 0.4 - simple Game |
3 | * Copyright (C) 1997,1998 Marcus Kreutzberger | 3 | * Copyright (C) 1997,1998 Marcus Kreutzberger |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or | 7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. | 8 | * (at your option) any later version. |
9 | * | 9 | * |
10 | * This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 | * | 18 | * |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include "StoneField.h" | 21 | #include "StoneField.h" |
22 | #include <assert.h> | 22 | #include <assert.h> |
23 | 23 | ||
24 | StoneFieldState::StoneFieldState(const StoneField &stonefield) | 24 | StoneFieldState::StoneFieldState(const StoneField &stonefield) |
25 | { | 25 | { |
26 | field=new unsigned char[stonefield.maxstone]; | 26 | field=new unsigned char[stonefield.maxstone]; |
27 | for (int i=0;i<stonefield.maxstone;i++) | 27 | for (int i=0;i<stonefield.maxstone;i++) |
28 | field[i]=stonefield.field[i].color; | 28 | field[i]=stonefield.field[i].color; |
29 | 29 | ||
30 | colors=stonefield.colors; | 30 | colors=stonefield.colors; |
31 | board=stonefield.board; | 31 | board=stonefield.board; |
32 | score=stonefield.score; | 32 | score=stonefield.score; |
33 | gameover=stonefield.gameover; | 33 | gameover=stonefield.gameover; |
34 | } | 34 | } |
35 | 35 | ||
36 | StoneFieldState::~StoneFieldState() { | 36 | StoneFieldState::~StoneFieldState() { |
37 | delete[] field; | 37 | delete[] field; |
38 | } | 38 | } |
39 | 39 | ||
40 | void | 40 | void |
41 | StoneFieldState::restore(StoneField &stonefield) const { | 41 | StoneFieldState::restore(StoneField &stonefield) const { |
42 | for (int i=0;i<stonefield.maxstone;i++) { | 42 | for (int i=0;i<stonefield.maxstone;i++) { |
43 | stonefield.field[i].color=field[i]; | 43 | stonefield.field[i].color=field[i]; |
44 | stonefield.field[i].changed=true; | 44 | stonefield.field[i].changed=true; |
45 | stonefield.field[i].marked=false; | 45 | stonefield.field[i].marked=false; |
46 | } | 46 | } |
47 | 47 | ||
48 | stonefield.colors=colors; | 48 | stonefield.colors=colors; |
49 | stonefield.board=board; | 49 | stonefield.board=board; |
50 | stonefield.score=score; | 50 | stonefield.score=score; |
51 | stonefield.marked=0; | 51 | stonefield.marked=0; |
52 | stonefield.gameover=gameover; | 52 | stonefield.gameover=gameover; |
53 | } | 53 | } |
54 | 54 | ||
55 | StoneField::StoneField(int width, int height, | 55 | StoneField::StoneField(int width, int height, |
56 | int colors, unsigned int board, | 56 | int colors, unsigned int board, |
57 | bool undoenabled) | 57 | bool undoenabled) |
58 | { | 58 | { |
59 | // Q_ASSERT(width>0); | 59 | // Q_ASSERT(width>0); |
60 | // Q_ASSERT(height>0); | 60 | // Q_ASSERT(height>0); |
61 | 61 | ||
62 | if (undoenabled) undolist=new QList<StoneFieldState>; | 62 | if (undoenabled) undolist=new QList<StoneFieldState>; |
63 | else undolist=0; | 63 | else undolist=0; |
64 | 64 | ||
65 | sizex=width; | 65 | sizex=width; |
66 | sizey=height; | 66 | sizey=height; |
67 | maxstone=sizex*sizey; | 67 | maxstone=sizex*sizey; |
68 | field=new Stone[maxstone]; | 68 | field=new Stone[maxstone]; |
69 | newGame(board,colors); | 69 | newGame(board,colors); |
70 | m_gotBonus= false; | 70 | m_gotBonus= false; |
71 | } | 71 | } |
72 | 72 | ||
73 | StoneField::~StoneField() { | 73 | StoneField::~StoneField() { |
74 | delete[] field; | 74 | delete[] field; |
75 | delete undolist; | 75 | delete undolist; |
76 | // kdDebug() << "~StoneField\n" << endl; | 76 | // kdDebug() << "~StoneField\n" << endl; |
77 | } | 77 | } |
78 | 78 | ||
79 | int | 79 | int |
80 | StoneField::width() const { | 80 | StoneField::width() const { |
81 | return sizex; | 81 | return sizex; |
82 | } | 82 | } |
83 | 83 | ||
84 | int | 84 | int |
85 | StoneField::height() const { | 85 | StoneField::height() const { |
86 | return sizey; | 86 | return sizey; |
87 | } | 87 | } |
88 | 88 | ||
89 | void | 89 | void |
90 | StoneField::newGame(unsigned int board,int colors) { | 90 | StoneField::newGame(unsigned int board,int colors) { |
91 | // kdDebug() << "StoneField::newgame board " | 91 | // kdDebug() << "StoneField::newgame board " |
92 | // << board << " colors " << colors << endl; | 92 | // << board << " colors " << colors << endl; |
93 | if (colors<1) colors=3; | 93 | if (colors<1) colors=3; |
94 | if (colors>7) colors=7; | 94 | if (colors>7) colors=7; |
95 | this->colors=colors; | 95 | this->colors=colors; |
96 | this->board=board; | 96 | this->board=board; |
97 | reset(); | 97 | reset(); |
98 | } | 98 | } |
99 | 99 | ||
100 | void | 100 | void |
101 | StoneField::reset() { | 101 | StoneField::reset() { |
102 | random.setSeed(board); | 102 | random.setSeed(board); |
103 | 103 | ||
104 | Stone *stone=field; | 104 | Stone *stone=field; |
105 | for (int i=0;i<maxstone;i++,stone++) { | 105 | for (int i=0;i<maxstone;i++,stone++) { |
106 | stone->color=1+random.getLong(colors); | 106 | stone->color=1+random.getLong(colors); |
107 | stone->marked=false; | 107 | stone->marked=false; |
108 | stone->changed=true; | 108 | stone->changed=true; |
109 | } | 109 | } |
110 | 110 | ||
111 | gameover=-1; | 111 | gameover=-1; |
112 | score=0; | 112 | score=0; |
113 | marked=0; | 113 | marked=0; |
114 | 114 | ||
115 | if (undolist) { | 115 | if (undolist) { |
116 | undolist->setAutoDelete(true); | 116 | undolist->setAutoDelete(true); |
117 | undolist->clear(); | 117 | undolist->clear(); |
118 | } | 118 | } |
119 | 119 | ||
120 | 120 | ||
121 | int c[7]; | 121 | int c[7]; |
122 | int j; | 122 | int j; |
123 | for (j=0;j<7;j++) c[j]=0; | 123 | for (j=0;j<7;j++) c[j]=0; |
124 | 124 | ||
125 | for (j=0,stone=field;j<maxstone;j++,stone++) { | 125 | for (j=0,stone=field;j<maxstone;j++,stone++) { |
126 | c[stone->color]++; | 126 | c[stone->color]++; |
127 | } | 127 | } |
128 | // kdDebug() << "red " << c[1] << endl; | 128 | // kdDebug() << "red " << c[1] << endl; |
129 | // kdDebug() << "blue " << c[2] << endl; | 129 | // kdDebug() << "blue " << c[2] << endl; |
130 | // kdDebug() << "yellow " << c[3] << endl; | 130 | // kdDebug() << "yellow " << c[3] << endl; |
131 | // kdDebug() << "green " << c[4] << endl; | 131 | // kdDebug() << "green " << c[4] << endl; |
132 | 132 | ||
133 | } | 133 | } |
134 | 134 | ||
135 | int | 135 | int |
136 | StoneField::map(int x,int y) { | 136 | StoneField::map(int x,int y) { |
137 | assert (!(x<0||y<0||x>=sizex||y>=sizey)); | 137 | assert (!(x<0||y<0||x>=sizex||y>=sizey)); |
138 | return x+y*sizex; | 138 | return x+y*sizex; |
139 | } | 139 | } |
140 | 140 | ||
141 | int | 141 | int |
142 | StoneField::mark(int x,int y,bool force) { | 142 | StoneField::mark(int x,int y,bool force) { |
143 | int index=map(x,y); | 143 | int index=map(x,y); |
144 | 144 | ||
145 | if (index<0) { | 145 | if (index<0) { |
146 | unmark(); | 146 | unmark(); |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | 149 | ||
150 | if (field[index].marked) return -1; | 150 | if (field[index].marked) return -1; |
151 | unmark(); | 151 | unmark(); |
152 | 152 | ||
153 | mark(index,field[index].color); | 153 | mark(index,field[index].color); |
154 | 154 | ||
155 | if (marked==1&&!force) { | 155 | if (marked==1&&!force) { |
156 | field[index].marked=false; | 156 | field[index].marked=false; |
157 | marked=0; | 157 | marked=0; |
158 | } | 158 | } |
159 | return marked; | 159 | return marked; |
160 | } | 160 | } |
161 | 161 | ||
162 | void | 162 | void |
163 | StoneField::mark(int index,unsigned char color) { | 163 | StoneField::mark(int index,unsigned char color) { |
164 | if ( index<0 || index>=maxstone ) return; | 164 | if ( index<0 || index>=maxstone ) return; |
165 | 165 | ||
166 | Stone &stone=field[index]; | 166 | Stone &stone=field[index]; |
167 | 167 | ||
168 | if (stone.marked) return; | 168 | if (stone.marked) return; |
169 | 169 | ||
170 | if (!stone.color || stone.color!=color) return; | 170 | if (!stone.color || stone.color!=color) return; |
171 | 171 | ||
172 | stone.changed=true; | 172 | stone.changed=true; |
173 | stone.marked=true; | 173 | stone.marked=true; |
174 | marked++; | 174 | marked++; |
175 | 175 | ||
176 | // mark left | 176 | // mark left |
177 | if ((index%sizex)!=0) mark(index-1,color); | 177 | if ((index%sizex)!=0) mark(index-1,color); |
178 | // mark right | 178 | // mark right |
179 | if (((index+1)%sizex)!=0) mark(index+1,color); | 179 | if (((index+1)%sizex)!=0) mark(index+1,color); |
180 | // mark upward | 180 | // mark upward |
181 | if (index>=sizex) mark(index-sizex,color); | 181 | if (index>=sizex) mark(index-sizex,color); |
182 | // mark downward | 182 | // mark downward |
183 | if (index<(sizex-1)*sizey) mark(index+sizex,color); | 183 | if (index<(sizex-1)*sizey) mark(index+sizex,color); |
184 | } | 184 | } |
185 | 185 | ||
186 | void | 186 | void |
187 | StoneField::unmark() { | 187 | StoneField::unmark() { |
188 | if (!marked) return; | 188 | if (!marked) return; |
189 | 189 | ||
190 | Stone *stone=field; | 190 | Stone *stone=field; |
191 | for (int i=0;i<maxstone;i++,stone++) { | 191 | for (int i=0;i<maxstone;i++,stone++) { |
192 | stone->marked=false; | 192 | stone->marked=false; |
193 | stone->changed=true; | 193 | stone->changed=true; |
194 | } | 194 | } |
195 | marked=0; | 195 | marked=0; |
196 | } | 196 | } |
197 | 197 | ||
198 | int | 198 | int |
199 | StoneField::remove(int x,int y,bool force) { | 199 | StoneField::remove(int x,int y,bool force) { |
200 | int index=map(x,y); | 200 | int index=map(x,y); |
201 | 201 | ||
202 | if (index<0) return 0; | 202 | if (index<0) return 0; |
203 | 203 | ||
204 | if (!field[index].marked) { | 204 | if (!field[index].marked) { |
205 | mark(x,y,force); | 205 | mark(x,y,force); |
206 | } | 206 | } |
207 | 207 | ||
208 | if (!marked) return 0; | 208 | if (!marked) return 0; |
209 | 209 | ||
210 | // remove a single stone?? | 210 | // remove a single stone?? |
211 | if (marked==1&&!force) return 0; | 211 | if (marked==1&&!force) return 0; |
212 | 212 | ||
213 | // add current field to undolist | 213 | // add current field to undolist |
214 | if (undolist) | 214 | if (undolist) |
215 | undolist->append(new StoneFieldState(*this)); | 215 | undolist->append(new StoneFieldState(*this)); |
216 | 216 | ||
217 | // increase score | 217 | // increase score |
218 | if (marked>2) | 218 | if (marked>2) |
219 | score+=(marked-2)*(marked-2); | 219 | score+=(marked-2)*(marked-2); |
220 | 220 | ||
221 | // remove marked stones | 221 | // remove marked stones |
222 | Stone *stone=field; | 222 | Stone *stone=field; |
223 | for (int i=0;i<maxstone;i++,stone++) { | 223 | for (int i=0;i<maxstone;i++,stone++) { |
224 | if (stone->marked) { | 224 | if (stone->marked) { |
225 | stone->color=0; | 225 | stone->color=0; |
226 | stone->changed=true; | 226 | stone->changed=true; |
227 | stone->marked=false; | 227 | stone->marked=false; |
228 | } | 228 | } |
229 | } | 229 | } |
230 | int removed=marked; | 230 | int removed=marked; |
231 | marked=0; | 231 | marked=0; |
232 | 232 | ||
233 | for (int col=0;col<sizex;col++) { | 233 | for (int col=0;col<sizex;col++) { |
234 | int i1=col+maxstone-sizex; | 234 | int i1=col+maxstone-sizex; |
235 | while ( i1>=0 && field[i1].color ) i1-=sizex; | 235 | while ( i1>=0 && field[i1].color ) i1-=sizex; |
236 | int i2=i1; | 236 | int i2=i1; |
237 | while (i2>=0) { | 237 | while (i2>=0) { |
238 | while ( i2>=0 && !field[i2].color ) i2-=sizex; | 238 | while ( i2>=0 && !field[i2].color ) i2-=sizex; |
239 | while ( i2>=0 && field[i2].color ) { | 239 | while ( i2>=0 && field[i2].color ) { |
240 | field[i1].color=field[i2].color; | 240 | field[i1].color=field[i2].color; |
241 | field[i1].changed=true; | 241 | field[i1].changed=true; |
242 | field[i2].color=0; | 242 | field[i2].color=0; |
243 | field[i2].changed=true; | 243 | field[i2].changed=true; |
244 | i1-=sizex; | 244 | i1-=sizex; |
245 | i2-=sizex; | 245 | i2-=sizex; |
246 | } | 246 | } |
247 | } | 247 | } |
248 | } | 248 | } |
249 | 249 | ||
250 | // find the last column that has something | 250 | // find the last column that has something |
251 | int lastcol = sizex; | 251 | int lastcol = sizex; |
252 | while (lastcol > 0 && !field[map(lastcol-1, sizey-1)].color) { | 252 | while (lastcol > 0 && !field[map(lastcol-1, sizey-1)].color) { |
253 | lastcol--; | 253 | lastcol--; |
254 | } | 254 | } |
255 | 255 | ||
256 | for (int col=0;col<lastcol-1;) { | 256 | for (int col=0;col<lastcol-1;) { |
257 | bool empty = true; | 257 | bool empty = true; |
258 | for (int row = 0; row < sizey; row++) | 258 | for (int row = 0; row < sizey; row++) |
259 | if (field[map(col, row)].color) { | 259 | if (field[map(col, row)].color) { |
260 | empty = false; | 260 | empty = false; |
261 | break; | 261 | break; |
262 | } | 262 | } |
263 | if (!empty) { | 263 | if (!empty) { |
264 | col++; | 264 | col++; |
265 | continue; | 265 | continue; |
266 | } | 266 | } |
267 | int nextfullcol = col + 1; | 267 | int nextfullcol = col + 1; |
268 | while (nextfullcol < sizex && | 268 | while (nextfullcol < sizex && |
269 | !field[map(nextfullcol, sizey - 1)].color) | 269 | !field[map(nextfullcol, sizey - 1)].color) |
270 | nextfullcol++; | 270 | nextfullcol++; |
271 | 271 | ||
272 | if (nextfullcol > sizex - 1) | 272 | if (nextfullcol > sizex - 1) |
273 | break; // we're ready | 273 | break; // we're ready |
274 | 274 | ||
275 | for (int row=0; row < sizey; row++) { | 275 | for (int row=0; row < sizey; row++) { |
276 | int source = map(nextfullcol, row); | 276 | int source = map(nextfullcol, row); |
277 | int dest = map(col, row); | 277 | int dest = map(col, row); |
278 | field[dest].color=field[source].color; | 278 | field[dest].color=field[source].color; |
279 | field[dest].changed=true; | 279 | field[dest].changed=true; |
280 | field[source].color=0; | 280 | field[source].color=0; |
281 | field[source].changed=true; | 281 | field[source].changed=true; |
282 | } | 282 | } |
283 | } | 283 | } |
284 | 284 | ||
285 | // add a bonus, if field is empty | 285 | // add a bonus, if field is empty |
286 | if (!field[map(0, sizey-1)].color) { | 286 | if (!field[map(0, sizey-1)].color) { |
287 | score+=1000; | 287 | score+=1000; |
288 | m_gotBonus= true; | 288 | m_gotBonus= true; |
289 | } | 289 | } |
290 | 290 | ||
291 | // gameover is undefined | 291 | // gameover is undefined |
292 | gameover=-1; | 292 | gameover=-1; |
293 | return removed; | 293 | return removed; |
294 | } | 294 | } |
295 | 295 | ||
296 | bool StoneField::undoPossible() const { | 296 | bool StoneField::undoPossible() const { |
297 | return !(!undolist||undolist->isEmpty()); | 297 | return !(!undolist||undolist->isEmpty()); |
298 | } | 298 | } |
299 | 299 | ||
300 | int | 300 | int |
301 | StoneField::undo(int count) { | 301 | StoneField::undo(int count) { |
302 | if (!undoPossible()) | 302 | if (!undoPossible()) |
303 | return 0; | 303 | return 0; |
304 | if (count <= 0) | 304 | if (count <= 0) |
305 | return 0; | 305 | return 0; |
306 | int undocount=1; | 306 | int undocount=1; |
307 | StoneFieldState *state=0; | 307 | StoneFieldState *state=0; |
308 | undolist->setAutoDelete(true); | 308 | undolist->setAutoDelete(true); |
309 | while (--count>0) { | 309 | while (--count>0) { |
310 | if (undolist->count()==1) break; | 310 | if (undolist->count()==1) break; |
311 | undolist->removeLast(); | 311 | undolist->removeLast(); |
312 | undocount++; | 312 | undocount++; |
313 | } | 313 | } |
314 | state=undolist->getLast(); | 314 | state=undolist->getLast(); |
315 | // Q_ASSERT(state); | 315 | // Q_ASSERT(state); |
316 | state->restore(*this); | 316 | state->restore(*this); |
317 | undolist->removeLast(); | 317 | undolist->removeLast(); |
318 | return undocount; | 318 | return undocount; |
319 | } | 319 | } |
320 | 320 | ||
321 | bool | 321 | bool |
322 | StoneField::isGameover() const { | 322 | StoneField::isGameover() const { |
323 | register int i=maxstone-1;; | 323 | register int i=maxstone-1;; |
324 | register unsigned char color; | 324 | register unsigned char color; |
325 | 325 | ||
326 | if (gameover>=0) return (bool)gameover; | 326 | if (gameover>=0) return (bool)gameover; |
327 | // kdDebug() << "-->gameover" << endl; | 327 | // kdDebug() << "-->gameover" << endl; |
328 | 328 | ||
329 | while (i>=0) { | 329 | while (i>=0) { |
330 | // kdDebug() << i << " " << field[i].color << endl; | 330 | // kdDebug() << i << " " << field[i].color << endl; |
331 | // ignore empty fields | 331 | // ignore empty fields |
332 | while ( i>=0 && field[i].color==0 ) i--; | 332 | while ( i>=0 && field[i].color==0 ) i--; |
333 | // Wenn Stein gefunden, | 333 | // Wenn Stein gefunden, |
334 | // dann die Nachbarn auf gleiche Farbe pruefen. | 334 | // dann die Nachbarn auf gleiche Farbe pruefen. |
335 | while ( i>=0 && (color=field[i].color) ) { | 335 | while ( i>=0 && (color=field[i].color) ) { |
336 | // check left | 336 | // check left |
337 | if ( (i%sizex)!=0 && field[i-1].color==color) | 337 | if ( (i%sizex)!=0 && field[i-1].color==color) |
338 | goto check_gameover; | 338 | goto check_gameover; |
339 | // check upward | 339 | // check upward |
340 | if ( i>=sizex && field[i-sizex].color==color) | 340 | if ( i>=sizex && field[i-sizex].color==color) |
341 | goto check_gameover; | 341 | goto check_gameover; |
342 | i--; | 342 | i--; |
343 | } | 343 | } |
344 | } | 344 | } |
345 | check_gameover: | 345 | check_gameover: |
346 | gameover=(i<0); | 346 | gameover=(i<0); |
347 | // kdDebug() << "<--gameover" << endl; | 347 | // kdDebug() << "<--gameover" << endl; |
348 | return (bool)gameover; | 348 | return (bool)gameover; |
349 | } | 349 | } |
350 | 350 | ||
351 | bool StoneField::gotBonus() const { | 351 | bool StoneField::gotBonus() const { |
352 | return m_gotBonus; | 352 | return m_gotBonus; |
353 | } | 353 | } |
354 | 354 | ||
355 | void StoneField::clearBonus() { | ||
356 | m_gotBonus = false; | ||
357 | } | ||
358 | |||
355 | int | 359 | int |
356 | StoneField::getBoard() const { | 360 | StoneField::getBoard() const { |
357 | return board; | 361 | return board; |
358 | } | 362 | } |
359 | 363 | ||
360 | int | 364 | int |
361 | StoneField::getScore() const { | 365 | StoneField::getScore() const { |
362 | return score; | 366 | return score; |
363 | } | 367 | } |
364 | 368 | ||
365 | int | 369 | int |
366 | StoneField::getColors() const { | 370 | StoneField::getColors() const { |
367 | return colors; | 371 | return colors; |
368 | } | 372 | } |
369 | 373 | ||
370 | int | 374 | int |
371 | StoneField::getMarked() const { | 375 | StoneField::getMarked() const { |
372 | return marked; | 376 | return marked; |
373 | } | 377 | } |
374 | 378 | ||
375 | int | 379 | int |
376 | StoneField::getFieldSize() const { | 380 | StoneField::getFieldSize() const { |
377 | return maxstone; | 381 | return maxstone; |
378 | } | 382 | } |
379 | 383 | ||
380 | struct Stone * | 384 | struct Stone * |
381 | StoneField::getField() const { | 385 | StoneField::getField() const { |
382 | return field; | 386 | return field; |
383 | } | 387 | } |
384 | 388 | ||
385 | 389 | ||
386 | 390 | ||
387 | 391 | ||
388 | 392 | ||
389 | 393 | ||
390 | 394 | ||