Announcement

Collapse
No announcement yet.

MapSquare Class OO discussion

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

  • MapSquare Class OO discussion

    The idea of this thread is to achieve concensus on an OO structure for the MapSquare class. F_Smith, can you post the variables for your existing class here also?

    Here is what I currently have in the MapSquare classes for the demo 4 + code. Because I was initially trying to be frugal with memory storage for each MapSquare there was a hierarchy of three types of MapSquare classes. The lowest is BaseMapSquare which can handle things like sea squares that don't require all the information that is required for land. Next highest is MapSquare which holds all the info necessary for a land square. The highest is PopSquare which is a MapSquare with population in it.

    Given what I've learned from F. Smith, it is probably foolish to have these three different levels of MapSquare. I will just put them one after the other, and the sum of all three is my guess the starting proposal for the new MapSquare class.

    The entire map is held in a class called TheMap which is simply a 2D array of BaseMapSquare. I strongly urge that we keep this structure intact, since substantial amounts of the existing code for AI, movement, and map graphics, relies on this 2d array being there.

    If you don't want to look at my abbreviated version, the complete Javadoc and source code are available in the thread Javadoc Documentation for current source / + current source code


    This stuff is not all self-explanatory. There's some things that relate to the AI, such as having different worlds (to test out strategies in a world that is divorced from the game world). If you are really having a hard time figuring out what something is, post a question and I'll try to answer it quickly.

    Also, where possible, I think we should keep the current variable names and structures unless there are big problems with them. Every change will potentially involve a lot of work. Please don't suggest a change unless you think the existing version is so bad that it will cause significant future problems.

    Code:
     /** BaseMapSquare is an individual square of the map and its characteristics.  
     *	BaseMapSquare provides routines used by all MapSquare classes, stores information about:
     *	1) Generic Terrain Types and Specific Value for This Square,
     *	2) Square Location, X and Y,
     *	3) Military TFs present...,
     *	4) Whether the Square Is Selected or Not, an Aid for the User Interface,
     *	5) Special resources are implemented at this level (eventually) to handle fishing...,
     *
     *	BaseMapSquare fully represents a sea or lake Square.  For a land square it is extended to 
     *	MapSquare if unpopulated, and PopSquare if populated.
    
    
     *
     *	Copyright 1999, the Clash of Civilizations Development Group
     *
     *	@author Mark Everson
     *	@version 0.3, Date: January 12 2000 
     */ 
    public class BaseMapSquare extends SerialCloneable implements Cloneable { 
     
    // Which world is the square in?  Defaults to 0, the main game world
    // Rather than have a whole new set of constructors for different worlds, when the World()
    // constructor is called it will  paste in the correct value.
    private byte worldIndex = 0;
    	
    /**  Describing whether a square is coastal, inland, etc  */
    private byte positionType = 0;
    /** Describes land squares around a littoral water square; so far just use 4 bits for
    	adjacent land to the North (1), East (2), South (4), and West (8); so a one-square lake = 15*/
    private byte oceanType = 0;
    protected byte terrain = OFF_MAP; // one of the terrain types, e.g. MapSquare.WATER
    private byte siteType = 0;// index pointing to position in econSitesArray that holds site information
    // Right now there is only one siteType for each terrain type, but I'm setting it up more
    // generally for future use
    private byte mapTile = 0; // map Tile numbers - not used currently
    
    protected int xLoc, yLoc; // absolute x and y coords of the square.
    
    private TF[] TFsHere; // the TFs know what civ they're from by TF.itsCiv
    private byte numTFsHere = 0;
    /** Is combat possible here this turn; used for assigning support forces to friendly TFs  */
    private boolean potentialCombat = false;
    /** Attacker for combat that will take place this turn, loaded in isTherePotentialCombatThisTurn()*/
    private Civ attackerCiv;
    /** Defender for combat that will take place this turn, loaded in isTherePotentialCombatThisTurn() */
    private Civ defenderCiv;
    
    private boolean selected; // for use in selecting squares on the map for various functions
    private boolean isTarget; // a second type of selection, currently not used
    
    **************************************************
    
    /**   MapSquare                                                                           
     * PopSquare at bottom of file extends MapSquare to cover populated squares that
     * don't belong to a civ
     * An individual land square of the map and its characteristics
     *
     * Copyright 1999, the Clash of Civilizations Development Group
     *
     * @Author Unknown
     * @Version 0.3 Date January 12 2000
     */
    public class MapSquare extends BaseMapSquare implements Cloneable {  
    	
    /** 1 in a bit means there's a river, all rivers flow to center of Sq
     *  N edge is 8x bit rotating clockwise (NESW) to
     *  W edge is 1x bit - River N&E -> riverPos = 12;	
     */
    private   byte riverPos = 0;
    /** [0] is N and it goes cw ([1] = NE etc...)
     * just because roadTo[x] is true doesn't mean there's a useable road
     * must check roadCondition[] value to determine existence and
     * quality
     */
    private     boolean[] roadTo; 
    /** None = 0, is for planned or destroyed roads */
    private     byte[] roadCondition; 
     
    /** MapSquare() constructor */
    public  MapSquare(){
    	// [0] is N and it goes cw ([1] = NE etc...)
    	roadTo = new boolean[8] ; 
    	// None = 0, is for planned or destroyed roads
    	// might have info, like the tiling used to display
    	// the road in future implementations
    	roadCondition = new byte[8] ; 
    }
    
    Copy
    /**   PopSquare                                                                           //
     * PopSquare extends MapSquare to cover populated squares 
     *
     * Copyright 1999, the Clash of Civilizations Development Group
     *
     * @Author Unknown
     * @Version 0.3 Date January 12 2000
     */
    public class PopSquare extends MapSquare implements Cloneable {
    /** the Province the square is associated with, if any */
    private Province prov; 
    /** city indicates whether the square is urban or not */
    private boolean city = false;
    /** used in multi-square province (MSP) bookkeeping, has to
     *  do with how developed this square is with respect to the average for the MSP
     *  no [0] similar to sector numbers [1] is diff for Farm, [5] is for Merch... */
    private float[] capDifference = null;
    /** Contains the population of the square population, 1 = 1000 people */
    private float pop;     
    /*  The defensive military capability of the inhabitants of the square */
    private float milPower = 0;
    /** Culture covers tech and society aspects of populated squares
    	there can be up to three cultures per popSquare */
    private Culture cultures[];
    /** culturepct that don't belong to a civ, culturePct keeps track of percent
     *  of population in each of three cultures if sum over culturePct less than 100
     *  the rest of the pop is a mixture of other cultures too small to keep track of */
    private byte culturePct[];
    /** nomad is the pop primarily nomadic or agricultural */
    private boolean nomad = false;
    	
    /** frontline is used if sq is part of a prov to determine if
     *  this square is directly exposed to potential hostilities */
    private boolean frontLine = false; 
    /** number of foreign squares adjacent
     * Specifically, number of adjacent land squares not controlled directly by us */
    private byte numForeignSqs = -1; 
    
    *******************************************************************
    
    And here is TheMap...
    
    /**
     * TheMap Holds a map (2D array of type BaseMapSquare) of the world for a particular World.
     * It functions mostly as just a container for map[][] after initialization which it handles.
     * Right now initialization is by reading in a world map from a save file format and performing
     * some modifications to the initial information.  For now there is no way to replace a square
     * with a different type directly, you're stuck with the map as it is.
     *
     * Date: 10/4/1999, Copyright 1999, the Clash of Civilizations Development Group
     *
     * @author Mark Everson
     * @Version 0.3 Date January 12 2000
     */
    public class TheMap{
    
    /** which world this is associated with */
    private int worldNumber;
    
    /** the detailed map  */
    private BaseMapSquare[][] map = new BaseMapSquare[mapLengthX][mapLengthY]; 
    // eventually earth map will be absorbed by this map
    
    /** makes an off-map square for various uses  */
    private static PopSquare zipMapSquare;
    /** position of upper left of map in earthMap, right now set so play occurs on Europe */
    private static Point smallMap00_Position_OnWorldMap;// 
    
    /** squares in map x dir  */
    private static final int mapLengthX = 70; // 
    /** squares in map y dir  */
    private static final int mapLengthY = 150;
    
    /** Map of Earth size 320x200 from an old game project called Antiquity  */
    private static short[][] earthMap = new short[320][200];
    
    private static short[][] earthMapRotated = new short[1000][700];
    
    private InputStream in; /*FileInputStream*/
    Project Lead for The Clash of Civilizations
    A Unique civ-like game that will feature low micromanagement, great AI, and a Detailed Government model including internal power struggles. Demo 8 available Now! (go to D8 thread at top of forum).
    Check it out at the Clash Web Site and Forum right here at Apolyton!

  • #2
    Excellent start, Mark:

    I'll work with this, think about it, then get back to you tonight.

    One thing off the top of my head, tho -- all the 'AI' copies of a mapsquare don't belong in the class. That should be done seperately.

    Each mapsquare only needs to know the info it'll need to do it's own methods.

    Comment


    • #3
      Mark:

      Here's the 'MapSquare' class in the beast --

      Now, this extends Canvas, which we may not want to do. But I think we will want it to have the code to draw itself, via whatever means necessary, so that we can easily redraw individual squares.

      The relevant data items are all listed at the top --

        [*]GameData -- a pointer to the game world database.[*]Name -- String name of the square (player defined).[*]Terrain -- a pointer to a 'terrain' object.[*]explored -- a boolean to indicate if the player has explored here yet.[*]selected_square -- a pointer to the square that is 'selected'.[*]controlling_civ -- a pointer to the 'civ' controlling it.[*]controlling prov -- a pointer to the 'prov' controlling it.[*]ethnic_groups -- a collection of pointers to all the ethnic_groups in the square.[*]task_forces -- a collection of pointers to all the 'task force' objects (military version of an EG) in the square.[*]zone integers -- several 'zone' values that likely should be handled as a single object. That part hasn't been designed yet.[*]x_loc and y_loc -- x and y location of the mapsquare.[*]observers -- a list of all GUI components that will need to be redrawn when the mapsquare data changes.[*]menu -- the popup menu that will be displayed on right-clicking this square.[*]pref_size -- for screen redraw, the optimal size to draw this square.[*]turn_handler -- a pointer to the 'turnhandler' object that will be called once per turn.[/list]

        There's getters and setters for all, which is how a mapsquare is built and used. The constructer requires a pointer to the gamedata database, and the x and y locatoin of the mapsquare. Then you setTerrain, addFoodZone, addEthnicGroup, that kind of thing.

        For use, there are all the necessary getters. There are methods for getting the total pop (it just adds up the pop from all the EGs contained within), terrain, controlling_civ, etc.

        Now the big question is this --

        Clear your mind of any previous thoughts, any other models. Answer this question cold, with a 'beginners mind'.

          [*]What other information is contained within a square location of land that would have an effect on gameplay?[/list]


          What do I still need to add?




          Code:
          import java.awt.*;
          import java.awt.event.*;
          import java.util.*;
          
          public class MapSquare extends Canvas
          {    
              private GameData data;
              
              private String name = "Wild Countryside";
              private Terrain terrain;
              
              private boolean explored;
              static private MapSquare selected_square;
              private boolean selected;
              
              private Civilization controlling_civ;
              private Province controlling_prov;
              
              private Vector ethnic_groups;
              private Vector task_forces;
              
              private int food_zones;
              private int raw_materials_zones;
              private int production_zones;
              private int services_zones;
              private int special_materials_zones;
              
              private int x_loc;
              private int y_loc;
              
              private Vector observers;   
              
              private PopupMenu menu;
              private Dimension pref_size;
              
              private TurnHandler turn_handler;
              
              public MapSquare(GameData d, int x, int y)
              {
                  data = d;
                  initData(x, y);
              }
              
              private void initData(int x, int y)
              {
                  explored = true;
                  pref_size = new Dimension(50, 50);
                  
                  ethnic_groups = new Vector();
                  task_forces   = new Vector();
                  
                  observers = new Vector();
              
                  x_loc = x;
                  y_loc = y;
                  
                  setTurnHandler(new MapSquareTurnHandler(this));
                  
                  addMouseListener(new MouseAdapter()
                                      {
                                          public void mouseClicked(MouseEvent evt)
                                          {
                                              select();
                                              
                                              if(hasTaskForces())
                                              {                                        
                                                  TaskForce t = (TaskForce)task_forces.elementAt(0);
                                                  
                                                  if(evt.getClickCount() == 2)
                                                  {                                            
                                                      t.issueOrders();
                                                      setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
                                                  }
                                                  else
                                                  {
                                                      setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                                                  }
                                              }
                                          }
                                      }
                                  );
                                  
                  updateView();
              }
              
              public void updateView()
              {        
                  if(hasTaskForces())
                  {
                      TaskForce tf = (TaskForce)task_forces.elementAt(0);
                      addPopup(tf.getDetailPopup());
                  }
                  else
                      addPopup(getDetailPopup());    
              }
              
              public void addPopup(PopupMenu m)
              {
                  menu = m;
                  add(menu);
              }    
              
              public void processMouseEvent(MouseEvent evt)
              {
                  if((menu != null) && (evt.isPopupTrigger()))
                  {
                      if(hasTaskForces())
                      {
                          Enumeration enum = getAllTaskForces();
                          
                          TaskForce tf = (TaskForce)enum.nextElement();
                          
                          addPopup(tf.getDetailPopup());
                      }
                      else
                      {
                          addPopup(getDetailPopup());
                      }            
                      
                      menu.show(this, evt.getX(), evt.getY());            
                  }
                  else
                      super.processMouseEvent(evt);
              }
              
              public void setName(String n)
              {
                  name = n;
              }
              
              public String getName()
              {
                  return name;
              }
              
              public void setTurnHandler(TurnHandler t)
              {
                  turn_handler = t;
              }
              
              public TurnHandler getTurnHandler()
              {
                  return turn_handler;
              }
              
              public void addEthnicGroup(EthnicGroup g)
              {
                  g.setLocation(this);
                  ethnic_groups.addElement(g);
                  repaint();
                  notifyObservers(g);
              }
              
              public void loadEGVector(Vector eg)
              {
                  Enumeration enum = eg.elements();
                  
                  while(enum.hasMoreElements())
                  {
                      EthnicGroup g = (EthnicGroup)enum.nextElement();
                      
                      addEthnicGroup(g);
                  }
              }
              
              public EthnicGroup getEthnicGroup(String n)
              {
                  Enumeration enum = ethnic_groups.elements();
                  
                  while(enum.hasMoreElements())
                  {
                      EthnicGroup grp = (EthnicGroup)enum.nextElement();
                      
                      if(grp.getNationality().equals(n))
                          return grp;
                  }
                  
                  return null;
              }    
              
              public Enumeration getAllEthnicGroups()
              {
                  return ethnic_groups.elements();
              }
                  
              public Demographics getDemographics()
              {
                  Demographics d = new Demographics();
                  
                  int uc = 0;
                  int mc = 0;
                  int lc = 0;
                  int sl = 0;
                  
                  Enumeration enum = getAllEthnicGroups();
                  
                  while(enum.hasMoreElements())
                  {
                      EthnicGroup eg = (EthnicGroup)enum.nextElement();
                      
                      Demographics eg_demo = eg.getDemographics();
                      
                      uc += eg_demo.getUC();
                      mc += eg_demo.getMC();
                      lc += eg_demo.getLC();
                      sl += eg_demo.getSlaves();
                  }
                  
                  return d;
              }
                  
              public void addTaskForce(TaskForce t)
              {
                  task_forces.addElement(t);
                  t.setLocation(this);
                  // updateView();
              }
              
              public void removeTaskForce(TaskForce t)
              {
                  int index = task_forces.indexOf(t);
                  task_forces.removeElementAt(index);
                  updateView();
              }
              
              public Enumeration getAllTaskForces()
              {
                  return task_forces.elements();
              }
              
              public boolean hasTaskForces()
              {
                  return !task_forces.isEmpty();
              }
              
              public int getPop()
              {
                  int pop = 0;
                  
                  Enumeration enum = ethnic_groups.elements();
                  
                  while(enum.hasMoreElements())
                  {
                      EthnicGroup eg = (EthnicGroup)enum.nextElement();
                      
                      pop += eg.getPopulation();
                  }
                  
                  return pop;
              }
              
              public void addFoodZones(int n)
              {
                  food_zones += n;
              }
              
              public void setFoodZones(int n)
              {
                  food_zones = n;        
              }
              
              public void removeFoodZones(int n)
              {
                  food_zones -= n;
                  
                  if(food_zones < 0)
                      food_zones = 0;
              }
              
              public int getFoodZones()
              {
                  return food_zones;
              }
              
              public int getSoilQuality()
              {
                  return terrain.getSoilQuality();
              }
              
              public void setLocation(int x, int y)
              {
                  x_loc = x;
                  y_loc = y;        
              }
              
              public int getXLoc()
              {
                  return x_loc;
              }
              
              public int getYLoc()
              {
                  return y_loc;
              }
              
              public boolean isPopulated()
              {
                  return !ethnic_groups.isEmpty();
              }
              
              public void setControllingCiv(Civilization c)
              {
                  controlling_civ = c;
              }
              
              public Civilization getControllingCiv()
              {
                  return controlling_civ;
              }
              
              public void setControllingProv(Province p)
              {
                  controlling_prov = p;
              }
              
              public Province getControllingProv()
              {
                  return controlling_prov;
              }
              
              public boolean isControlled()
              {
                  if(controlling_civ == null)
                      return false;
                  
                  return true;
              }
              
              public void select()
              {
                  
                  if(selected_square != this)
                  {
                      if(selected_square != null)
                          selected_square.unselect();
                  
                      selected = true;
                      
                      selected_square = this;
                      
                      notifyObservers(this);
                  }
                  
                  repaint();
              }
              
              public void unselect()
              {
                  selected = false;
                  notifyObservers("unselected");
                  repaint();
              }
              
              public void setTerrain(Terrain t)
              {
                  terrain = t;
                  terrain.initZones(this);
                  setBackground(terrain.getColor());
              }
              
              public String getTerrain()
              {
                  return terrain.toString();
              }
              
              
              public PopupMenu getDetailPopup()
              {   
                  PopupMenu menu = null;
                  
                  if(hasTaskForces())
                  {
                      Enumeration enum = getAllTaskForces();
                      
                      TaskForce tf = (TaskForce)enum.nextElement();
                      
                      menu = tf.getDetailPopup();
                  }
                  else
                  {
                      menu = new PopupMenu("Square");
                          
                      menu.add(new MenuItem("Food"));
                      menu.add(new MenuItem("Raw Materials"));
                      menu.add(new MenuItem("Finished Goods"));
                      menu.add(new MenuItem("Services"));
                      menu.addActionListener(new ActionListener()
                                                  {
                                                      public void actionPerformed(ActionEvent evt)
                                                      {
                                                          String cmd = evt.getActionCommand();
                                                              
                                                          if(cmd.equals("Food"))
                                                          {
                                                              foodCommand();
                                                          }
                                                      }
                                                  }
                                          );
                  }
                  
                  return menu;
              }
              
              public void foodCommand()
              {
                  new FoodDetailDialog(new Frame(), this);
              }
              
              public void paint(Graphics g)
              {
                  update(g);
              }
              
              public void update(Graphics g)
              {     
                  Dimension d = getSize();
                          
                  Dimension off_dimension = getSize();;
                  Image off_image = createImage(d.width, d.height);
                  
                  if(off_image != null)
                  {
                      Graphics off_graphics = off_image.getGraphics();
                      
                      int h = (int)d.height;
                      int w = (int)d.width;        
                                  
                      if(explored)
                      {
                          if(selected)      
                              setBackground(Color.pink);
                          else
                              setBackground(terrain.getColor());
                              
                          drawTerrain(off_graphics, h);
                      
                          if(hasTaskForces())
                              drawTaskForce(off_graphics, h, w);
                          else
                          if(isPopulated())
                              drawPopulation(off_graphics, h, w);
                          
                          if(isControlled())
                              drawCivMask(off_graphics, h, w);
                          else
                          if(data.isGridOn())
                              drawGrid(off_graphics, h, w);
                              
                      }
                      
                      g.drawImage(off_image, 0, 0, this);
                  }       
              }   
              
              public void drawTaskForce(Graphics off_graphics, int h, int w)
              {
                  off_graphics.setColor(Color.black);
                  TaskForce t = (TaskForce)task_forces.elementAt(0);
                  
                  int n = t.getNumOfMen()/100;
                  
                  int x = 10;
                  int y = 10;
                  
                  for(int i=0; i
          

      Comment


      • #4
        Hi F:

        First off, it's good to have this going. Let's see...

        I do strongly object to MapSquare extending Canvas. I think you know that you are badly mixing different parts of the MVC paradigm . And even I have this part right in the demo 4 code! You don't want to be taking steps backwards do you? Same comment goes for all the other GUI-type stuff you currently have in MapSquare. So I guess my proposal is you need a MapSquareView class or something and point to it from MapSquare.

        On to other things, first thoughts about what you have included already ...

        Personally I think it is silly to have every single object in the game have a pointer to GameData. You know more than me about these things, but it seems more rational to have a static method in GameData that can give the pointer to the game data instance associated with the player. But it's your code, so my feelings are not nearly as strong as about the MVC point.

        Just for the record, I think there should be more than one level of whether a square has been explored or not. In Clash one should be able to learn about squares without actually trudging a military unit through them. But that is just a detail here.

        Additional stuff that needs to be in there. Most of these are already covered above, so I will just use one word or so to indicate them. I am not clearing my mind for this, I am just referring to what is above so you don't miss it.

        Roads, railways, rivers, canals... or do you envision this in Terrain?

        There are a lot of things we need for AI support at the square level. These are things like my variable positionType that describes whether a square is coastal, inland, etc.. There are six or seven things like that in total in the stuff I described above. If you want to keep these out of the MapSquare object itself, that is perfectly understandable. But then we will need to add a unique object for each MapSquare that is an AI helper for MapSquare that each MapSquare will have a pointer to.

        You need a pointer for an economy object in each MapSquare. Right now in the demo 4 code this is called EconStub because it can either be a limited amount of information, or point to a full-fledged Economy object.

        There is a possibility that we will need some support in MapSquare for the ticks system of military movement. This is to ensure that two units that "swap squares" and move on the same tick can't teleport over each other when in reality they would meet. We can probably handle this when we talk about the military stuff.

        Possibly we need military infrastructure such as walls and fortifications. Do you think this should go with the square itself, or be accessed through an infrastructure object that belongs to the economy object of the MapSquare?

        I can't come up with anything truly new to put into this object. Then again I have been thinking about this for years, so it's probably not too surprising. I am assuming all the economic sites stuff both in terms of potential sites, and sites actually usable at current technology, will be contained in the terrain object. So we need to talk about that soon also.

        Oh, one other thing. People have mentioned that in terms of flexibility we may want to have different levels to the terrain like in CTP. So you may need X, Y, and Z info for each square to allow for this flexibility.

        Project Lead for The Clash of Civilizations
        A Unique civ-like game that will feature low micromanagement, great AI, and a Detailed Government model including internal power struggles. Demo 8 available Now! (go to D8 thread at top of forum).
        Check it out at the Clash Web Site and Forum right here at Apolyton!

        Comment


        • #5
          I agree that we should have the ability to make multiple maps like underworld, surface, and sky. That provides a lot of flexibility.

          Is it feasable to include the ability to create the cube world I discussed earlier? It has six maps with certain rules for joining at the edges. For more description, see my original post.
          [This message has been edited by Richard Bruns (edited September 24, 2000).]

          Comment


          • #6
            Mark:

            Actually, the 'M-V-C' architecture requires data objects to draw themselves. In fact, OO requires that objects do all their own work. It's the GUI components that will display the object that belongs in the 'View' code.

            We don't absolutely have to do this that way, but I'll show you an example of it in action and why the architecture is designed that way. It simplifies the code a lot.

            As far as using a 'global' GameData object -- it's consider very bad form to use Global variables. We can do it that way, but I'd rather not.

            I agree with you about the 'explored' boolean. There should be more booleans.

            'Roads', 'Railways' and 'Canals' are 'infrastructure' objects, which I was thinking would be held in 'Terrain' -- altho that's what we're here to work thru.

            'River' absolutely belongs in 'terrain'. In fact, the 'Terrain' object will also hold all that info you want for AI (and more, I think).

            An 'Economy' data object certainly belongs somewhere in all this. Altho I'm not sure of the object hierarchy. Haven't thought it thru. We'll have to do an analysis.

            For the military tick support, I'm not sure I understand what needs to be here. We should talk about that.

            Again, for walls and fortifications those will be 'infrastructure' objects like roads, etc, and I was initially thinking that they belong to the terrain. We'll go thru the 'terrain' object analysis next, so this won't have to wait long for discussion.

            You're absolutely correct, I should have a 'z_loc' for height above sea level. Will do.

            For multiple layers (sky, space and underground/underwater), I would want to use a different object and a seperate collection, instead of containing all the info in that square object.




            Richard:

            I'll look at your post when I get a chance. If it's feasible, I'll make it happen. One of the rules of XP is that when asked to include functionality, the programmer must always say "yes, I can do that"!

            Comment


            • #7
              Mark:

              A quick note -- for an excellent example of how the 'M-V-C' architecture works, check out the Swing components 'JTable', 'JList', 'JTree', etc.

              I'll go over 'JTable' real quick.

              You have the 'view' component, 'JTable'. It's only purpose is to contain a 'TableModel' object and display that object.

              Then you have the 'data' component -- 'TableModel' (you extend 'AbstractTableModel'). It contains all the code on how specifically it will be rendered -- the number of columns, the number of rows, the info on how those rows and columns will be rendered ('CellRenderer' objects).

              Does that explain it?

              The biggest bonus to using this 'M-V-C' approach is that the 'view' object never has to be altered. When the data in the 'data' object changes, the 'data' object redraws itself.

              Comment


              • #8
                Are you planning on considering Beör's proposal regarding "Habitat" objects? I really think that it could be good. The natural landscape would be kept in "Terrain" mapsquares, and all the populated stuff could be the "Habitat" mapsquares. Creating that distinction could give us lots of flexibility.

                quote:


                One of the rules of XP is that when asked to include functionality, the programmer must always say "yes, I can do that"!


                [Darth Vader Voice]
                I have you now!
                [/Vader Voice]

                Could you add the functionality of Beör's proposal?

                Comment


                • #9
                  Hmmm... I didn't like much the Habitat idea. Can we discuss it some more before taking this coding step with Habitats?

                  Comment


                  • #10
                    If we don't like it we can shut it off and revert to the standard way. It would only be an option. Even if it is not standard, it could be a scenario design tool.

                    At least, that was my impression of the flexibility of OO. Is that correct, or am I confused again?

                    Comment


                    • #11
                      Only discussing map issues (immobile habitats), I think the habitat idea could be incorporated seemlessly. You would have exactly the same functionality, with the option of adding a little more at a later stage. I don't even think the programming would be very hard. It might take some decisions as to whether the habitat is really derived from a more basic infrastructure object being able to contain population, which again could be a derivative of the basic infrastructure object, only having a slot for the basic infrastructure action (object in, transform, object out)

                      If on the other hand we are talking about extending the concept to include mobile habitats this would change the entire object model, particularly the military unit and related parts
                      Civilisation means European civilisation. there is no other...
                      (Mustafa Kemal Pasha)

                      Comment


                      • #12
                        Guys:

                        If you want the game logic to work that way, that's an easy thing to include as an option.

                        But if you want the game architecture to work that way, that's not an easy option.

                        And as an architecture, this seems to be very complex for no added functionality -- in fact, it would remove functionality that is necessary for the game. The existing architecture can produce these results.

                        Comment


                        • #13
                          I don't understand

                          I just think, as a game designer, that infrastructure should not be tied to a certain mapsquare. How does it couse problems to model tham as part of a "habitat" rather than part of the mapsquare?

                          Note: I do not ask these questions to be mean or try to tell people wat to do. I ask questions because I want to learn about something.

                          Comment


                          • #14
                            Not knowing Java makes it a little difficult to comment, but I'll give it a shot.

                            1. Could someone please give a brief explanation of what's in game world database.

                            2. 'Extending canvas' - If I need to understand this please explain.

                            3. Same goes for MVC.

                            4. Why track both the controlling province and the controlling civ? I should think that having access to the province would yield the civ.

                            5. Are mapsquares still stored in a two-dimensional array as in demo4?

                            6. Are all military units taskforces here?

                            7. It seems that most of the interesting stuff (infrastructure) could go in the terrain object. However, I think it is likely that we will have infrastructure objects that are not part of task forces, but still resemble military units by being able to move (fishing fleets again). I would think it more intuitive to keep infrastructure of all sorts in the mapsquare object itself with EGs and military units (it has been argued that military units are infrastructure objects, which makes sense given the way they are produced via the infrastructure model). If you have military units in the mapsquare it would also make most sense to have their encampments and fortifications here. You might even have military units possessing/carying infrastructure.
                            The terrain object would then only be concerned with the physical characteristics of the square itself. Of course the distinction between infrastructure and terrain is not a clear one: Roads, canals and rivers have features of both. Since roads and canals can be constructed I would probably place them in the mapsquare, and since I see no difference between a canal and a river (except that the latter cannot be constructed) I would probably opt for including rivers in the mapsquare as well.

                            8. I brought this up in another thread as well: Someone please explain the status of sites. What are they, infrastructure or terrain or something else. Mark mentioned somewhere that it was the intention to make it possible to construct sites, as if they were some kind of infrastructure. Will there be a maximum number of sites available at maximum tech level? Another possibility is to have 'tagged' sites. When you reach a particular tech level you could enable x food sites, which could then be exploited.

                            I don't think we lack anything, but we should decide what goes where. If y'all think that the infrastructure vector should be placed in the terrain-object I have no objections (I think ;, and even if I had, it would probably not make a big difference )), so let's decide and move on to the terrain object.
                            Civilisation means European civilisation. there is no other...
                            (Mustafa Kemal Pasha)

                            Comment


                            • #15
                              Please disregard the queries pertaining to sites. I think we have that going in another thread.
                              Civilisation means European civilisation. there is no other...
                              (Mustafa Kemal Pasha)

                              Comment

                              Working...
                              X