Board_info Alphabeta::run_alphabeta(Board_info ¤t_board, int depth, int a, int b, char tile) { Board_info best_child, temp_child; vector<Board_info> children; vector<Board_info>::iterator child; int break_flag=0; if (depth == 0){ current_board.visited = 1; if(tile == your_tile){ current_board.a=a; current_board.b=current_board.weight; } else{ current_board.a=current_board.weight; current_board.b=b; } (DEBUG?cout:log) << xy2(current_board.x, current_board.y)<<","<<this->depth - depth<<","<< current_board.weight<<","; (DEBUG?cout:log) << ab2(a, b)<<endl; }else{ if(current_board.visited==0){ current_board.visited = 1; (DEBUG?cout:log) << xy2(current_board.x, current_board.y)<<","<<this->depth - depth<<","; (DEBUG?cout:log) << (tile == your_tile ?"-":"")<<"Infinity,"; (DEBUG?cout:log) <<ab2(a,b) <<endl; } } if(depth == 0){ return current_board; } children = get_new_boards_vector(your_tile, current_board, tile); // it's pocoutible get 0 child if(children.size() == 0){ cout<<"no children"<<endl; current_board.print(); exit(0); }else{ sort(children.begin(), children.end(), compare_order); } best_child.a = a; best_child.b = b; if(tile == your_tile){ for(child=children.begin(); child != children.end(); ++child){ temp_child = run_alphabeta(*child, depth -1, best_child.a, best_child.b, other_tile); best_child = max_a(best_child, temp_child); (DEBUG?cout:log) << xy2(current_board.x, current_board.y)<<","<<this->depth - depth<<","<< best_child.weight<<","; if(best_child.b<=best_child.a){ cout<<"prune form:"<<xy2(best_child.x, best_child.y)<<endl; break_flag = 1; (DEBUG?cout:log) <<ab2(current_board.a,best_child.b)<<endl; break; }else{ (DEBUG?cout:log) <<ab2(best_child.a,best_child.b)<<endl; } } }else{ for(child=children.begin(); child != children.end(); ++child){ temp_child = run_alphabeta(*child, depth -1, best_child.a, best_child.b, your_tile); best_child = min_b(best_child, temp_child); (DEBUG?cout:log) << xy2(current_board.x, current_board.y)<<","<<this->depth - depth<<","<< best_child.weight<<","; if(best_child.b<=best_child.a){ cout<<"prune form:"<<xy2(best_child.x, best_child.y)<<endl; break_flag = 1; (DEBUG?cout:log) <<ab2(best_child.a,current_board.b)<<endl; break; }else{ (DEBUG?cout:log) <<ab2(best_child.a,best_child.b)<<endl; } } } free_boards(children); //weight is the only var to save/to callee current_board.weight = best_child.weight; current_board.best_child_x = best_child.x; current_board.best_child_y = best_child.y; if(break_flag==0){ if(tile == your_tile) current_board.b = best_child.a; else current_board.a = best_child.b; } cout << xy2(current_board.x, current_board.y) <<":"<< xy2(current_board.best_child_x, current_board.best_child_y)<<endl; return current_board; }
int main() { Mercator::Terrain terrain; terrain.setBasePoint(0, 0, 2.8); terrain.setBasePoint(1, 0, 7.1); terrain.setBasePoint(0, 1, 0.2); terrain.setBasePoint(1, 1, 14.7); Mercator::Segment * segment = terrain.getSegment(0, 0); if (segment == 0) { std::cerr << "Segment not created by addition of required basepoints" << std::endl << std::flush; return 1; } segment->populate(); //test box definitely outside terrain WFMath::AxisBox<3> highab(WFMath::Point<3> (10.0, 10.0, segment->getMax() + 3.0), WFMath::Point<3> (20.0, 20.0, segment->getMax() + 6.1)); if (Mercator::Intersect(terrain, highab)) { std::cerr << "axisbox intersects with terrain even though it should be above it" << std::endl; return 1; } //test box definitely inside terrain WFMath::AxisBox<3> lowab(WFMath::Point<3> (10.0, 10.0, segment->getMin() - 6.1), WFMath::Point<3> (20.0, 20.0, segment->getMax() - 3.0)); if (!Mercator::Intersect(terrain, lowab)) { std::cerr << "axisbox does not intersect with terrain even though it should be below it" << std::endl; return 1; } //test axis box moved from above terrain to below it. bool inter=false; float dz = highab.highCorner()[2] - highab.lowCorner()[2] - 0.1; while (highab.highCorner()[2] > segment->getMin()) { highab.shift(WFMath::Vector<3>(0.0, 0.0, -dz)); if (Mercator::Intersect(terrain, highab)) { inter=true; break; } } if (!inter) { std::cerr << "axisbox passed through terrain with no intersection" << std::endl; return 1; } //test axisbox that spans two segments terrain.setBasePoint(0, 2, 4.8); terrain.setBasePoint(1, 2, 3.7); Mercator::Segment *segment2 = terrain.getSegment(0, 1); segment2->populate(); float segmax=std::max(segment->getMax(), segment2->getMax()); float segmin=std::min(segment->getMin(), segment2->getMin()); WFMath::AxisBox<3> ab(WFMath::Point<3> (50.0, 10.0, segmax + 3.0), WFMath::Point<3> (70.0, 20.0, segmax + 6.1)); if (Mercator::Intersect(terrain, ab)) { std::cerr << "axisbox2 intersects with terrain even though it should be above it" << std::endl; return 1; } WFMath::AxisBox<3> ab2(WFMath::Point<3> (50.0, 10.0, segmin - 6.1), WFMath::Point<3> (70.0, 20.0, segmin + 3.0)); if (!Mercator::Intersect(terrain, ab2)) { std::cerr << "axisbox2 does not intersect with terrain even though it should be below it" << std::endl; return 1; } WFMath::Point<3> intPoint; WFMath::Vector<3> intNorm; float par; //test vertical ray if (Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(0.0,0.0,50.0), intPoint, intNorm, par)) { std::cerr << "vertical ray intersected when it shouldnt" << std::endl; return 1; } if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(0.0,0.0,-50.0), intPoint, intNorm, par)) { std::cerr << "vertical ray didnt intersect when it should" << std::endl; return 1; } //test each quadrant if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(10.0,10.0,-100.0), intPoint, intNorm, par)) { std::cerr << "quad1 ray didnt intersect when it should" << std::endl; return 1; } if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(10.0,-15.0,-50.0), intPoint, intNorm, par)) { std::cerr << "quad2 ray didnt intersect when it should" << std::endl; return 1; } if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(-10.0,-10.0,-50.0), intPoint, intNorm, par)) { std::cerr << "quad3 ray didnt intersect when it should" << std::endl; return 1; } if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(-10.0,10.0,-50.0), intPoint, intNorm, par)) { std::cerr << "quad4 ray didnt intersect when it should" << std::endl; return 1; } //test dx==0 and dy==0 if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(0.0,10.0,-50.0), intPoint, intNorm, par)) { std::cerr << "y+ ray didnt intersect when it should" << std::endl; return 1; } if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(0.0,-10.0,-50.0), intPoint, intNorm, par)) { std::cerr << "y- ray didnt intersect when it should" << std::endl; return 1; } if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(-10.0,0.0,-50.0), intPoint, intNorm, par)) { std::cerr << "x- ray didnt intersect when it should" << std::endl; return 1; } if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), WFMath::Vector<3>(10.0,0.0,-50.0), intPoint, intNorm, par)) { std::cerr << "x+ ray didnt intersect when it should" << std::endl; return 1; } //test a longer ray if (!Mercator::Intersect(terrain, WFMath::Point<3>(-10.08, -20.37, segmax + 3), WFMath::Vector<3>(100.0,183.0,-50.0), intPoint, intNorm, par)) { std::cerr << "long ray didnt intersect when it should" << std::endl; return 1; } //check the height value float h; WFMath::Vector<3> n; terrain.getHeightAndNormal(intPoint[0], intPoint[1], h, n); n.normalize(); if (n != intNorm) { std::cerr << "calculated normal is different from getHeightAndNormal" << std::endl; std::cerr << intPoint << std::endl; std::cerr << intNorm << "!=" << n << std::endl; // return 1; } // We can't check for equality here is it just doesn't work with // floats. Look it up in any programming book if you don't believe me. // - 20040721 <*****@*****.**> if (fabs(h - intPoint[2]) > 0.00001) { std::cerr << "calculated height is different from getHeightAndNormal" << std::endl; std::cerr << h << "!=" << intPoint[2] << std::endl; return 1; } return 0; }