Announcement

Collapse
No announcement yet.

AI : Army Movement

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #76
    Fair point. There's a number of people there that might be worth contacting.
    Solver, WePlayCiv Co-Administrator
    Contact: solver-at-weplayciv-dot-com
    I can kill you whenever I please... but not today. - The Cigarette Smoking Man

    Comment


    • #77
      I found this in world.h

      Code:
      void CalcChokePoints();
      does this help anything?
      Formerly known as "E" on Apolyton

      See me at Civfanatics.com

      Comment


      • #78
        Originally posted by E
        I found this in world.h

        Code:
        void CalcChokePoints();
        does this help anything?
        Well this is the declaration the function that calculates the choke points, at least its name suggests this. To check wheather the choke points are calculated correctly, we have to check the implementation in the according *.cpp source file. Actual what I had in my was to add a field to strategy.txt that like the good settle bonus that contains a bonus for settling at choke points.

        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.

        -Martin
        Civ2 military advisor: "No complaints, Sir!"

        Comment


        • #79
          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


          • #80
            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.

            -Martin
            Civ2 military advisor: "No complaints, Sir!"

            Comment


            • #81
              bump for sekel
              Formerly known as "E" on Apolyton

              See me at Civfanatics.com

              Comment


              • #82
                I´d just love to have a good C++ work environment here and start experimenting with the AI goals .... but I´ll have to wait till next week

                Comment


                • #83
                  sekel, I hope you stick to it, a lot of people have shown interest but unfortunately few have contributed
                  Formerly known as "E" on Apolyton

                  See me at Civfanatics.com

                  Comment


                  • #84
                    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;
                    }
                    For now I just disabled Calvitix code, however I think that neither the original nor Calvitix' code are right. The original code evaluates this greater variable and returns it finally. In the middle it evaluates some other variables that aren't used. Calvitix just sets this greater variable afterwards it has been evaluated to false and evaluates it again. He also ignores the other greater variables evaluated before.

                    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.

                    -Martin
                    Civ2 military advisor: "No complaints, Sir!"

                    Comment


                    • #85
                      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


                      • #86
                        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;
                        }
                        Otherwise my test game ran fine, the AI filled the whole map with cities, I saw sea activity, maybe some more coordinated activity for oversea invasion would be good. But maybe the AI should first conquer its neighbors. Unfortunatly I cannot continue the game the game had to crash during saving the autosave, that left me with a autosavegame of 9kb and that is definitely to small for a save game, and I have no idea what happened as I don't have a crash.txt of that event. ANother thing I saw is that the AI doesn't attack cities without defenders.

                        Originally posted by LDiCesare
                        return false; // or 0 or FALSE I don't know the relevant defines
                        The difference is that false is of type bool, it has the same size as a char of 1 byte IIRC. BOOL is a typedef of int and that is bigger bool. BOOL needs 4 byte, and FALSE is just 0 also an int. I know you can also see it as a short.

                        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.
                        Well I don't thing that the logic is the same, in your version and also in my version, once the transport thing is true, the operator returns true, in Calvitix version the return value could still change, however I think that our logic is the better logic as it restores the compatibility with the transport stuff, Calvitix version doesn't do this. I think that the slowdown is caused by the outcome of the operator not by the number of steps it does.

                        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.

                        -Martin
                        Civ2 military advisor: "No complaints, Sir!"

                        Comment


                        • #87
                          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.

                          -Martin
                          Civ2 military advisor: "No complaints, Sir!"

                          Comment


                          • #88
                            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 modified the final squad size test, so that it only returns true if the size of the first squad is bigger than the size of the other squad, if the values of both are 0. That means two squads are equal in strength if their values are equal irrespective of their size. Or are equal if these values are all in both squads 0 and their size is equal.

                            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.

                            -Martin
                            Civ2 military advisor: "No complaints, Sir!"

                            Comment


                            • #89
                              It is not anti-symmetrical yet. When having both[list=1][*]A.m_transport > B.m_transport > 0[*]B.Sum(strenghts) > A.Sum(strengths)[/list=1]you will have A > B (because of 1.) and B > A (because of 2.) return true.

                              Comment


                              • #90
                                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;
                                }
                                Obviously transport squads should be always bigger, so only if the transport strength of both squads is equal, then the values should be tested.

                                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.

                                -Martin
                                Civ2 military advisor: "No complaints, Sir!"

                                Comment

                                Working...
                                X