* @brief Initialize move generation state for a new deal. * * Sets up tracking arrays and initializes removed ranks based on the starting * position. Handles partial tricks by incorporating already-played cards. * * The removedRanks array tracks which cards are no longer available. It starts * with all cards (0xffff), then XORs with available cards to mark them as * available, then XORs bac
| 105 | * available, then XORs back any cards already played in this trick. |
| 106 | */ |
| 107 | auto Moves::Init(const int tricks, const int relStartHand, |
| 108 | const int initialRanks[], const int initialSuits[], |
| 109 | const unsigned short rank_in_suit[DDS_HANDS][DDS_SUITS], |
| 110 | const int our_trump, const int our_lead_hand) -> void { |
| 111 | currTrick = tricks; |
| 112 | trump = our_trump; |
| 113 | |
| 114 | if (relStartHand == 0) |
| 115 | track[tricks].lead_hand = our_lead_hand; |
| 116 | |
| 117 | for (int m = 0; m < 13; m++) { |
| 118 | for (int h = 0; h < DDS_HANDS; h++) { |
| 119 | moveList[m][h].current = 0; |
| 120 | moveList[m][h].last = 0; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | // 0x1ffff would be enough, but this is for compatibility. |
| 125 | for (int s = 0; s < DDS_SUITS; s++) |
| 126 | track[tricks].removed_ranks[s] = 0xffff; |
| 127 | |
| 128 | for (int h = 0; h < DDS_HANDS; h++) |
| 129 | for (int s = 0; s < DDS_SUITS; s++) |
| 130 | track[tricks].removed_ranks[s] ^= rank_in_suit[h][s]; |
| 131 | |
| 132 | for (int n = 0; n < relStartHand; n++) { |
| 133 | int s = initialSuits[n]; |
| 134 | int r = initialRanks[n]; |
| 135 | |
| 136 | track[tricks].removed_ranks[s] ^= bit_map_rank[r]; |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | auto Moves::Reinit(const int tricks, const int ourLeadHand) -> void { |
| 141 | track[tricks].lead_hand = ourLeadHand; |