00001 //--------------------------------------------------------------------------- 00002 /** @file 00003 */ 00004 //--------------------------------------------------------------------------- 00005 00006 #include <boost/test/auto_unit_test.hpp> 00007 00008 #include "BoardUtils.hpp" 00009 #include "ConstBoard.hpp" 00010 00011 using namespace benzene; 00012 00013 //--------------------------------------------------------------------------- 00014 00015 namespace { 00016 00017 BOOST_AUTO_TEST_CASE(ConstBoard_Dimensions) 00018 { 00019 BOOST_REQUIRE(MAX_WIDTH >= 5 && MAX_HEIGHT >= 7); 00020 ConstBoard* cb = &ConstBoard::Get(1, 1); 00021 BOOST_CHECK_EQUAL(cb->Width(), 1); 00022 BOOST_CHECK_EQUAL(cb->Height(), 1); 00023 cb = &ConstBoard::Get(5); 00024 BOOST_CHECK_EQUAL(cb->Width(), 5); 00025 BOOST_CHECK_EQUAL(cb->Height(), 5); 00026 cb = &ConstBoard::Get(4, 7); 00027 BOOST_CHECK_EQUAL(cb->Width(), 4); 00028 BOOST_CHECK_EQUAL(cb->Height(), 7); 00029 cb = &ConstBoard::Get(MAX_WIDTH, MAX_HEIGHT); 00030 BOOST_CHECK_EQUAL(cb->Width(), MAX_WIDTH); 00031 BOOST_CHECK_EQUAL(cb->Height(), MAX_HEIGHT); 00032 } 00033 00034 BOOST_AUTO_TEST_CASE(ConstBoard_CellsLocationsValid) 00035 { 00036 BOOST_REQUIRE(MAX_WIDTH >= 5 && MAX_HEIGHT >= 3); 00037 ConstBoard* cb = &ConstBoard::Get(5, 3); 00038 bitset_t b1 = cb->GetCells(); 00039 BOOST_CHECK_EQUAL(b1.count(), 15u); 00040 BOOST_CHECK(b1.test(FIRST_CELL)); 00041 BOOST_CHECK(!b1.test(FIRST_CELL-1)); 00042 BOOST_CHECK(!b1.test(NORTH)); 00043 BOOST_CHECK(!b1.test(SOUTH)); 00044 BOOST_CHECK(!b1.test(WEST)); 00045 BOOST_CHECK(!b1.test(EAST)); 00046 bitset_t b2 = cb->GetLocations(); // adds 4 edges 00047 BOOST_CHECK_EQUAL(b1.count() + 4, b2.count()); 00048 BOOST_CHECK(BitsetUtil::IsSubsetOf(b1, b2)); 00049 BOOST_CHECK(b2.test(FIRST_EDGE)); 00050 BOOST_CHECK(!b2.test(FIRST_EDGE-1)); 00051 BOOST_CHECK(!b2.test(SWAP_PIECES)); 00052 bitset_t b3 = cb->GetValid(); // adds swap and resign 00053 BOOST_CHECK_EQUAL(b2.count() + 2, b3.count()); 00054 BOOST_CHECK(BitsetUtil::IsSubsetOf(b2, b3)); 00055 BOOST_CHECK(b3.test(FIRST_SPECIAL)); 00056 BOOST_CHECK(!b3.test(FIRST_SPECIAL-1)); 00057 00058 // checking individual HexPoints 00059 BOOST_CHECK(cb->IsValid(SWAP_PIECES)); 00060 BOOST_CHECK(!cb->IsLocation(SWAP_PIECES)); 00061 BOOST_CHECK(cb->IsLocation(NORTH)); 00062 BOOST_CHECK(cb->IsLocation(SOUTH)); 00063 BOOST_CHECK(cb->IsValid(EAST)); 00064 BOOST_CHECK(!cb->IsCell(WEST)); 00065 BOOST_CHECK(cb->IsValid(HEX_CELL_A1)); 00066 BOOST_CHECK(cb->IsCell(HEX_CELL_A3)); 00067 BOOST_CHECK(cb->IsLocation(HEX_CELL_E3)); 00068 BOOST_CHECK(!cb->IsValid(INVALID_POINT)); 00069 BOOST_CHECK(cb->IsValid(RESIGN)); 00070 BOOST_CHECK(!cb->IsLocation(RESIGN)); 00071 BOOST_CHECK(FIRST_INVALID==BITSETSIZE || !cb->IsValid(FIRST_INVALID)); 00072 BOOST_CHECK(!cb->IsValid(HEX_CELL_F1)); 00073 BOOST_CHECK(!cb->IsValid(HEX_CELL_A4)); 00074 BOOST_CHECK(!cb->IsValid(HEX_CELL_E4)); 00075 00076 // checking validity of bitsets 00077 BOOST_CHECK(cb->IsValid(b1)); 00078 BOOST_CHECK(cb->IsValid(b2)); 00079 BOOST_CHECK(cb->IsValid(b3)); 00080 BOOST_CHECK(!cb->IsValid(b3.flip())); 00081 b3.flip(0); 00082 BOOST_CHECK(!cb->IsValid(b3.flip())); 00083 b1.reset(); 00084 b1.set(0); 00085 BOOST_CHECK(!cb->IsValid(b1)); 00086 b1.flip(0); 00087 b1.set(6); 00088 b1.set(7); 00089 BOOST_CHECK(cb->IsValid(b1)); 00090 00091 // testing that FIRST_INVALID is just beyond the last valid 00092 // HexPoint on the largest possible board 00093 cb = &ConstBoard::Get(MAX_WIDTH, MAX_HEIGHT); 00094 BOOST_CHECK(FIRST_INVALID==BITSETSIZE); 00095 BOOST_CHECK(FIRST_INVALID-1==HEX_CELL_K11); 00096 BOOST_CHECK(cb->IsValid(HEX_CELL_K11)); 00097 } 00098 00099 BOOST_AUTO_TEST_CASE(ConstBoard_CellLocationValidIterators) 00100 { 00101 BOOST_REQUIRE(MAX_WIDTH >= 9 && MAX_HEIGHT >= 6); 00102 ConstBoard* cb = &ConstBoard::Get(9, 6); 00103 bitset_t originalBitset, remainingBitset; 00104 bool allInSet, noRepeats; 00105 00106 // testing cells iterator 00107 allInSet = true; 00108 noRepeats = true; 00109 originalBitset = cb->GetCells(); 00110 remainingBitset = originalBitset; 00111 for (BoardIterator it(cb->Interior()); it; ++it) { 00112 allInSet = allInSet && originalBitset.test(*it); 00113 noRepeats = noRepeats && remainingBitset.test(*it); 00114 remainingBitset.reset(*it); 00115 } 00116 BOOST_CHECK(allInSet); 00117 BOOST_CHECK(noRepeats); 00118 BOOST_CHECK(remainingBitset.none()); 00119 00120 // testing locations iterator 00121 allInSet = true; 00122 noRepeats = true; 00123 originalBitset = cb->GetLocations(); 00124 remainingBitset = originalBitset; 00125 for (BoardIterator it(cb->EdgesAndInterior()); it; ++it) { 00126 allInSet = allInSet && originalBitset.test(*it); 00127 noRepeats = noRepeats && remainingBitset.test(*it); 00128 remainingBitset.reset(*it); 00129 } 00130 BOOST_CHECK(allInSet); 00131 BOOST_CHECK(noRepeats); 00132 BOOST_CHECK(remainingBitset.none()); 00133 00134 // testing all iterator 00135 allInSet = true; 00136 noRepeats = true; 00137 originalBitset = cb->GetValid(); 00138 remainingBitset = originalBitset; 00139 for (BoardIterator it(cb->AllValid()); it; ++it) { 00140 allInSet = allInSet && originalBitset.test(*it); 00141 noRepeats = noRepeats && remainingBitset.test(*it); 00142 remainingBitset.reset(*it); 00143 } 00144 BOOST_CHECK(allInSet); 00145 BOOST_CHECK(noRepeats); 00146 BOOST_CHECK(remainingBitset.none()); 00147 } 00148 00149 BOOST_AUTO_TEST_CASE(ConstBoard_NeighbourIterators) 00150 { 00151 BOOST_REQUIRE(MAX_WIDTH >= 11 && MAX_HEIGHT >= 11); 00152 BOOST_REQUIRE(Pattern::MAX_EXTENSION >= 3); 00153 ConstBoard* cb = &ConstBoard::Get(8, 8); 00154 bitset_t b; 00155 bool allAdjacent, allUnique; 00156 00157 // testing immediate neighbours iterator 00158 allAdjacent = true; 00159 allUnique = true; 00160 for (BoardIterator it(cb->Nbs(FIRST_CELL)); it; ++it) { 00161 allAdjacent = allAdjacent && cb->Adjacent(FIRST_CELL, *it); 00162 allUnique = allUnique && (!b.test(*it)); 00163 b.set(*it); 00164 } 00165 BOOST_CHECK(allAdjacent); 00166 BOOST_CHECK(allUnique); 00167 BOOST_CHECK_EQUAL(b.count(), 4u); 00168 00169 b.reset(); 00170 allAdjacent = true; 00171 allUnique = true; 00172 for (BoardIterator it(cb->Nbs(WEST)); it; ++it) { 00173 allAdjacent = allAdjacent && cb->Adjacent(WEST, *it); 00174 allUnique = allUnique && (!b.test(*it)); 00175 b.set(*it); 00176 } 00177 BOOST_CHECK(allAdjacent); 00178 BOOST_CHECK(allUnique); 00179 // interior cells + nbr edges 00180 BOOST_CHECK_EQUAL(b.count(), (std::size_t)(cb->Height()+2)); 00181 00182 b.reset(); 00183 allAdjacent = true; 00184 allUnique = true; 00185 for (BoardIterator it(cb->Nbs(HEX_CELL_B6)); it; ++it) { 00186 allAdjacent = allAdjacent && cb->Adjacent(HEX_CELL_B6, *it); 00187 allUnique = allUnique && (!b.test(*it)); 00188 b.set(*it); 00189 } 00190 BOOST_CHECK(allAdjacent); 00191 BOOST_CHECK(allUnique); 00192 BOOST_CHECK_EQUAL(b.count(), 6u); 00193 00194 // testing radius neighbours iterator 00195 cb = &ConstBoard::Get(11, 11); 00196 int radius; 00197 bool allWithinRadius; 00198 radius = 2; 00199 b.reset(); 00200 allUnique = true; 00201 allWithinRadius = true; 00202 for (BoardIterator it(cb->Nbs(HEX_CELL_F6, radius)); it; ++it) { 00203 int curDistance = cb->Distance(HEX_CELL_F6, *it); 00204 allWithinRadius = allWithinRadius && (0 < curDistance) && (curDistance <= radius); 00205 allUnique = allUnique && (!b.test(*it)); 00206 b.set(*it); 00207 } 00208 BOOST_CHECK(allUnique); 00209 BOOST_CHECK(allWithinRadius); 00210 BOOST_CHECK_EQUAL(b.count(), 18u); 00211 00212 radius = 3; 00213 b.reset(); 00214 allUnique = true; 00215 allWithinRadius = true; 00216 for (BoardIterator it(cb->Nbs(HEX_CELL_F6, radius)); it; ++it) { 00217 int curDistance = cb->Distance(HEX_CELL_F6, *it); 00218 allWithinRadius = allWithinRadius && (0 < curDistance) && (curDistance <= radius); 00219 allUnique = allUnique && (!b.test(*it)); 00220 b.set(*it); 00221 } 00222 BOOST_CHECK(allUnique); 00223 BOOST_CHECK(allWithinRadius); 00224 BOOST_CHECK_EQUAL(b.count(), 36u); 00225 00226 b.reset(); 00227 allUnique = true; 00228 allWithinRadius = true; 00229 for (BoardIterator it(cb->Nbs(HEX_CELL_D3, radius)); it; ++it) { 00230 int curDistance = cb->Distance(HEX_CELL_D3, *it); 00231 allWithinRadius = allWithinRadius && (0 < curDistance) && (curDistance <= radius); 00232 allUnique = allUnique && (!b.test(*it)); 00233 b.set(*it); 00234 } 00235 BOOST_CHECK(allUnique); 00236 BOOST_CHECK(allWithinRadius); 00237 BOOST_CHECK_EQUAL(b.count(), 33u); 00238 00239 b.reset(); 00240 allUnique = true; 00241 allWithinRadius = true; 00242 for (BoardIterator it(cb->Nbs(SOUTH, radius)); it; ++it) { 00243 int curDistance = cb->Distance(SOUTH, *it); 00244 allWithinRadius = allWithinRadius && (0 < curDistance) && (curDistance <= radius); 00245 allUnique = allUnique && (!b.test(*it)); 00246 b.set(*it); 00247 } 00248 BOOST_CHECK(allUnique); 00249 BOOST_CHECK(allWithinRadius); 00250 BOOST_CHECK_EQUAL(b.count(), (std::size_t)(radius*cb->Width() + 2)); 00251 00252 cb = &ConstBoard::Get(1, 1); 00253 b.reset(); 00254 allUnique = true; 00255 allWithinRadius = true; 00256 for (BoardIterator it(cb->Nbs(EAST, radius)); it; ++it) { 00257 int curDistance = cb->Distance(EAST, *it); 00258 allWithinRadius = allWithinRadius && (0 < curDistance) && (curDistance <= radius); 00259 allUnique = allUnique && (!b.test(*it)); 00260 b.set(*it); 00261 } 00262 BOOST_CHECK(allUnique); 00263 BOOST_CHECK(allWithinRadius); 00264 BOOST_CHECK_EQUAL(b.count(), 3u); // interior cell + 2 nbg edges 00265 00266 cb = &ConstBoard::Get(3, 8); 00267 b.reset(); 00268 allUnique = true; 00269 allWithinRadius = true; 00270 for (BoardIterator it(cb->Nbs(WEST, radius)); it; ++it) { 00271 int curDistance = cb->Distance(WEST, *it); 00272 allWithinRadius = allWithinRadius && (0 < curDistance) && (curDistance <= radius); 00273 allUnique = allUnique && (!b.test(*it)); 00274 b.set(*it); 00275 } 00276 BOOST_CHECK(allUnique); 00277 BOOST_CHECK(allWithinRadius); 00278 BOOST_CHECK_EQUAL(b.count(), cb->GetLocations().count() - 2); 00279 00280 radius = 2; 00281 b.reset(); 00282 allUnique = true; 00283 allWithinRadius = true; 00284 for (BoardIterator it(cb->Nbs(WEST, radius)); it; ++it) { 00285 int curDistance = cb->Distance(WEST, *it); 00286 allWithinRadius = allWithinRadius 00287 && (0 < curDistance) && (curDistance <= radius); 00288 allUnique = allUnique && (!b.test(*it)); 00289 b.set(*it); 00290 } 00291 BOOST_CHECK(allUnique); 00292 BOOST_CHECK(allWithinRadius); 00293 BOOST_CHECK_EQUAL((int)b.count(), radius*cb->Height() + 2); 00294 } 00295 00296 BOOST_AUTO_TEST_CASE(ConstBoard_DistanceAndAdjacency) 00297 { 00298 BOOST_REQUIRE(MAX_WIDTH >= 11 && MAX_HEIGHT >= 11); 00299 00300 // distance/adjacency from point on board to edges 00301 ConstBoard* cb = &ConstBoard::Get(1, 11); 00302 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_A1, NORTH), 1); 00303 BOOST_CHECK(cb->Adjacent(HEX_CELL_A1, NORTH)); 00304 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_A1, SOUTH), 11); 00305 BOOST_CHECK(!cb->Adjacent(HEX_CELL_A1, SOUTH)); 00306 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_A1, EAST), 1); 00307 BOOST_CHECK(cb->Adjacent(HEX_CELL_A1, EAST)); 00308 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_A1, WEST), 1); 00309 BOOST_CHECK(cb->Adjacent(HEX_CELL_A1, WEST)); 00310 cb = &ConstBoard::Get(8, 1); 00311 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_B1, NORTH), 1); 00312 BOOST_CHECK(cb->Adjacent(HEX_CELL_A1, NORTH)); 00313 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_B1, SOUTH), 1); 00314 BOOST_CHECK(cb->Adjacent(HEX_CELL_A1, SOUTH)); 00315 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_B1, EAST), 7); 00316 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_B1, WEST), 2); 00317 00318 // distance and adjacency between two edges 00319 cb = &ConstBoard::Get(6, 7); 00320 BOOST_CHECK_EQUAL(cb->Distance(NORTH, NORTH), 0); 00321 BOOST_CHECK(!cb->Adjacent(NORTH, NORTH)); 00322 BOOST_CHECK_EQUAL(cb->Distance(EAST, NORTH), 1); 00323 BOOST_CHECK_EQUAL(cb->Distance(SOUTH, NORTH), 7); 00324 BOOST_CHECK_EQUAL(cb->Distance(WEST, EAST), 6); 00325 BOOST_CHECK(!cb->Adjacent(EAST, WEST)); 00326 BOOST_CHECK(!cb->Adjacent(NORTH, SOUTH)); 00327 BOOST_CHECK(cb->Adjacent(NORTH, EAST)); 00328 BOOST_CHECK(cb->Adjacent(NORTH, WEST)); 00329 BOOST_CHECK(cb->Adjacent(SOUTH, EAST)); 00330 BOOST_CHECK(cb->Adjacent(SOUTH, WEST)); 00331 00332 // adjacency of two points on board 00333 BOOST_CHECK(!cb->Adjacent(HEX_CELL_C6, HEX_CELL_B5)); 00334 BOOST_CHECK(cb->Adjacent(HEX_CELL_C6, HEX_CELL_B6)); 00335 BOOST_CHECK(cb->Adjacent(HEX_CELL_C6, HEX_CELL_B7)); 00336 BOOST_CHECK(cb->Adjacent(HEX_CELL_C6, HEX_CELL_C5)); 00337 BOOST_CHECK(!cb->Adjacent(HEX_CELL_C6, HEX_CELL_C6)); 00338 BOOST_CHECK(cb->Adjacent(HEX_CELL_C6, HEX_CELL_C7)); 00339 BOOST_CHECK(cb->Adjacent(HEX_CELL_C6, HEX_CELL_D5)); 00340 BOOST_CHECK(cb->Adjacent(HEX_CELL_C6, HEX_CELL_D6)); 00341 BOOST_CHECK(!cb->Adjacent(HEX_CELL_C6, HEX_CELL_D7)); 00342 BOOST_CHECK(cb->Adjacent(HEX_CELL_A7, WEST)); 00343 BOOST_CHECK(cb->Adjacent(HEX_CELL_A7, SOUTH)); 00344 00345 // distance between two points on board 00346 cb = &ConstBoard::Get(11, 11); 00347 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_F4, HEX_CELL_F4), 0); 00348 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_F4, HEX_CELL_A1), 8); 00349 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_F4, HEX_CELL_B7), 4); 00350 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_F4, HEX_CELL_C4), 3); 00351 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_F4, HEX_CELL_F1), 3); 00352 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_F4, HEX_CELL_F10), 6); 00353 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_F4, HEX_CELL_H4), 2); 00354 BOOST_CHECK_EQUAL(cb->Distance(HEX_CELL_F4, HEX_CELL_K11), 12); 00355 } 00356 00357 } 00358 00359 //---------------------------------------------------------------------------