Fair point. There's a number of people there that might be worth contacting.
Announcement
Collapse
No announcement yet.
AI : Army Movement
Collapse
X
-
I found this in world.h
Code:void CalcChokePoints();
Comment
-
Originally posted by E
I found this in world.h
Code:void CalcChokePoints();
The task to do here are to add that flag to strategies.txt in a manner such that it has a default value so that it hasn't to be added to strategies.txt and the default value shouldn't overwrite explicitly set values when strategies are merged.
Then you have to find the code that uses this settle good bonus and you have to add in the same way like this good bonus the choke point settle bonus.
-MartinCiv2 military advisor: "No complaints, Sir!"
Comment
-
I cheked that file quickly (gs/world/WrldCont.cpp).
The computation seems to be done on neighbours only. There are several passes, but only neighbours are cheked. (I don't know what values you get when there is an isthmus.)
The result is a map of (0,1) for land and water. Thus it's binary, either you are a choke point or not. There's no way of knowing whether it's a 2-direction or 3-direction chokepoint for instance, and the land masses aren't considered because the algorithm only checks neighbours.
It would be simple to change that by removing the chokepoints from the map, computing the size of the landmasses separated by the landpoints, and giving a weight to the chokepoint as a function of that...
But then I'm not going to do it so I'd better keep lurking.
Good luck to you all.Clash of Civilization team member
(a civ-like game whose goal is low micromanagement and good AI)
web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)
Comment
-
At least it seems to be not a problem in respect to backwards compatibility, as it looks like that choke points are recalculated after every reload, at least the stuff is not explicitly stored, so we can use more numbers then 256 to measure their quality, but even with 256 quality classes we should be able to distinguish them.
-MartinCiv2 military advisor: "No complaints, Sir!"
Comment
-
-
sekel, I hope you stick to it, a lot of people have shown interest but unfortunately few have contributed
Comment
-
OK, I nailed down the problem that caused these massive slow downs. It is this operator> from Squad_Strength:
Code:bool Squad_Strength::operator> (const Squad_Strength &squad_strength) const { bool greater = (m_attack_str > squad_strength.m_attack_str) || (m_defense_str > squad_strength.m_defense_str) || (m_transport > squad_strength.m_transport); bool greater_defenders = (m_defenders > squad_strength.m_defenders ); bool greater_ranged = (m_ranged > squad_strength.m_ranged); bool greater_ranged_str = (m_ranged_str > squad_strength.m_ranged_str ); bool greater_value = (m_value > squad_strength.m_value); bool greater_agents = (m_agent_count > squad_strength.m_agent_count); #if 0 && !defined (ACTIVISION_ORIGINAL) // Calvitix // Removed by Martin Gühmann // Causes a severe slow down on maps with more than one continent. // Needs therefore be reconsidered. That is also true for the // original code, only the greater variable is used. greater = false; // Attack difference sint16 attack_cpr = (m_attack_str - squad_strength.m_attack_str); // Defense difference sint16 defense_cpr = (m_defense_str - squad_strength.m_defense_str); // ranged difference sint16 ranged_cpr = (m_ranged_str - squad_strength.m_ranged_str); // value difference sint16 value_cpr = (m_value - squad_strength.m_value); sint16 ranged_nb = (m_ranged - squad_strength.m_ranged); sint16 defenders_nb = (m_defenders - squad_strength.m_defenders); sint16 transport_nb = (m_transport - squad_strength.m_transport); // the addition of all differences has to be greater than 0 // it is certainly better than only testing attack or defense // but can be improved (for exemple, by applying a ratio on the greater score if ((attack_cpr + defense_cpr + ranged_cpr + value_cpr) > 0) greater = true; // To be compatible with the original operator, test the // nb of transport too if (m_transport > 0 && transport_nb > 0) greater = true; // test the nb of agent too if (m_agent_count > 0 && squad_strength.m_agent_count > 0) { greater = greater || greater_agents; //when only agent count is as criterion : (for special units for example) if (m_attack_str + m_defense_str + m_ranged_str + m_value == 0) { greater = greater_agents; } } #endif return greater; }
However there seems to be something wrong with this, maybe it lies inside of this operator or the problem is finally caused outside of the operator.
-MartinCiv2 military advisor: "No complaints, Sir!"
Comment
-
Did you try replacing the end by
if ((attack_cpr + defense_cpr + ranged_cpr + value_cpr) > 0)
return greater;
// To be compatible with the original operator, test the
// nb of transport too
if (m_transport > 0 && transport_nb > 0)
return true;
// test the nb of agent too
if (m_agent_count > 0 && squad_strength.m_agent_count > 0)
{
//when only agent count is as criterion : (for special units for example)
if (m_attack_str + m_defense_str + m_ranged_str + m_value == 0)
{
return greater_agents;
}
}
return false; // or 0 or FALSE I don't know the relevant defines
?
The logic is exactly the same but you don't do useless computations. That and putting the original code in a #ifdef/#else so you don't use the other useless variables?
(back to lurker mode).Clash of Civilization team member
(a civ-like game whose goal is low micromanagement and good AI)
web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)
Comment
-
Well I came up with this code, it is a cleaner version. And it seems to help the AI. However it still causes a slow down that spontaniously disappeared. It is less severe but it is still there.
Code:bool Squad_Strength::operator> (const Squad_Strength &squad_strength) const { // To be compatible with the original operator, test the // nb of transport too sint16 transport_nb = (m_transport - squad_strength.m_transport); if(m_transport > 0 && transport_nb > 0) return true; // Attack difference sint16 attack_cpr = (m_attack_str - squad_strength.m_attack_str); // Defense difference sint16 defense_cpr = (m_defense_str - squad_strength.m_defense_str); // ranged difference sint16 ranged_cpr = (m_ranged_str - squad_strength.m_ranged_str); // value difference sint16 value_cpr = (m_value - squad_strength.m_value); // the addition of all differences has to be greater than 0 // it is certainly better than only testing attack or defense // but can be improved (for exemple, by applying a ratio on the greater score if((attack_cpr + defense_cpr + ranged_cpr + value_cpr) > 0) return true; // test the nb of agent too if(m_agent_count > 0 && squad_strength.m_agent_count > 0){ //when only agent count is as criterion : (for special units for example) if (m_attack_str + m_defense_str + m_ranged_str + m_value == 0){ return (m_agent_count > squad_strength.m_agent_count); } } return false; }
Originally posted by LDiCesare
return false; // or 0 or FALSE I don't know the relevant defines
The main difference is the size, and the operator should return a bool therefore false is more appropiate. However you can also use FALSE that is then casted to false, but using false directly is cleaner code.
Originally posted by LDiCesare
The logic is exactly the same but you don't do useless computations.
For the original version I can clearly say that this could happen:
(A > B) == true
(B > A) == true
And instance if attack strength of A is bigger than of B, and if defence strength B is bigger than of A. That's a kind of logic that worries me. I didn't check whether this could happen to the new version as well, but I doubt that this should be possible.
-MartinCiv2 military advisor: "No complaints, Sir!"
Comment
-
Well after some more testing it seems to be that the problem even with my version of the operator occurs. It seems to be that it is a problem with missing transports, and unreachable positions. For now I would consider this code as expreimental.
-MartinCiv2 military advisor: "No complaints, Sir!"
Comment
-
OK here is another version of that operator, it should now be correct and assymetrical, well except for the case A == B, then it should return false as well as for B == A.
Code:bool Squad_Strength::operator> (const Squad_Strength &squad_strength) const { // To be compatible with the original operator, test the // nb of transport too sint16 transport_nb = (m_transport - squad_strength.m_transport); if(m_transport > 0 && transport_nb > 0) return true; // Attack difference sint16 attack_cpr = (m_attack_str - squad_strength.m_attack_str); // Defense difference sint16 defense_cpr = (m_defense_str - squad_strength.m_defense_str); // ranged difference sint16 ranged_cpr = (m_ranged_str - squad_strength.m_ranged_str); // value difference sint16 value_cpr = (m_value - squad_strength.m_value); // The addition of all differences has to be greater than 0 // it is certainly better than only testing attack or defense // but can be improved (for exemple, by applying a ratio on the greater score if((attack_cpr + defense_cpr + ranged_cpr + value_cpr) > 0) return true; // Test the nb of agent too if(m_agent_count > 0 && squad_strength.m_agent_count > 0){ //If only agent count is a criterion : (for special units for example) if(m_attack_str + m_defense_str + m_ranged_str + m_value == 0 && squad_strength.m_attack_str + squad_strength.m_defense_str + squad_strength.m_ranged_str + squad_strength.m_value == 0 ){ return (m_agent_count > squad_strength.m_agent_count); } } return false; } #endif
I tested this operator against the original operator in a late game. The AI turn times seem to be equal, however this doesn't indicate that the sorting results during the game create the same length of AI turn tedium.
However I don't think that this operator is the real problem of the AI slowness. I think it has still to do something with the AI transport capacity. As AIs without the need of transporting a lot of units are much faster and aren't a problem.
Well any comments about this version of the operator. Seems it be fine. Is it error free, has it the claimed assymetry?
Some other notes about the AI, if an AI has no idea what it should do with its units it puts them on their roads, you see a lot of units sleeping on their roads. Of course that are all single units and the tiles aren't filled to the tile limit of 12 units. An easy goal for an attacker and something that is another possible AI turn time slow down.
-MartinCiv2 military advisor: "No complaints, Sir!"
Comment
-
What about this:
Code:bool Squad_Strength::operator> (const Squad_Strength &squad_strength) const { // Transport squads should always be always bigger: if(m_transport > squad_strength.m_transport) return true; else if(m_transport < squad_strength.m_transport) return false; // Attack difference sint16 attack_cpr = (m_attack_str - squad_strength.m_attack_str); // Defense difference sint16 defense_cpr = (m_defense_str - squad_strength.m_defense_str); // ranged difference sint16 ranged_cpr = (m_ranged_str - squad_strength.m_ranged_str); // value difference sint16 value_cpr = (m_value - squad_strength.m_value); // The addition of all differences has to be greater than 0 // it is certainly better than only testing attack or defense // but can be improved (for exemple, by applying a ratio on the greater score if((attack_cpr + defense_cpr + ranged_cpr + value_cpr) > 0) return true; // Test the nb of agent too if(m_agent_count > 0 && squad_strength.m_agent_count > 0){ //If only agent count is a criterion : (for special units for example) if(m_attack_str + m_defense_str + m_ranged_str + m_value == 0 && squad_strength.m_attack_str + squad_strength.m_defense_str + squad_strength.m_ranged_str + squad_strength.m_value == 0 ){ return (m_agent_count > squad_strength.m_agent_count); } } return false; }
By the way I didn't understand for what this nb_transport variable is and why Calvitix checks whether m_transport > 0 and transport_nb > 0, the first check should be included in the second one.
-MartinCiv2 military advisor: "No complaints, Sir!"
Comment
Comment