← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~7010622-q/widelands/topple-seafaring-1 into lp:widelands

 

toptopple has proposed merging lp:~7010622-q/widelands/topple-seafaring-1 into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~7010622-q/widelands/topple-seafaring-1/+merge/310436

Expedition strategy is quite weak at present, but I could improve it by providing a higher-quality random source (game().logic_rand()) and setting up for a more rational decision making when confronted with island-hit and port-spaces. The repetition of island-crusing (circle) has been minimized as AI can't afford the time. An additional criterion for ship-building is introduced: number of ships shall be at least the number of available ports of the player.

-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~7010622-q/widelands/topple-seafaring-1 into lp:widelands.
=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc	2016-11-03 07:20:57 +0000
+++ src/ai/defaultai.cc	2016-11-09 14:22:35 +0000
@@ -3556,10 +3556,13 @@
 	if (shipyards_count == 0 || !idle_shipyard_stocked || ports_count == 0) {
 		enough_ships = FleetStatus::kDoNothing;
 	} else if (allships.size() - expeditions_in_progress == 0) {
-		// We always need at least one ship in transport mode
+		// we always need at least one ship in transport mode
+		enough_ships = FleetStatus::kNeedShip;
+	} else if (int(allships.size()) - ports_count < 0) {
+		// we want at least as many ships as we have ports
 		enough_ships = FleetStatus::kNeedShip;
 	} else if (persistent_data->ships_utilization > 5000) {
-		// If ships utilization is too high
+		// if ships utilization is too high
 		enough_ships = FleetStatus::kNeedShip;
 	} else {
 		enough_ships = FleetStatus::kEnoughShips;
@@ -4689,7 +4692,7 @@
 
 	allships.push_back(ShipObserver());
 	allships.back().ship = &ship;
-	if (game().get_gametime() % 2 == 0) {
+	if (game().logic_rand() % 20 < 10) {
 		allships.back().island_circ_direction = IslandExploreDirection::kClockwise;
 	} else {
 		allships.back().island_circ_direction = IslandExploreDirection::kCounterClockwise;
@@ -4930,17 +4933,19 @@
 	return score;
 }
 
+
 // this is called whenever ship received a notification that requires
 // navigation decisions (these notifiation are processes not in 'real time')
 void DefaultAI::expedition_management(ShipObserver& so) {
 
-	Map& map = game().map();
+    Map& map = game().map();
 	const int32_t gametime = game().get_gametime();
+	// probability for island exploration repetition
+	const int repeat_island_prob = 0;
 
 	// second we put current spot into visited_spots
-	bool first_time_here = false;
-	if (so.visited_spots.count(so.ship->get_position().hash()) == 0) {
-		first_time_here = true;
+	bool first_time_here = so.visited_spots.count(so.ship->get_position().hash()) == 0;
+	if (first_time_here) {
 		so.visited_spots.insert(so.ship->get_position().hash());
 	}
 
@@ -4948,10 +4953,10 @@
 	// 1. Build a port there
 	if (!so.ship->exp_port_spaces().empty()) {  // making sure we have possible portspaces
 
-		// we score the place
-		const uint8_t spot_score = spot_scoring(so.ship->exp_port_spaces().front());
+		// we score the place (value max == 8)
+		const uint8_t spot_score = spot_scoring(so.ship->exp_port_spaces().front()) *2;
 
-		if ((gametime / 10) % 8 < spot_score) {  // we build a port here
+		if (game().logic_rand() % 8 < spot_score) {  // we build a port here
 			game().send_player_ship_construct_port(*so.ship, so.ship->exp_port_spaces().front());
 			so.last_command_time = gametime;
 			so.waiting_for_command_ = false;
@@ -4960,7 +4965,7 @@
 			// TODO(TiborB): how long it takes to build a port?
 			// I used 5 minutes
 			MapRegion<Area<FCoords>> mr(
-			   game().map(), Area<FCoords>(map.get_fcoords(so.ship->exp_port_spaces().front()), 8));
+			   map, Area<FCoords>(map.get_fcoords(so.ship->exp_port_spaces().front()), 8));
 			do {
 				blocked_fields.add(mr.location(), game().get_gametime() + 5 * 60 * 1000);
 			} while (mr.advance(map));
@@ -4971,21 +4976,22 @@
 
 	// 2. Go on with expedition
 
+    // we were not here before
 	if (first_time_here) {
 		game().send_player_ship_explore_island(*so.ship, so.island_circ_direction);
 		so.last_command_time = gametime;
 		so.waiting_for_command_ = false;
 
-		// we was here but to add randomnes we might continue with expedition
-	} else if (gametime % 2 == 0) {
+	// we were here before but we might randomly repeat island exploration
+	} else if (game().logic_rand() % 100 < repeat_island_prob) {
 		game().send_player_ship_explore_island(*so.ship, so.island_circ_direction);
 		so.last_command_time = gametime;
 		so.waiting_for_command_ = false;
+
 	} else {
-		// get swimmable directions
+		// determine swimmable directions
 		std::vector<Direction> possible_directions;
 		for (Direction dir = FIRST_DIRECTION; dir <= LAST_DIRECTION; ++dir) {
-
 			// testing distance of 8 fields
 			// this would say there is an 'open sea' there
 			Widelands::FCoords tmp_fcoords = map.get_fcoords(so.ship->get_position());
@@ -4994,7 +5000,6 @@
 				if (tmp_fcoords.field->nodecaps() & MOVECAPS_SWIM) {
 					if (i == 7) {
 						possible_directions.push_back(dir);
-						break;  // not needed but.....
 					}
 				} else {
 					break;
@@ -5005,14 +5010,16 @@
 		// we test if there is open sea
 		if (possible_directions.empty()) {
 			// 2.A No there is no open sea
+			// .. I'd prefer to send ship HOME instead! (toptopple)
+			// .. otherwise some escape procedure
 			game().send_player_ship_explore_island(*so.ship, so.island_circ_direction);
 			so.last_command_time = gametime;
 			so.waiting_for_command_ = false;
 			;
 		} else {
-			// 2.B Yes, pick one of avaliable directions
+			// 2.B Yes, pick one of available directions
 			const Direction final_direction =
-			   possible_directions.at(gametime % possible_directions.size());
+			   possible_directions.at(game().logic_rand() % possible_directions.size());
 			game().send_player_ship_scouting_direction(
 			   *so.ship, static_cast<WalkingDir>(final_direction));
 			so.last_command_time = gametime;


Follow ups