king8.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
eval/ml/king8.cc
Go to the documentation of this file.
1 #include "osl/eval/ml/king8.h"
2 #include "osl/checkmate/king8Info.h"
3 using osl::MultiInt;
4 using osl::MultiIntPair;
5
6 template <bool Opening>
7 osl::misc::CArray<int, 32> osl::eval::ml::King8EffectEmptySquare<Opening>::table;
8 template <bool Opening>
9 osl::misc::CArray<int, 32> osl::eval::ml::King8EffectDefenseSquare<Opening>::table;
10
11 osl::misc::CArray<int, 32> osl::eval::ml::King8Effect::empty_table;
12 osl::misc::CArray<int, 32> osl::eval::ml::King8Effect::defense_table;
13 osl::misc::CArray<int, 288> osl::eval::ml::King8Effect::empty_y_table;
14 osl::misc::CArray<int, 288> osl::eval::ml::King8Effect::defense_y_table;
15
16 void osl::eval::ml::
17 King8Effect::setUp(const Weights &weights)
18 {
19 for (size_t i = 0; i < empty_table.size(); ++i)
20 {
21 empty_table[i] = weights.value(i);
22 }
23 for (size_t i = 0; i < defense_table.size(); ++i)
24 {
25 defense_table[i] = weights.value(i + empty_table.size());
26 }
27 for (size_t i = 0; i < empty_y_table.size(); ++i)
28 {
29 empty_y_table[i] = weights.value(i + empty_table.size() +
30 defense_table.size());
31 }
32 for (size_t i = 0; i < defense_y_table.size(); ++i)
33 {
34 defense_y_table[i] = weights.value(i + empty_table.size() +
35 defense_table.size() +
36 empty_y_table.size());
37 }
38 }
39
40 int osl::eval::ml::King8Effect::eval(
41 const osl::state::NumEffectState &state)
42 {
43 int result = 0;
44 const Piece black_king = state.kingPiece<BLACK>();
45 const Piece white_king = state.kingPiece<WHITE>();
46 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
47 {
48 const Direction dir = static_cast<Direction>(i);
49 {
50 EffectState empty, defense;
51 effectState(state, BLACK, dir, empty, defense);
52 if (empty != NOT_EMPTY)
53 {
54 result -= empty_table[index(dir, empty)];
55 result -= empty_y_table[indexY(black_king, dir, empty)];
56 }
57 if (defense != NOT_EMPTY)
58 {
59 result -= defense_table[index(dir, defense)];
60 result -= defense_y_table[indexY(black_king, dir, defense)];
61 }
62 }
63 {
64 EffectState empty, defense;
65 effectState(state, WHITE, dir, empty, defense);
66 if (empty != NOT_EMPTY)
67 {
68 result += empty_table[index(dir, empty)];
69 result += empty_y_table[indexY(white_king, dir, empty)];
70 }
71 if (defense != NOT_EMPTY)
72 {
73 result += defense_table[index(dir, defense)];
74 result += defense_y_table[indexY(white_king, dir, defense)];
75 }
76 }
77 }
78 return result;
79 }
80
81 int osl::eval::ml::
82 King8Effect::index(const Direction dir,
83 EffectState state)
84 {
85 return (dir * 4 + state);
86 }
87
88 int osl::eval::ml::
89 King8Effect::indexY(Piece king,
90 const Direction dir,
91 EffectState state)
92 {
93 const int y = ((king.owner() == BLACK) ?
94 king.square().y() : 10 - king.square().y());
95 return (dir * 4 + state) * 9 + y - 1;
96 }
97
98
99
100 void osl::eval::ml::
101 King8Effect::effectState(const NumEffectState &state,
102 const Player defenseP,
103 const Direction dir,
104 EffectState &empty,
105 EffectState &defense)
106 {
107 const Square target =
108 Board_Table.nextSquare(defenseP,
109 state.kingSquare(defenseP),
110 dir);
111 if (!state.pieceAt(target).isEmpty())
112 {
113 empty = defense = NOT_EMPTY;
114 return;
115 }
116 const int attack_count = state.countEffect(alt(defenseP), target);
117 const int defense_count = state.countEffect(defenseP, target);
118 if (attack_count == 0)
119 {
120 empty = NO_EFFECT;
121 defense = NO_EFFECT;
122 }
123 else if (defense_count == 1)
124 {
125 empty = MORE_EFFECT_KING_ONLY;
126 }
127 else if (attack_count >= defense_count)
128 {
129 empty = MORE_EFFECT;
130 }
131 else
132 {
133 empty = LESS_EFFECT;
134 }
135 if (defense_count == 1 && attack_count > defense_count)
136 {
137 defense = MORE_EFFECT_KING_ONLY;
138 }
139 else if (attack_count > defense_count)
140 {
141 defense = MORE_EFFECT;
142 }
143 else
144 {
145 defense = LESS_EFFECT;
146 }
147 }
148
149
150
151 struct osl::eval::ml::King8EffectBase::
152 MakeEffectStateSimple
153 {
154 EffectState operator()(const NumEffectState &state,
155 const Player defense,
156 const Direction dir) const
157 {
158 const Square target =
159 Board_Table.nextSquare(defense,
160 state.kingSquare(defense),
161 dir);
162 if (!state.pieceAt(target).isEmpty())
163 return NOT_EMPTY;
164
165 const int attack_count = state.countEffect(alt(defense), target);
166 if (attack_count == 0)
167 return NO_EFFECT;
168 const int defense_count = state.countEffect(defense, target);
169 if (defense_count == 1)
170 return MORE_EFFECT_KING_ONLY;
171 else if (attack_count >= defense_count)
172 return MORE_EFFECT;
173 else
174 return LESS_EFFECT;
175 }
176 };
177
178 struct osl::eval::ml::King8EffectBase::
179 MakeEffectStateDefense
180 {
181 EffectState operator()(const NumEffectState &state,
182 const Player defense,
183 const Direction dir) const
184 {
185 const Square target =
186 Board_Table.nextSquare(defense,
187 state.kingSquare(defense),
188 dir);
189 if (!state.pieceAt(target).isOnBoardByOwner(defense))
190 return NOT_EMPTY;
191
192 const int attack_count = state.countEffect(alt(defense), target);
193 if (attack_count == 0)
194 return NO_EFFECT;
195
196 const int defense_count = state.countEffect(defense, target);
197 if (defense_count == 1 && attack_count > defense_count)
198 return MORE_EFFECT_KING_ONLY;
199 else if (attack_count > defense_count)
200 return MORE_EFFECT;
201 else
202 return LESS_EFFECT;
203 }
204 };
205
206 template <class MakeEffectState>
207 const osl::CArray<int,2>
208 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
209 __attribute__ ((used))
210 #endif
211 osl::eval::ml::
212 King8EffectBase::evalCommon(const osl::state::NumEffectState &state, const table_t& table)
213 {
214 MakeEffectState f;
215 CArray<int,2> result = {{0, 0}};
216 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
217 {
218 const Direction dir = static_cast<Direction>(i);
219 const EffectState black_effect_state = f(state, BLACK, dir);
220 if (black_effect_state != NOT_EMPTY)
221 {
222 result[0] -= table[index(dir, black_effect_state)];
223 }
224 const EffectState white_effect_state = f(state, WHITE, dir);
225 if (white_effect_state != NOT_EMPTY)
226 {
227 result[1] += table[index(dir, white_effect_state)];
228 }
229 }
230
231 return result;
232 }
233
234 template <class MakeEffectState>
235 const osl::CArray<int,2>
236 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
237 __attribute__ ((used))
238 #endif
239 osl::eval::ml::
240 King8EffectBase::evalWithUpdateCommon(const osl::state::NumEffectState &new_state, Move last_move,
241 const CArray<int,2>& last_value, const table_t& table)
242 {
243 CArray<int,2> result = last_value;
244 MakeEffectState f;
245 BoardMask mask = new_state.changedEffects();
246 mask.set(last_move.to()); mask.set(last_move.from());
247 for (int z=0; z<2; ++z)
248 {
249 const Player pl = indexToPlayer(z);
250 const Square king = new_state.kingSquare(pl);
251 bool update = mask.anyInRange(Board_Mask_Table3x3.mask(king));
252 if (! update)
253 continue;
254 result[z] = 0;
255 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
256 {
257 const Direction dir = static_cast<Direction>(i);
258 const EffectState effect_state = f(new_state, pl, dir);
259 if (effect_state != NOT_EMPTY)
260 {
261 result[z] -= table[index(dir, effect_state)];
262 }
263 }
264 if (z == 1)
265 result[1] = -result[1];
266 }
267 return result;
268 }
269
270 template <class MakeEffectState>
271 inline
272 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
273 King8EffectBase::evalWithUpdateCommon(const osl::state::NumEffectState &new_state, Move last_move,
274 const CArray<int,2>& last_value_o, const CArray<int,2>& last_value_e,
275 const table_t& table_o, const table_t& table_e)
276 {
277 CArray<int,2> result_o = last_value_o, result_e = last_value_e;
278 MakeEffectState f;
279 BoardMask mask = new_state.changedEffects();
280 mask.set(last_move.to()); mask.set(last_move.from());
281 for (int z=0; z<2; ++z)
282 {
283 const Player pl = indexToPlayer(z);
284 const Square king = new_state.kingSquare(pl);
285 bool update = mask.anyInRange(Board_Mask_Table3x3.mask(king));
286 if (! update)
287 continue;
288 result_o[z] = result_e[z] = 0;
289 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
290 {
291 const Direction dir = static_cast<Direction>(i);
292 const EffectState effect_state = f(new_state, pl, dir);
293 if (effect_state != NOT_EMPTY)
294 {
295 result_o[z] -= table_o[index(dir, effect_state)];
296 result_e[z] -= table_e[index(dir, effect_state)];
297 }
298 }
299 if (z == 1)
300 {
301 result_o[1] = -result_o[1];
302 result_e[1] = -result_e[1];
303 }
304 }
305 return std::make_pair(result_o, result_e);
306 }
307
308 template <bool Opening>
309 void osl::eval::ml::
310 King8EffectEmptySquare<Opening>::setUp(const Weights &weights)
311 {
312 table.fill(0);
313 for (size_t i = 0; i < weights.dimension(); ++i)
314 {
315 table[i] = weights.value(i);
316 }
317 }
318
319 template <bool Opening>
320 const osl::CArray<int,2> osl::eval::ml::
321 King8EffectEmptySquare<Opening>::eval(const osl::state::NumEffectState &state)
322 {
323 return evalCommon<MakeEffectStateSimple>(state, table);
324 }
325 template <bool Opening>
326 const osl::CArray<int,2> osl::eval::ml::
327 King8EffectEmptySquare<Opening>::evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move,
328 const CArray<int,2>& last_value)
329 {
330 return evalWithUpdateCommon<MakeEffectStateSimple>
331 (new_state, last_move, last_value, table);
332 }
333
334 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
335 osl::eval::ml::King8EffectEmptySquareBoth::
336 evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move,
337 const CArray<int,2>& last_value_opening,
338 const CArray<int,2>& last_value_ending)
339 {
340 return evalWithUpdateCommon<MakeEffectStateSimple>
341 (new_state, last_move, last_value_opening, last_value_ending,
342 King8EffectEmptySquare<true>::table, King8EffectEmptySquare<false>::table);
343 }
344
345
346 template <bool Opening>
347 void osl::eval::ml::
348 King8EffectDefenseSquare<Opening>::setUp(const Weights &weights)
349 {
350 table.fill(0);
351 for (size_t i = 0; i < weights.dimension(); ++i)
352 {
353 table[i] = weights.value(i);
354 }
355 }
356 template <bool Opening>
357 const osl::CArray<int,2> osl::eval::ml::
358 King8EffectDefenseSquare<Opening>::eval(const osl::state::NumEffectState &state)
359 {
360 return evalCommon<MakeEffectStateDefense>(state, table);
361 }
362 template <bool Opening>
363 const osl::CArray<int,2> osl::eval::ml::
364 King8EffectDefenseSquare<Opening>::evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move,
365 const CArray<int,2>& last_value)
366 {
367 return evalWithUpdateCommon<MakeEffectStateDefense>
368 (new_state, last_move, last_value, table);
369 }
370
371
372 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
373 osl::eval::ml::King8EffectDefenseSquareBoth::
374 evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move,
375 const CArray<int,2>& last_value_opening,
376 const CArray<int,2>& last_value_ending)
377 {
378 return evalWithUpdateCommon<MakeEffectStateDefense>
379 (new_state, last_move, last_value_opening, last_value_ending,
380 King8EffectDefenseSquare<true>::table, King8EffectDefenseSquare<false>::table);
381 }
382
383
384
385 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
386 osl::eval::ml::King8EffectAll::base_table;
387 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
388 osl::eval::ml::King8EffectAll::u_table;
389 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
390 osl::eval::ml::King8EffectAll::d_table;
391 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
392 osl::eval::ml::King8EffectAll::l_table;
393 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
394 osl::eval::ml::King8EffectAll::r_table;
395
396 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
397 osl::eval::ml::King8EffectAll::base_defense_piece_table;
398 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
399 osl::eval::ml::King8EffectAll::u_defense_piece_table;
400 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
401 osl::eval::ml::King8EffectAll::d_defense_piece_table;
402 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
403 osl::eval::ml::King8EffectAll::l_defense_piece_table;
404 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
405 osl::eval::ml::King8EffectAll::r_defense_piece_table;
406
407 void osl::eval::ml::
408 King8EffectAll::setUp(const Weights &weights)
409 {
410 base_table.fill(0);
411 u_table.fill(0);
412 d_table.fill(0);
413 l_table.fill(0);
414 r_table.fill(0);
415 base_defense_piece_table.fill(0);
416 u_defense_piece_table.fill(0);
417 d_defense_piece_table.fill(0);
418 l_defense_piece_table.fill(0);
419 r_defense_piece_table.fill(0);
420 for (size_t i = 0; i < ONE_DIM; ++i)
421 {
422 base_table[i] = weights.value(i);
423 u_table[i] = weights.value(i+ONE_DIM);
424 d_table[i] = weights.value(i+ONE_DIM*2);
425 l_table[i] = weights.value(i+ONE_DIM*3);
426 r_table[i] = weights.value(i+ONE_DIM*4);
427 base_defense_piece_table[i] = weights.value(i+ONE_DIM*5);
428 u_defense_piece_table[i] = weights.value(i+ONE_DIM*6);
429 d_defense_piece_table[i] = weights.value(i+ONE_DIM*7);
430 l_defense_piece_table[i] = weights.value(i+ONE_DIM*8);
431 r_defense_piece_table[i] = weights.value(i+ONE_DIM*9);
432 }
433 }
434
435 void
436 osl::eval::ml::King8EffectAll::effectState(
437 const NumEffectState &state,
438 const Player defense,
439 const Direction dir,
440 EffectState &empty, EffectState &defense_effect)
441 {
442 empty = NOT_EMPTY;
443 defense_effect = NOT_EMPTY;
444 const Square target =
445 Board_Table.nextSquare(defense,
446 state.kingSquare(defense),
447 dir);
448 const Piece piece = state.pieceAt(target);
449 if (!target.isOnBoard() ||
450 piece.isOnBoardByOwner(alt(defense)))
451 return;
452
453 const int attack_count = state.countEffect(alt(defense), target);
454 const int defense_count = state.countEffect(defense, target);
455
456 if (piece.isEmpty())
457 {
458 if (attack_count == 0)
459 empty = NO_EFFECT;
460 else if (defense_count == 1)
461 empty = MORE_EFFECT_KING_ONLY;
462 else if (attack_count >= defense_count)
463 empty = MORE_EFFECT;
464 else
465 empty = LESS_EFFECT;
466 }
467 else
468 {
469 if (attack_count == 0)
470 defense_effect = NO_EFFECT;
471 else if (defense_count == 1 && attack_count > defense_count)
472 defense_effect = MORE_EFFECT_KING_ONLY;
473 else if (attack_count > defense_count)
474 defense_effect = MORE_EFFECT;
475 else
476 defense_effect = LESS_EFFECT;
477 }
478 }
479
480 int osl::eval::ml::
481 King8EffectAll::index(const Direction dir, EffectState state)
482 {
483 return dir * 4 + state;
484 }
485
486 int osl::eval::ml::
487 King8EffectAll::eval(const osl::state::NumEffectState &state,
488 PieceMask /*black_mask*/, PieceMask /*white_mask*/)
489 {
490 int result = 0;
491 osl::checkmate::King8Info black_king(state.Iking8Info(BLACK));
492 const int black_liberty = black_king.liberty();
493 const bool black_u_blocked =
494 (black_liberty & ((DirectionTraits<UL>::mask |
495 DirectionTraits<U>::mask |
496 DirectionTraits<UR>::mask))) == 0;
497 const bool black_d_blocked =
498 (black_liberty & ((DirectionTraits<DL>::mask |
499 DirectionTraits<D>::mask |
500 DirectionTraits<DR>::mask))) == 0;
501 const bool black_l_blocked =
502 (black_liberty & ((DirectionTraits<UL>::mask |
503 DirectionTraits<L>::mask |
504 DirectionTraits<DL>::mask))) == 0;
505 const bool black_r_blocked =
506 (black_liberty & ((DirectionTraits<UR>::mask |
507 DirectionTraits<R>::mask |
508 DirectionTraits<DR>::mask))) == 0;
509 osl::checkmate::King8Info white_king(state.Iking8Info(WHITE));
510 const int white_liberty = white_king.liberty();
511 const bool white_u_blocked =
512 (white_liberty & ((DirectionTraits<UL>::mask |
513 DirectionTraits<U>::mask |
514 DirectionTraits<UR>::mask))) == 0;
515 const bool white_d_blocked =
516 (white_liberty & ((DirectionTraits<DL>::mask |
517 DirectionTraits<D>::mask |
518 DirectionTraits<DR>::mask))) == 0;
519 const bool white_l_blocked =
520 (white_liberty & ((DirectionTraits<UL>::mask |
521 DirectionTraits<L>::mask |
522 DirectionTraits<DL>::mask))) == 0;
523 const bool white_r_blocked =
524 (white_liberty & ((DirectionTraits<UR>::mask |
525 DirectionTraits<R>::mask |
526 DirectionTraits<DR>::mask))) == 0;
527
528 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
529 {
530 const Direction dir = static_cast<Direction>(i);
531 EffectState black_empty_effect_state,
532 black_defense_effect_state;
533 effectState(state, BLACK, dir,
534 black_empty_effect_state, black_defense_effect_state);
535 if (black_empty_effect_state != NOT_EMPTY)
536 {
537 const int idx = index(dir, black_empty_effect_state);
538 result -= base_table[idx];
539 if (black_u_blocked)
540 result -= u_table[idx];
541 if (black_d_blocked)
542 result -= d_table[idx];
543 if (black_l_blocked)
544 result -= l_table[idx];
545 if (black_r_blocked)
546 result -= r_table[idx];
547 }
548 if (black_defense_effect_state != NOT_EMPTY)
549 {
550 const int idx = index(dir, black_defense_effect_state);
551 result -= base_defense_piece_table[idx];
552 if (black_u_blocked)
553 result -= u_defense_piece_table[idx];
554 if (black_d_blocked)
555 result -= d_defense_piece_table[idx];
556 if (black_l_blocked)
557 result -= l_defense_piece_table[idx];
558 if (black_r_blocked)
559 result -= r_defense_piece_table[idx];
560 }
561 EffectState white_empty_effect_state,
562 white_defense_effect_state;
563 effectState(state, WHITE, dir,
564 white_empty_effect_state, white_defense_effect_state);
565 if (white_empty_effect_state != NOT_EMPTY)
566 {
567 const int idx = index(dir, white_empty_effect_state);
568 result += base_table[idx];
569 if (white_u_blocked)
570 result += u_table[idx];
571 if (white_d_blocked)
572 result += d_table[idx];
573 if (white_l_blocked)
574 result += l_table[idx];
575 if (white_r_blocked)
576 result += r_table[idx];
577 }
578 if (white_defense_effect_state != NOT_EMPTY)
579 {
580 const int idx = index(dir, white_defense_effect_state);
581 result += base_defense_piece_table[idx];
582 if (white_u_blocked)
583 result += u_defense_piece_table[idx];
584 if (white_d_blocked)
585 result += d_defense_piece_table[idx];
586 if (white_l_blocked)
587 result += l_defense_piece_table[idx];
588 if (white_r_blocked)
589 result += r_defense_piece_table[idx];
590 }
591 }
592
593 return result;
594 }
595
596
597 osl::misc::CArray<MultiInt, osl::eval::ml::KingXBothBlocked::ONE_DIM>
598 osl::eval::ml::KingXBothBlocked::table;
599 osl::misc::CArray<MultiInt, osl::eval::ml::KingXBothBlockedY::ONE_DIM>
600 osl::eval::ml::KingXBothBlockedY::table;
601
602 void osl::eval::ml::
603 KingXBothBlocked::setUp(const Weights &weights)
604 {
605 for (int i = 0; i < ONE_DIM; ++i)
606 {
607 for (int s=0; s<NStages; ++s)
608 table[i][s] = weights.value(i + ONE_DIM*s);
609 }
610 }
611
612 void osl::eval::ml::
613 KingXBothBlockedY::setUp(const Weights &weights)
614 {
615 for (int i = 0; i < ONE_DIM; ++i)
616 {
617 for (int s=0; s<NStages; ++s)
618 table[i][s] = weights.value(i + ONE_DIM*s);
619 }
620 }
621
622 template <int Sign>
623 inline
624 void osl::eval::ml::
625 KingXBothBlocked::adjust(int index, int index_y, MultiInt &out)
626 {
627 if(Sign>0)
628 out += KingXBothBlocked::table[index] +KingXBothBlockedY::table[index_y];
629 else
630 out -= KingXBothBlocked::table[index] +KingXBothBlockedY::table[index_y];
631 }
632
633 MultiIntPair osl::eval::ml::
634 KingXBothBlocked::eval(const NumEffectState &state)
635 {
636 MultiIntPair result;
637 King8Info black(state.Iking8Info(BLACK));
638 if ((black.liberty() & (DirectionTraits<UL>::mask |
639 DirectionTraits<L>::mask |
640 DirectionTraits<DL>::mask |
641 DirectionTraits<UR>::mask |
642 DirectionTraits<R>::mask |
643 DirectionTraits<DR>::mask)) == 0)
644 {
645 const Square black_king = state.kingSquare<BLACK>();
646 adjust<1>(index(black_king),
647 indexY<BLACK>(black_king),
648 result[BLACK]);
649 }
650
651 King8Info white(state.Iking8Info(WHITE));
652 if ((white.liberty() & (DirectionTraits<UL>::mask |
653 DirectionTraits<L>::mask |
654 DirectionTraits<DL>::mask |
655 DirectionTraits<UR>::mask |
656 DirectionTraits<R>::mask |
657 DirectionTraits<DR>::mask)) == 0)
658 {
659 const Square white_king = state.kingSquare<WHITE>();
660 adjust<-1>(index(white_king),
661 indexY<WHITE>(white_king),
662 result[WHITE]);
663 }
664
665 return result;
666 }
667
668 template <osl::Player P>
669 int osl::eval::ml::KingXBlockedBase::index(
670 Square king, int diff)
671 {
672 const int king_x = king.x();
673 if (P == BLACK)
674 {
675 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
676 int x_diff = diff;
677 if (king_x >= 6)
678 x_diff = -x_diff;
679 return target_x - 1 + ((x_diff == 1) ? 0 : 5);
680 }
681 else
682 {
683 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
684 int x_diff = diff;
685 if (king_x >= 5)
686 x_diff = -x_diff;
687 return target_x - 1 + ((x_diff == 1) ? 0 : 5);
688 }
689 }
690
691 template <osl::Player P>
692 bool osl::eval::ml::KingXBlockedBase::isBlocked(
693 const NumEffectState &state,
694 int diff)
695 {
696 #if 1
697 const King8Info info(state.Iking8Info(P));
698 if ((diff == 1) ^ (P == BLACK))
699 return (info.liberty() & (DirectionTraits<UR>::mask
700 | DirectionTraits<R>::mask
701 | DirectionTraits<DR>::mask)) == 0;
702 assert((diff == 1 && P == BLACK) || (diff == -1 && P == WHITE));
703 return (info.liberty() & (DirectionTraits<UL>::mask
704 | DirectionTraits<L>::mask
705 | DirectionTraits<DL>::mask)) == 0;
706 #else
707 const Square pos = state.kingSquare<P>();
708 const int target_x = pos.x() + diff;
709 for (int y = pos.y() - 1; y <= pos.y() + 1; ++y)
710 {
711 Square target(target_x, y);
712 Piece p(state.pieceAt(target));
713 if ((!p.isEdge()) && ! p.isOnBoardByOwner<P>() &&
714 !state.hasEffectAt<PlayerTraits<P>::opponent>(target))
715 {
716 return false;
717 }
718 }
719 return true;
720 #endif
721 }
722
723 const MultiIntPair osl::eval::ml::
724 KingXBlockedBase::eval(const osl::state::NumEffectState &state, const table_t& table)
725 {
726 MultiIntPair val;
727 const Square black_king = state.kingSquare<BLACK>();
728 const Square white_king = state.kingSquare<WHITE>();
729 const int b = playerToIndex(BLACK), w = playerToIndex(WHITE);
730 if (isBlocked<BLACK>(state, 1))
731 val[b] += table[index<BLACK>(black_king, 1)];
732 if (isBlocked<BLACK>(state, -1))
733 val[b] += table[index<BLACK>(black_king, -1)];
734
735 if (isBlocked<WHITE>(state, 1))
736 val[w] -= table[index<WHITE>(white_king, 1)];
737 if (isBlocked<WHITE>(state, -1))
738 val[w] -= table[index<WHITE>(white_king, -1)];
739 return val;
740 }
741
742 const MultiIntPair osl::eval::ml::
743 KingXBlockedYBase::eval(const osl::state::NumEffectState &state,
744 const table_t& table)
745 {
746 MultiIntPair val;
747 const Square black_king = state.kingSquare<BLACK>();
748 const Square white_king = state.kingSquare<WHITE>();
749 const int b = playerToIndex(BLACK), w = playerToIndex(WHITE);
750 const bool black_r_blocked = KingXBlockedBase::isBlocked<BLACK>(state, 1);
751 const bool black_l_blocked = KingXBlockedBase::isBlocked<BLACK>(state, -1);
752 if (black_r_blocked)
753 val[b] += table[index<BLACK>(black_king, 1)];
754 if (black_l_blocked)
755 val[b] += table[index<BLACK>(black_king, -1)];
756
757 const bool white_r_blocked = KingXBlockedBase::isBlocked<WHITE>(state, 1);
758 const bool white_l_blocked = KingXBlockedBase::isBlocked<WHITE>(state, -1);
759 if (white_r_blocked)
760 val[w] -= table[index<WHITE>(white_king, 1)];
761 if (white_l_blocked)
762 val[w] -= table[index<WHITE>(white_king, -1)];
763 return val;
764 }
765
766 #if 0
767 inline
768 std::pair<osl::CArray<int,2>,osl::CArray<int,2> >
769 osl::eval::ml::
770 KingXBlockedBase::evalWithUpdate(const NumEffectState &new_state, Move last_move,
771 const CArray<int,2>& last_value_o, const CArray<int,2>& last_value_e,
772 const table_t& table_o, const table_t& table_e)
773 {
774 CArray<int,2> val_o = last_value_o;
775 CArray<int,2> val_e = last_value_e;
776 const Square black_king = new_state.kingSquare<BLACK>();
777 const Square white_king = new_state.kingSquare<WHITE>();
778 BoardMask mask = new_state.changedEffects();
779 mask.set(last_move.from()); mask.set(last_move.to());
780 if (mask.anyInRange(Board_Mask_Table3x3.mask(black_king)))
781 {
782 const int b = playerToIndex(BLACK);
783 val_o[b] = val_e[b]= 0;
784 if (isBlocked<BLACK>(new_state, 1)) {
785 val_o[b] += table_o[index<BLACK>(black_king, 1)];
786 val_e[b] += table_e[index<BLACK>(black_king, 1)];
787 }
788 if (isBlocked<BLACK>(new_state, -1)) {
789 val_o[b] += table_o[index<BLACK>(black_king, -1)];
790 val_e[b] += table_e[index<BLACK>(black_king, -1)];
791 }
792 }
793 if (mask.anyInRange(Board_Mask_Table3x3.mask(white_king)))
794 {
795 const int w = playerToIndex(WHITE);
796 val_o[w] = val_e[w]= 0;
797 if (isBlocked<WHITE>(new_state, 1)) {
798 val_o[w] -= table_o[index<WHITE>(white_king, 1)];
799 val_e[w] -= table_e[index<WHITE>(white_king, 1)];
800 }
801 if (isBlocked<WHITE>(new_state, -1)) {
802 val_o[w] -= table_o[index<WHITE>(white_king, -1)];
803 val_e[w] -= table_e[index<WHITE>(white_king, -1)];
804 }
805 }
806 return std::make_pair(val_o, val_e);
807 }
808 #endif
809
810 template <int Sign>
811 inline
812 void osl::eval::ml::
813 KingXBlockedYBase::adjust(int index, int index_y, MultiInt &out)
814 {
815 if(Sign>0)
816 out += KingXBlocked::table[index]+ KingXBlockedY::table[index_y];
817 else
818 out -= KingXBlocked::table[index]+ KingXBlockedY::table[index_y];
819 }
820
821 inline
822 void
823 osl::eval::ml::
824 KingXBlockedYBase::evalWithUpdateBang(const NumEffectState &new_state,
825 Move last_move,
826 MultiIntPair& values)
827 {
828 const Square black_king = new_state.kingSquare<BLACK>();
829 const Square white_king = new_state.kingSquare<WHITE>();
830 BoardMask mask = new_state.changedEffects();
831 mask.set(last_move.from()); mask.set(last_move.to());
832 if (mask.anyInRange(Board_Mask_Table3x3.mask(black_king)))
833 {
834 values[BLACK].clear();
835 const bool black_r_blocked = KingXBlockedBase::isBlocked<BLACK>(new_state, 1);
836 const bool black_l_blocked = KingXBlockedBase::isBlocked<BLACK>(new_state, -1);
837 if (black_r_blocked) {
838 adjust<1>(KingXBlockedBase::index<BLACK>(black_king, 1),
839 index<BLACK>(black_king, 1),
840 values[BLACK]);
841 }
842 if (black_l_blocked) {
843 adjust<1>(KingXBlockedBase::index<BLACK>(black_king, -1),
844 index<BLACK>(black_king, -1),
845 values[BLACK]);
846 }
847 if (black_r_blocked && black_l_blocked)
848 {
849 KingXBothBlocked::adjust<1>(KingXBothBlocked::index(black_king),
850 KingXBothBlocked::indexY<BLACK>(black_king),
851 values[BLACK]);
852 }
853 }
854 if (mask.anyInRange(Board_Mask_Table3x3.mask(white_king)))
855 {
856 values[WHITE].clear();
857 const bool white_r_blocked = KingXBlockedBase::isBlocked<WHITE>(new_state, 1);
858 const bool white_l_blocked = KingXBlockedBase::isBlocked<WHITE>(new_state, -1);
859 if (white_r_blocked) {
860 adjust<-1>(KingXBlockedBase::index<WHITE>(white_king, 1),
861 index<WHITE>(white_king, 1),
862 values[WHITE]);
863 }
864 if (white_l_blocked) {
865 adjust<-1>(KingXBlockedBase::index<WHITE>(white_king, -1),
866 index<WHITE>(white_king, -1),
867 values[WHITE]);
868 }
869 if (white_r_blocked && white_l_blocked)
870 {
871 KingXBothBlocked::adjust<-1>(KingXBothBlocked::index(white_king),
872 KingXBothBlocked::indexY<WHITE>(white_king),
873 values[WHITE]);
874 }
875 }
876 }
877
878 template <osl::Player P> inline
879 int osl::eval::ml::KingXBlockedYBase::index(
880 Square king, int diff)
881 {
882 const int king_x = king.x();
883 if (P == BLACK)
884 {
885 const int king_y = king.y();
886 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
887 int x_diff = diff;
888 if (king_x >= 6)
889 x_diff = -x_diff;
890 return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
891 }
892 else
893 {
894 const int king_y = 10 - king.y();
895 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
896 int x_diff = diff;
897 if (king_x >= 5)
898 x_diff = -x_diff;
899 return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
900 }
901 }
902
903 osl::misc::CArray<MultiInt, 10> osl::eval::ml::KingXBlocked::table;
904 osl::misc::CArray<MultiInt, 90> osl::eval::ml::KingXBlockedY::table;
905
906 void osl::eval::ml::
907 KingXBlocked::setUp(const Weights &weights,int stage)
908 {
909 for (size_t i = 0; i < table.size(); ++i)
910 {
911 table[i][stage] = weights.value(i);
912 }
913 }
914 void
915 osl::eval::ml::
916 KingXBlockedBoth::evalWithUpdateBang(const NumEffectState &new_state, Move last_move,
917 MultiIntPair& last_values)
918 {
919 KingXBlockedYBase::evalWithUpdateBang
920 (new_state, last_move, last_values);
921 }
922
923 void osl::eval::ml::
924 KingXBlockedY::setUp(const Weights &weights,int stage)
925 {
926 for (size_t i = 0; i < table.size(); ++i)
927 {
928 table[i][stage] = weights.value(i);
929 }
930 }
931
932
933 osl::misc::CArray<MultiInt, 80> osl::eval::ml::KingXBlocked3::table;
934 osl::misc::CArray<MultiInt, 720> osl::eval::ml::KingXBlocked3::y_table;
935
936 void osl::eval::ml::KingXBlocked3::setUp(const Weights &weights)
937 {
938 for (int i = 0; i < ONE_DIM; ++i)
939 {
940 for (int s=0; s<NStages; ++s)
941 table[i][s] = weights.value(i + ONE_DIM*s);
942 }
943 }
944
945 void osl::eval::ml::KingXBlocked3Y::setUp(const Weights &weights)
946 {
947 for (int i = 0; i < ONE_DIM; ++i)
948 {
949 for (int s=0; s<NStages; ++s)
950 KingXBlocked3::y_table[i][s] = weights.value(i + ONE_DIM*s);
951 }
952 for(int x=1;x<=5;x++)
953 for(int y=1;y<=9;y++)
954 for(int is_l=0;is_l<2;is_l++)
955 for(int u_blocked=0;u_blocked<2;u_blocked++)
956 for(int opp_u_blocked=0;opp_u_blocked<2;opp_u_blocked++)
957 for(int opp_blocked=0;opp_blocked<2;opp_blocked++){
958 int indexY=x - 1 + 5 * (y - 1 + 9 * ((is_l ? 1 : 0) + 2 * ((u_blocked ? 1 : 0) + 2 * ((opp_u_blocked ? 1 : 0) + 2 * (opp_blocked ? 1 : 0)))));
959 int index0=x - 1 + 5 * ((is_l ? 1 : 0) + 2 * ((u_blocked ? 1 : 0) + 2 * ((opp_u_blocked ? 1 : 0) + 2 * (opp_blocked ? 1 : 0))));
960 KingXBlocked3::y_table[indexY]+=KingXBlocked3::table[index0];
961 }
962 }
963
964 MultiInt osl::eval::ml::
965 KingXBlocked3::eval(const NumEffectState &state)
966 {
967 MultiInt result;
968 King8Info black(state.Iking8Info(BLACK));
969 if ((black.liberty() & (DirectionTraits<UL>::mask |
970 DirectionTraits<L>::mask |
971 DirectionTraits<DL>::mask)) == 0)
972 {
973 adjust<1>(
974 indexY<BLACK>(state.kingSquare<BLACK>(),
975 true,
976 (black.liberty() & DirectionTraits<U>::mask) == 0,
977 (black.liberty() & DirectionTraits<UR>::mask) == 0,
978 (black.liberty() & DirectionTraits<R>::mask) == 0),
979 result);
980 }
981 if ((black.liberty() & (DirectionTraits<UR>::mask |
982 DirectionTraits<R>::mask |
983 DirectionTraits<DR>::mask)) == 0)
984 {
985 adjust<1>(
986 indexY<BLACK>(state.kingSquare<BLACK>(),
987 false,
988 (black.liberty() & DirectionTraits<U>::mask) == 0,
989 (black.liberty() & DirectionTraits<UL>::mask) == 0,
990 (black.liberty() & DirectionTraits<L>::mask) == 0),
991 result);
992 }
993 King8Info white(state.Iking8Info(WHITE));
994 if ((white.liberty() & (DirectionTraits<UL>::mask |
995 DirectionTraits<L>::mask |
996 DirectionTraits<DL>::mask)) == 0)
997 {
998 adjust<-1>(
999 indexY<WHITE>(state.kingSquare<WHITE>(),
1000 true,
1001 (white.liberty() & DirectionTraits<U>::mask) == 0,
1002 (white.liberty() & DirectionTraits<UR>::mask) == 0,
1003 (white.liberty() & DirectionTraits<R>::mask) == 0),
1004 result);
1005 }
1006 if ((white.liberty() & (DirectionTraits<UR>::mask |
1007 DirectionTraits<R>::mask |
1008 DirectionTraits<DR>::mask)) == 0)
1009 {
1010 adjust<-1>(
1011 indexY<WHITE>(state.kingSquare<WHITE>(),
1012 false,
1013 (white.liberty() & DirectionTraits<U>::mask) == 0,
1014 (white.liberty() & DirectionTraits<UL>::mask) == 0,
1015 (white.liberty() & DirectionTraits<L>::mask) == 0),
1016 result);
1017 }
1018 return result;
1019 }
1020
1021
1022
1023 osl::misc::CArray<MultiInt, 4> osl::eval::ml::AnagumaEmpty::table;
1024
1025
1026 void osl::eval::ml::
1027 AnagumaEmpty::setUp(const Weights &weights,int stage)
1028 {
1029 for (size_t i = 0; i < table.size(); ++i)
1030 {
1031 table[i][stage] = weights.value(i);
1032 }
1033 }
1034
1035
1036 int osl::eval::ml::AnagumaEmpty::index(
1037 Square king, Square target)
1038 {
1039 return std::abs(king.x() - target.x()) + std::abs(king.y() - target.y()) * 2;
1040 }
1041
1042 template <osl::Player Defense>
1043 MultiInt osl::eval::ml::AnagumaEmpty::evalOne(const NumEffectState &state)
1044 {
1045 MultiInt result;
1046 const Square king = state.kingSquare<Defense>();
1047 if ((king.x() == 1 || king.x() == 9) &&
1048 ((Defense == BLACK && king.y() == 9) ||
1049 (Defense == WHITE && king.y() == 1))){
1050 const int x = (king.x() == 1 ? 2 : 8);
1051 const int y = (Defense == BLACK ? 8 : 2);
1052 if(Defense==BLACK){
1053 if (state.pieceAt(Square(king.x(), y)).isEmpty())
1054 result +=table[index(king, Square(king.x(), y))];
1055 if (state.pieceAt(Square(x, y)).isEmpty())
1056 result +=table[index(king, Square(x, y))];
1057 if (state.pieceAt(Square(x, king.y())).isEmpty())
1058 result +=table[index(king, Square(x, king.y()))];
1059 }
1060 else{
1061 if (state.pieceAt(Square(king.x(), y)).isEmpty())
1062 result -=table[index(king, Square(king.x(), y))];
1063 if (state.pieceAt(Square(x, y)).isEmpty())
1064 result -=table[index(king, Square(x, y))];
1065 if (state.pieceAt(Square(x, king.y())).isEmpty())
1066 result -=table[index(king, Square(x, king.y()))];
1067 }
1068 }
1069 return result;
1070 }
1071
1072 MultiInt osl::eval::ml::
1073 AnagumaEmpty::eval(const osl::state::NumEffectState &state)
1074 {
1075 return evalOne<BLACK>(state) + evalOne<WHITE>(state);
1076 }
1077
1078
1079
1080 namespace osl
1081 {
1082 namespace eval
1083 {
1084 namespace ml
1085 {
1086 template class King8EffectEmptySquare<true>;
1087 template class King8EffectEmptySquare<false>;
1088 template class King8EffectDefenseSquare<true>;
1089 template class King8EffectDefenseSquare<false>;
1090 }
1091 }
1092 }
1093 // ;;; Local Variables:
1094 // ;;; mode:c++
1095 // ;;; c-basic-offset:2
1096 // ;;; End: