Announcement

Collapse
No announcement yet.

Tracking my caravan routes... any ideas?

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

  • #16
    UI changes look nice, but the 'Sid Meier's Civilization IV' seems a bit distracting to me, I think I would remove it completely and just show more of the main map.

    Originally posted by JamisonP
    Another idea I just had was to stay with the specialist method, but just remove the code that displays that particular specialist in the screen. Before I attempt that, I'd like to do it the 'right' way though.
    I think that's the way to go.
    Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

    Comment


    • #17
      Be careful with using specialists or super specialists. There is a wonder that gives all specialists +2 culture per turn. Your superspecialists will get that bonus too.

      Roger Bacon

      Comment


      • #18
        Damn... I had just implemented the 'invisible' specialists and thought I had that aspect closed off... does the wonder give culture to just regular specialists or also to 'super specialists'... the ones that the great people settle as. I'm currently using the super specialists in my setup, but would be open to suggestions.

        EDIT: To answer my own question, yes... the sistine chapel does add culture to settled 'super specialists' also. Any ideas, other than deciding that the sistine chapels culturally enhance your food convoys?

        -Jamison

        Comment


        • #19
          Ok, current plan on this one... which will basically be a work-around to a work-around now. I'm thinking I'll create a second OUTGOING_CARAVAN and INCOMING_CARAVAN specialist... this time with -2 culture/turn. Then I check for the sistine chapel at the start of each turn and modify the specialists as needed.

          Before it's mentioned, I did consider the idea of catching the event when the chapel is built so I wouldn't have to check every round, but that's more trouble than it's worth, considering I'd have to track city captures, losses, razings, etc. to make sure I didn't leave in 'culture vacuum' specialists when the player didn't have the sistine chapel.

          I think I'm gonna put this code off for a bit and work on my caravan manager screen for now though, so if anyone has a better suggestion for this problem, go for it.

          EDIT: Looks like 4 versions of each specialist if I go this route...
          • Normal (+/- Food)
          • Sistine (+/- Food, -2culture)
          • Representation (+/- Food, -3beakers)
          • Sistine/Rep (+/- Food, -2culture, -3beakers)

          -Jamison

          Comment


          • #20
            Final note before I pass out... the list of specialists has increased... we now have:
            • INCOMING_CARAVAN (+2 food)
            • OUTGOING_CARAVAN (-3 food)
            • OUTGOING_CARAVAN_WITH_REFRIGERATION (-2 food)
            • SISTINE_CULTURE_DROP (-4 culture)
            • REPRESENTATION_BEAKER_DROP (-6 beakers)
            • SISTINE_AND_REPRESENTATION_DROP (-4 culture, -6 beakers)


            I think that should cover all my bases on correcting any modifier issues. Anyone see any oversights on my part?

            Also, the reason for -4 and -6 on the drops is to counter the +2/3 from the caravan and the +2/3 from the drop specialist itself. All I have to say is it's a good thing that making specific citizens invisible is easy.

            -Jamison

            Comment


            • #21
              Well, the main problem with going that way is your mod may not be compatible with other mods. Ie, if someone is using your mod with another one that affects culture (or something else) from specialists. Not really your problem, but it'd be nice if it could be avoided.

              Oh - Representative only adds 3 beakers per specialist, not 6 (only Scientists end up with 6 beakers, because they start with 3 already).

              Bh

              Comment


              • #22
                Bhuric: We're both right Representation gives all specialists +3 beakers. So in my situation, I need a specialist with -6 beakers to break even.

                ex.

                Before Rep: Caravan (+/- 0 beakers)

                After Rep: Caravan (+3 beakers from Rep) + Rep_Drop_Specialist (-6 beakers coded, +3 beakers from Rep) = net gain 0 beakers

                -Jamison

                Comment


                • #23
                  Oh, ok, I misunderstood how you were doing it.

                  Bh

                  Comment


                  • #24
                    Ok gurus of Python... I'm still working on this and trying to get the syntax down for everything. My current problem is in defining all of my nested variable structure within Python. If anyone could point me to some documentation on nested dictionaries, it would be appreciated. I'm using functions very similar to those posted by Locutus, but I need slightly more depth to my data storage, and I am having trouble defining and modifying these correctly.

                    Initial definition: caravans = {}

                    Information needed:

                    caravans['unit'][iUnitID]['Type'] as string
                    caravans['unit'][iUnitID]['OriginCity'] as integer
                    caravans['route'][iOriginCity][iDestinationCity]['Type'] as string
                    caravans['route'][iOriginCity][iDestinationCity]['Count'] as integer

                    Basically, I'm finding out just how used to VB I have become. I can't for the life of me figure out how to re-create an 'array of user defined types' as it would be defined in VB terms. Is there another way I should be approaching this data, or am I reasonably on the right track?

                    -Jamison

                    Comment


                    • #25
                      It's no more complicated than using multi-dimensional arrays in VB, if I remember those correctly (it's been a decade or so since I last coded in any form of Basic )

                      The important thing with data structures is to figure out exactly what data you need to store and what the best structure for storing it would be. In your case I'm a bit confused about what you're trying to do, but I'll try to interpret it as best as I can.

                      First off, while using different concepts such as routes and units as index for one dictionary is perfectly possible in Python, it's usually easier on a conceptual level to seperate them into two different dictionaries.

                      Also, I'm not sure what the difference between 'unit' and iUnitID in your code is. What kind of information are you trying to store? The type and origin city of every caravan unit and the type and count of every route? In that case you only need one of the two, either use the unit object or it's ID, not both.

                      In the code I posted above, the data structure I used was: {fromCity: {toCity: iNumRoutes}}. This basically translates as a 2-dimensional array.

                      E.g. {city0: {city1: 1}, city1: {city0: 2, city2: 3}, city2: {city1: 1}} translates as:

                      Code:
                      fr\to |	city0 |	city1 |	city2
                      ------+-------+-------+-------
                      city0 |	      |	1     |
                      city1 |	2     |       | 3
                      city2 |	      |	1     |
                      If you want to store type and origin city for every unit, as I think you're trying to do, what you need is a table:

                      Code:
                      unit	| type	  | origin
                      --------+---------+--------
                      unit0	| 'type1' | city0
                      unit1	| 'type2' | city1
                      unit2	| 'type1' | city2
                      The type-origin pairs are always the same and always contain data (contrary to my array above where cities where connected with some other cities but not all of them and not always the same ones). Such a fixed pairing is best represented by a tuple: (strType, originCity). You want to store this data for every unique unit, so your structure in Python would be: {unit: (strType, originCity)} (you could in theory also use a list of 3-element tuples (unit, strType, originCity), but the index of a dictionary guarantees you don't get doubles, in a list you have to check this manually). To get a specific value from this, use caravanUnitsDict[someUnit][0] to get the type, caravanUnitsDict[someUnit][1] to get the origin city.

                      Here 'unit' and 'someUnit' could be either unit objects or unit IDs, but unit objects would be preferable as unit IDs are not truely unique in Civ4: units of different civs can share the same ID. The same goes for cities as well BTW, but cities can be problematic when they change owner, it's best to use a tuple of map coordinates (iX, iY) to represent them.

                      The route info seems to be more similar to my original data structure for trade routes, but now you want to store 2 bits of info rather than 1, as with the units. It should look like this:

                      Code:
                      fr\to |	city0	   | city1      | city2
                      ------+------------+------------+------------
                      city0 |	           | 'type1', 1 |
                      city1 |	'type2', 2 |            |
                      city2 |	           |	        | 'type1', 1
                      The type-count pairs are basically a table inside the array, they are always the same, so again, best represented by a tuple: (strType, iCount). The 2-dimentional array is the same as the datastructure I used in my first post, so the data structure should be: {fromCity: {toCity: (strType, iCount)}}. To get specific data, use caravanRoutesDict[fromCity][toCity][0] and caravanRoutesDict[fromCity][toCity][1].

                      Of course, considering what I said above about using map coordinates, fromCity and toCity are actually tuples, so it would really look like this: {(iFromX, iFromY): {(iToX, iToY): (strType, iCount)}}. But if you just replace all city objects with (city.getX(), city.getY()) tuples as soon as you encounter real city objects you don't have to worry about that. Python lets you abstract from this, it doesn't care whether you use integers, tuples, objects or whatever else as index. (In the code I posted in my first post I already assumed that all the functions that have city arguments would get a tuple with coordinates as city argument -- if you read that code alone you don't even know exactly how the cities are represented, just that it is some form of representation of a city, whether object, ID, tuple or otherwise).

                      To improve readability of your code, it might be helpful to define at the start of your file a few constants that represent indices into your tuples. For example:

                      CARAVAN_TYPE = 0
                      CARAVAN_ORIGIN = 1
                      CARAVAN_COUNT = 1

                      Then caravanRoutesDict[fromCity][toCity][1] becomes caravanRoutesDict[fromCity][toCity][CARAVAN_COUNT] -- this is not required, but should make it easier to understand what's going on.

                      You won't easily find this kind of info in Python language tutorials and the like, these are basic and largely language-independent algorithms. If you want to learn more stuff like this you'd have to look for books on programming algorithms, not for language-specific guides (although many books use a specific language to be able to give examples of such algorithms). I'm not aware of any detailed online sources of such info, I'm not sure they exist. But I think/hope I gave you everything you need for now (dictionaries and tuples are the two most common data structures in Python, together with lists but those are basically very primitive and weak versions of dictionaries), and I'll gladly help you further if you need more help.
                      Last edited by Locutus; April 3, 2006, 09:10.
                      Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                      Comment


                      • #26
                        My caravan 'advisor' screen is coming together pretty well, but I'm having one major issue that I can't seem to figure out.

                        When creating a table to show each route (Origin, Destination, Food Sent, Waste, Food Received, Cost) I have a last column that has a 'Cancel Route' button. Each of these cancel buttons has the name 'CancelRouteA', 'CancelRouteB', etc. and I get the correct data when clicking on any of the images, but it only works for the first 9 items. Clicking on 'CancelRouteI' echos back 'CancelRouteI' as it's supposed to, but 'CancelRouteJ' doesn't do anything when clicked.

                        It may be important to mention that H is the last row displayed on the screen, I is the first that requires scrolling to reach.

                        Does anyone have any idea what would cause the action to only be called on the first 9 (A-I) buttons and not the rest?

                        EDIT: I've tested, and the problem is definately that only a certain number of rows after the initially visible rows will return anything on a click event. When I resized the table to check, I was able to get a response from the first 21 items in the list... 18 were visible on the screen before scrolling. I know that chances are noone would ever have more than 8 caravan routes to or from a single city, but I'd like the interface to be able to handle this nonetheless.

                        I've tried looking for other examples using this, but the only table I can find with a button in it is the domestic advisor screen, and that button is it's own widget type, so there's no checking on the code it calls when clicked.

                        -Jamison
                        Last edited by JamisonP; April 6, 2006, 00:49.

                        Comment


                        • #27
                          hi jamison! i think it´s a real cool thing you´re working on.
                          i have an egypt-scenario in mind with the fertile nile area with lots of food, but no resources and the desert area with gold to mine, but no food to support the pitmen. a food delivery would be necessary.

                          unfortunately, i lack the skills to give you any support, but moral back up.

                          so, carry on. i´d love to play it.
                          War and courage have done more great things than charity. Not your sympathy, but your bravery hath hitherto saved the victims.

                          Comment


                          • #28
                            Very Alpha version up for comments/criticism

                            After a nice, long learning curve I have an initial alpha release of my caravan mod ready for testing and comments. For those of you with python knowledge, please let me know if you see something that could have been done in a more efficient way. For those who dno't jump into the code, please let me know what could be done to improve the functionality of the mod.

                            Notes:
                            • Caravan units require 'The Wheel' to be built.
                            • Current cost is 1 hammer for caravan units... this is for testing purposes only, the actual cost will be increased later.
                            • If you have 100 food going from city A to city B, city B will grow very fast and city A will remain size 1... see the to-do list, as I'm looking to make a city unable to go negative due to caravans
                            • Route maintenance cost is determined by the distance between the two cities and then is doubled if there is no road/rail route built between the two cities.
                            • I am currently using the 'Great Merchant' unit for my caravans... if any modelers would like to make a covered wagon or something of the sort, it would be appreciated.
                            • This mod was made as a way to learn python... almost every function you see was either pasted and modified or derived from one of the following: Mercenaries Mod, Hungry Hungry Cities / Shepherd Mod, Action Buttons Mod, and SD-Toolkit.


                            Current To-do list:
                            • Move all strings to XML reference for the caravan interfaces
                            • Automatically reduce routes when a city shows negative food or production for a turn


                            Download Here: 'Caravan Mod' Alpha
                            Last edited by JamisonP; April 9, 2006, 04:39.

                            Comment


                            • #29
                              Screenshots

                              For your viewing pleasure...

                              The 'Caravan Manager' screen, accessible from an icon in the advisor bar at the top of the main interface, allows the player to view, modify, and delete caravan routes from their empire.


                              The city screen was reorganized slightly to make room for a new 'Caravan Routes' table in the left bar. Most noticably, the culture and nationality bars were moved to a new panel at the bottom of the interface.

                              Comment


                              • #30
                                Re: Very Alpha version up for comments/criticism

                                Originally posted by JamisonP


                                [*]If you have 100 food going from city A to city B, city B will grow very fast and city A will remain size 1... see the to-do list, as I'm looking to make a city unable to go negative due to caravans
                                Perhaps limiting it so that a caravan can only be built by a city when it has a food surplus? I don't know what would be needed to implement that though.
                                Those who live by the sword...get shot by those who live by the gun.

                                Comment

                                Working...
                                X