/* iter.h Iterators Copyright (c) 2000, 2001, 2003, 2004 Kriang Lerdsuwanakij email: lerdsuwa@users.sourceforge.net 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; either version 2 of the License, 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 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef ITER_H #define ITER_H #include "board.h" #include "order.h" // A linked-list containing empty positions struct empty_endgame_entry { int pos; empty_endgame_entry* next; }; // Empty positions information during alpha-beta searching struct empty_endgame_info { int empty_endgame_size; empty_endgame_entry *empty_endgame_head; empty_endgame_entry empty_endgame_order[NUM_MOVE]; }; // Initialize empty_endgame_info from current board void init_endgame_iterator(byte_board_info *board, empty_endgame_info &info); // Directions #define DIR_N 0 #define DIR_NE 1 #define DIR_E 2 #define DIR_SE 3 #define DIR_S 4 #define DIR_SW 5 #define DIR_W 6 #define DIR_NW 7 /************************************************************************* Iterate positions from top-left to bottom-right *************************************************************************/ struct board_iterator { int pos; void init_pos(int pos_ = 0) { pos = pos_; } bool next() { pos++; if (pos == 64) return false; return true; } }; /************************************************************************* Iterate positions for mid-game searching *************************************************************************/ /************************************************************************* Iterate positions for end-game searching *************************************************************************/ struct board_full_endgame_iterator { int pos; int pos_real; void init_pos(int pos_ = 0) { pos_real = pos_; pos = endgame_order[pos_real]; } bool next() { pos_real++; // Only NUM_MOVE (60) since we exclude // center squares here if (pos_real == NUM_MOVE) return false; pos = endgame_order[pos_real]; return true; } }; /************************************************************************* Iterate positions for end-game searching *************************************************************************/ struct board_endgame_iterator { int pos; empty_endgame_info &info; empty_endgame_entry* pos_real; empty_endgame_entry* pos_prev; typedef empty_endgame_entry* save_type; board_endgame_iterator(empty_endgame_info &info_) : info(info_) { } void init_pos() { pos_real = info.empty_endgame_head; pos_prev = 0; // Don't check if pos_real == 0 here pos = pos_real->pos; } bool next() { if (pos_real && pos_real->next) { pos_prev = pos_real; pos_real = pos_real->next; pos = pos_real->pos; return true; } return false; } void remove_current() { if (pos_prev) pos_prev->next = pos_real->next; else info.empty_endgame_head = pos_real->next; } void restore_current() { if (pos_prev) pos_prev->next = pos_real; else info.empty_endgame_head = pos_real; } }; /************************************************************************* Iterate positions in any of eight directions *************************************************************************/ struct board_dir_iterator { int x; int y; int pos; void init_xy(int x_ = 0, int y_ = 0) { x = x_; y = y_; pos = xy_to_pos(x_, y_); } void init_pos(int pos_ = 0) { x = pos_to_x(pos_); y = pos_to_y(pos_); pos = pos_; } bool next_N() { if (y == 0) return false; y--; pos -= 8; return true; } bool next_NE() { if (x == 7 || y == 0) return false; x++; y--; pos -= 7; return true; } bool next_E() { if (x == 7) return false; x++; pos++; return true; } bool next_SE() { if (x == 7 || y == 7) return false; x++; y++; pos += 9; return true; } bool next_S() { if (y == 7) return false; y++; pos += 8; return true; } bool next_SW() { if (x == 0 || y == 7) return false; x--; y++; pos += 7; return true; } bool next_W() { if (x == 0) return false; x--; pos--; return true; } bool next_NW() { if (x == 0 || y == 0) return false; y--; x--; pos -= 9; return true; } bool next_dir(int dir) { switch (dir) { case DIR_N: return next_N(); case DIR_NE: return next_NE(); case DIR_E: return next_E(); case DIR_SE: return next_SE(); case DIR_S: return next_S(); case DIR_SW: return next_SW(); case DIR_W: return next_W(); case DIR_NW: return next_NW(); default: return false; } } void next_N_nocheck() { y--; pos -= 8; } void next_NE_nocheck() { x++; y--; pos -= 7; } void next_E_nocheck() { x++; pos++; } void next_SE_nocheck() { x++; y++; pos += 9; } void next_S_nocheck() { y++; pos += 8; } void next_SW_nocheck() { x--; y++; pos += 7; } void next_W_nocheck() { x--; pos--; } void next_NW_nocheck() { y--; x--; pos -= 9; } void next_dir_nocheck(int dir) { switch (dir) { case DIR_N: next_N_nocheck(); return; case DIR_NE: next_NE_nocheck(); return; case DIR_E: next_E_nocheck(); return; case DIR_SE: next_SE_nocheck(); return; case DIR_S: next_S_nocheck(); return; case DIR_SW: next_SW_nocheck(); return; case DIR_W: next_W_nocheck(); return; case DIR_NW: next_NW_nocheck(); return; } } }; #endif /* ITER_H */