You can subscribe to this list here.
2005 |
Jan
|
Feb
(25) |
Mar
(84) |
Apr
(76) |
May
(25) |
Jun
(1) |
Jul
(28) |
Aug
(23) |
Sep
(50) |
Oct
(46) |
Nov
(65) |
Dec
(76) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(60) |
Feb
(33) |
Mar
(4) |
Apr
(17) |
May
(16) |
Jun
(18) |
Jul
(131) |
Aug
(11) |
Sep
(1) |
Oct
|
Nov
(1) |
Dec
(5) |
2007 |
Jan
(71) |
Feb
|
Mar
|
Apr
|
May
(6) |
Jun
(19) |
Jul
(40) |
Aug
(38) |
Sep
(7) |
Oct
(58) |
Nov
|
Dec
(10) |
2008 |
Jan
(17) |
Feb
(27) |
Mar
(12) |
Apr
(1) |
May
(50) |
Jun
(10) |
Jul
|
Aug
(15) |
Sep
(24) |
Oct
(64) |
Nov
(115) |
Dec
(47) |
2009 |
Jan
(30) |
Feb
(1) |
Mar
|
Apr
|
May
(2) |
Jun
|
Jul
(5) |
Aug
|
Sep
|
Oct
(4) |
Nov
(132) |
Dec
(93) |
2010 |
Jan
(266) |
Feb
(120) |
Mar
(168) |
Apr
(127) |
May
(83) |
Jun
(93) |
Jul
(77) |
Aug
(77) |
Sep
(86) |
Oct
(30) |
Nov
(4) |
Dec
(22) |
2011 |
Jan
(48) |
Feb
(81) |
Mar
(198) |
Apr
(174) |
May
(72) |
Jun
(101) |
Jul
(236) |
Aug
(144) |
Sep
(54) |
Oct
(132) |
Nov
(94) |
Dec
(111) |
2012 |
Jan
(135) |
Feb
(166) |
Mar
(86) |
Apr
(85) |
May
(137) |
Jun
(83) |
Jul
(54) |
Aug
(29) |
Sep
(49) |
Oct
(37) |
Nov
(8) |
Dec
(6) |
2013 |
Jan
(2) |
Feb
|
Mar
(1) |
Apr
(14) |
May
(5) |
Jun
(15) |
Jul
|
Aug
(38) |
Sep
(44) |
Oct
(45) |
Nov
(40) |
Dec
(23) |
2014 |
Jan
(22) |
Feb
(63) |
Mar
(43) |
Apr
(60) |
May
(10) |
Jun
(5) |
Jul
(13) |
Aug
(57) |
Sep
(36) |
Oct
(2) |
Nov
(30) |
Dec
(27) |
2015 |
Jan
(5) |
Feb
(2) |
Mar
(14) |
Apr
(3) |
May
|
Jun
(3) |
Jul
(10) |
Aug
(63) |
Sep
(31) |
Oct
(26) |
Nov
(11) |
Dec
(6) |
2016 |
Jan
|
Feb
(11) |
Mar
|
Apr
|
May
(1) |
Jun
(16) |
Jul
|
Aug
(4) |
Sep
|
Oct
(1) |
Nov
(4) |
Dec
(1) |
2017 |
Jan
(2) |
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
(20) |
Jul
(4) |
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(6) |
Nov
|
Dec
|
2019 |
Jan
|
Feb
|
Mar
|
Apr
(10) |
May
(10) |
Jun
(1) |
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2020 |
Jan
|
Feb
|
Mar
(3) |
Apr
(9) |
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(7) |
Dec
(4) |
2021 |
Jan
(5) |
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Brett L. <wak...@ea...> - 2005-03-04 17:18:51
|
>Although I could do many things (including buying a Swing book >and see how to make a stand-alone UI for the StockMarket >rather than my current servlet) I prefer to first redo the low-level >stuff I've done before, and perhaps add some functionality, >taking into account all the lessons I've learned so far. >Apologies to the servlet-runner-deprived. Try to go with the model/view design approach. For testability, toString() for the company markers on the stockmarket= should be defined to return their current position on the stockmarket. Returning a string that includes= position, value, and color is optional, but ideal. Being able to craft some quick test cases for moving the marker around and= checking the results via console is the first end-goal for the stockmarket class. I'll try to turn my swing demo into a more useful class that actually makes= use of the stockmarket objects. >1. In theory we might be able to make one StockMarket class that can >handle all varieties (linear, rectangular and hexagonal) >but I think we can better split up into generic and special classes. As was mentioned before, linear is just rectangular with a single row. No= special class needed there. >Hexagonal is rare (I believe 1837 only) so it's special anyway. >We might also consider linear stockmarkets special, because >so few games have it (AFAIK only the Tresham games and 1860). I wouldn't focus too much on getting a hexagonal stockmarket working just= yet. So long as the generic class is capable of allowing implementation of these later, that's fine. Because the standard rectangular markets are the most common, that should= be the focus of our current efforts and the first thing we get working. >5. The above applies both to StockMarket and StockChart. >In hindsight I think splitting these was not a very good idea, >because we might end up duplicating the whole class/interface structure. I agree. The naming is ambiguous. >6. Special subclasses might need additional or different XML entries. >I suppose that the XML DTD may become game-specific too in some cases. That's fine. I think the expectation from the beginning was that the XML= was to be game-specific. >This class will have the methods currently in StockMarket and StockChart. >Later on we can write subclasses like StockMarketLinear, StockMarket1837 >and perhaps other ones, that will override methods like payOut() >and can contain any special stuff. Yes. Though, I'd call it StockMarketHexagonal. I hesitate to reference= specific games within the class and method naming. >4. If I have time, _and_ get good advice on a replacement, I might replace >the SAX parser. >I'm somewhat concerned, though, that we will end up having the XML file >contents >in memory twice: once in the DOM object, and once in the class attributes >(organised as suits the class best). Is this a valid concern? I wouldn't set the priority on doing this very high. We can always change= it later. My primary concern is getting a working stockmarket. ---Brett. |
From: Iain A. <ia...@co...> - 2005-03-03 23:47:04
|
I also hope to have some time over the weekend to actually write some code, in the meantime a few points for Erik: Using DOM does mean that you do have the document in memory twice for a short period of time, however the DOM version can be discarded and garbage collected once its contents have been read. Since we are having multiple config files (one per component), only one at a time will need to be in memory twice, and the files are going to be pretty small anyway. I hope to provide some XML reading utility code to help this get moving. You are almost correct about the singleton pattern usage, don't jump in on that yet, I'll post more details in the next couple of days about how to do this right (just don't have time today, I'm afraid). Linear stock markets are a special case of two dimensional rectangular ones: they just have exactly one row. I don't think rectangular AND hexagonal is that hard to do; again I'll try and post more on this in the next few days. Iain. |
From: Erik V. <eri...@hc...> - 2005-03-03 21:07:25
|
Coming weekend I expect to have time to churn out some more or some better code, and I would like (this time for once) to submit my plan for review. Let me start by expressing my appreciation for the positive and fruitful way in which the discussions are held here. I hope the below may also show that we really are making progress. Although I could do many things (including buying a Swing book and see how to make a stand-alone UI for the StockMarket rather than my current servlet) I prefer to first redo the low-level stuff I've done before, and perhaps add some functionality, taking into account all the lessons I've learned so far. Apologies to the servlet-runner-deprived. First some considerations: 1. In theory we might be able to make one StockMarket class that can handle all varieties (linear, rectangular and hexagonal) but I think we can better split up into generic and special classes. Hexagonal is rare (I believe 1837 only) so it's special anyway. We might also consider linear stockmarkets special, because so few games have it (AFAIK only the Tresham games and 1860). I'm not sure yet if we need an abstract superclass, or just a generic one with built-in handling of rectangular stockmarkets; we'll see. (Yes, I will mention interfaces below). 2. StockMarket is a singleton and should IMO be constructed as such. This means: private constructors, access only via a static get() method that returns the one instance (which is created the first time, or from a static init block). In addition to safety, this removes the need to pass around object variables, as each class needing access to the stockmarket object can get it immediately by calling StockMarket.get(). 3. The single instance generated will be of a type defined in the XML config file. That class will then be instantiated by a class factory (not sure how classloaders work in a stand-alone program - on this aspect I have worked with servlets under Tomcat only: a nightmare, but finally solved). 4. The return type of the get() should obviously be an interface type. 5. The above applies both to StockMarket and StockChart. In hindsight I think splitting these was not a very good idea, because we might end up duplicating the whole class/interface structure. 6. Special subclasses might need additional or different XML entries. I suppose that the XML DTD may become game-specific too in some cases. The plan: 1. Recombine StockMarket and StockChart. Some or all StockChart methods become private. 2. Create an interface named StockMarket, defining the same methods that we now have in the same-named class. 3. Create a base implementation class StockMarketGeneric, handling rectangular markets. This class will have the methods currently in StockMarket and StockChart. Later on we can write subclasses like StockMarketLinear, StockMarket1837 and perhaps other ones, that will override methods like payOut() and can contain any special stuff. 3. The XML stockmarket opening tag will define the class to be instantiated, like <stockmarket class="StockMarketLinear">, the default being StockMarketGeneric. 4. If I have time, _and_ get good advice on a replacement, I might replace the SAX parser. I'm somewhat concerned, though, that we will end up having the XML file contents in memory twice: once in the DOM object, and once in the class attributes (organised as suits the class best). Is this a valid concern? Enough for today. Have fun. Erik. |
From: Stewart T. <wsr...@ho...> - 2005-03-03 11:26:14
|
Brett, If you regard all of the "classes" on the domain object model as being implemented as Java "interfaces", with a separate implementation class (or more than one!) then you'll be well on the way to achieving the independence suggested. In practical terms method parameters and returns for non simple data types are expressed with the Interface name rather than the Class name. Stewart >From: "Brett Lentz" <wak...@ea...> >Reply-To: rai...@li... >To: rai...@li... >Subject: Re: [Rails-devel] Java style point >Date: Wed, 02 Mar 2005 18:04:53 -0800 > >I think this is a good direction to take. > >Are you able to submit some code to move us in that direction? > > >---Brett. > >*********** REPLY SEPARATOR *********** > >On 3/2/2005 at 10:12 PM Iain Adams using ia...@co... >declared: > > >I suggested in a previous post using interfaces for primary datatype > >definitions: one example of how this is done can be found in the Java > >Collections framework. Here List is an interface which has a number of > >implementation classes, which differ in their internal representations: > >ArrayList LinkedList, etc. StockMarket.getIpoPile() has a return type of > >ArrayList - this class should be free to change its list representation > >without an API change, which can be achieved by declaring the method to > >return a List. Personally, I would also make the member variable ipoPile >be > >type List, and initialise it as a 'new ArrayList()' in the first >instance. > > > >Iain. > > > > > > > >------------------------------------------------------- > >SF email is sponsored by - The IT Product Guide > >Read honest & candid reviews on hundreds of IT Products from real users. > >Discover which products truly live up to the hype. Start reading now. > >http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > >_______________________________________________ > >Rails-devel mailing list > >Rai...@li... > >https://lists.sourceforge.net/lists/listinfo/rails-devel > > >********** REPLY SEPARATOR END ********** >This message sent with 100% recycled electrons. > > > >------------------------------------------------------- >SF email is sponsored by - The IT Product Guide >Read honest & candid reviews on hundreds of IT Products from real users. >Discover which products truly live up to the hype. Start reading now. >http://ads.osdn.com/?ad_ide95&alloc_id396&op=click >_______________________________________________ >Rails-devel mailing list >Rai...@li... >https://lists.sourceforge.net/lists/listinfo/rails-devel |
From: Stewart T. <wsr...@ho...> - 2005-03-03 11:14:13
|
> > > The revenue generated by a city can also be held as a > > property of the tile - just as it is in the physical game set. > >Disagree. > >_City_ should be an object itself with a property _revenue_. > >The tile contains an array of these _city_-objects (max. 6: London >1829/25?) and each _city_ has to be related to the _connections_ the >tile provides. >As you can see on tile #37 (1829 1825R1/R2) there is one connection >going through without hitting a city and there are two connections >ending up in a city. > >Another property could be an array of stations, each capable of >holding 1 company-token. If all stations are filled, the city is >blocked for other companies. I believe that a flattened representation of cities and revenues in a Tile object can meet all of these requirements equally well. The combination of DisjointCityLocation and Tile can represent these relationships. The physical game system doesn't require separate cities from tiles, we should think carefully before deciding to represent cities as separate objects and be convinced that they will bring value to the software. I agree that this is a denormalised view of the data involved, and many relational database designers would throw up their hands in horror at this failure to enforce 3rd normal form! The track connectivity is an independent issue from the presence or absence of cities, and has to be solved for all tiles. I think that tiles with large cities (those that can take tokens) have two orthogonal characteristics: 1) disjoint - where separate cities exist with different track connections, and possibly different revenues. 2) variable capacity - where there is just a single (conceptual) city that can take multiple tokens, but the connectivity is the same for each token. IIRC, 1837 has a couple of tiles that combine both characteristics. That is, a tile where there are disjoint cities with a capacity greater than one token. Stewart |
From: CB C. <chr...@co...> - 2005-03-03 09:53:47
|
> The revenue generated by a city can also be held as a > property of the tile - just as it is in the physical game set. Disagree. _City_ should be an object itself with a property _revenue_. The tile contains an array of these _city_-objects (max. 6: London 1829/25?) and each _city_ has to be related to the _connections_ the tile provides. As you can see on tile #37 (1829 1825R1/R2) there is one connection going through without hitting a city and there are two connections ending up in a city. Another property could be an array of stations, each capable of holding 1 company-token. If all stations are filled, the city is blocked for other companies. |
From: John D. G. <jd...@di...> - 2005-03-03 08:35:55
|
>>I don't know 2038 and I doubt if we should include it in our project. >>But if so, should that "private" then not be classified as a "minor >>company"? > Technically it IS an 18xx-style game, but it deviates in a lot of ways > from your standard 18xx game. One big example is that all the tiles are > randomly chosen, then the player selects where he wants to place the tile. Not quite. You choose a hex in which to play a tile, then draw a tile. (Certain companies get a possible second draw, to improve chances of finding a given commodity.) The biggest difference between 2038 and other 18xx is that there are no tracks in space. Instead, each tile is an asteroid and contains mines (or can be blown up to build a base). You also have to keep track of which mines' goods have been collected so far each operating round. I wouldn't try to implement 2038 in the first version of this project. But if the object classes can be kept general enough that it's possible or close to it, then the program can probably handle any potential 18xx game that will ever be written, including the very silly one I have on my "someday" list -- 18WW (Well World). > > A friend of mine has a copy of 2038, so I can probably borrow the rules to help implement it's ruleset. > > However, I'd definitely classify 2038 as a game we want to wait to look at implementing until much later in the dev process. > > > ---Brett. > > > > ------------------------------------------------------- > SF email is sponsored by - The IT Product Guide > Read honest & candid reviews on hundreds of IT Products from real users. > Discover which products truly live up to the hype. Start reading now. > http://ads.osdn.com/?ad_ide95&alloc_id396&op=click > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel > |
From: Brett L. <wak...@ea...> - 2005-03-03 06:46:59
|
I think this is a good direction to take. Are you able to submit some code to move us in that direction? ---Brett. *********** REPLY SEPARATOR *********** On 3/2/2005 at 10:12 PM Iain Adams using ia...@co...= declared: >I suggested in a previous post using interfaces for primary datatype >definitions: one example of how this is done can be found in the Java >Collections framework. Here List is an interface which has a number of >implementation classes, which differ in their internal representations: >ArrayList LinkedList, etc. StockMarket.getIpoPile() has a return type of >ArrayList - this class should be free to change its list representation >without an API change, which can be achieved by declaring the method to >return a List. Personally, I would also make the member variable ipoPile= be >type List, and initialise it as a 'new ArrayList()' in the first instance. > >Iain. > > > >------------------------------------------------------- >SF email is sponsored by - The IT Product Guide >Read honest & candid reviews on hundreds of IT Products from real users. >Discover which products truly live up to the hype. Start reading now. >http://ads.osdn.com/?ad_id=3D6595&alloc_id=3D14396&op=3Dclick >_______________________________________________ >Rails-devel mailing list >Rai...@li... >https://lists.sourceforge.net/lists/listinfo/rails-devel ********** REPLY SEPARATOR END ********** This message sent with 100% recycled electrons. |
From: Brett L. <wak...@ea...> - 2005-03-03 04:10:55
|
I like just calling it a stop, or a trainStop. What do you think about this layout: Have an interface, or abstract class called TrainStop, which defines= objects for which a train must stop during the course of its runs. Cities,= towns, and whistle stops (e.g. the single 10$ stops, the 1830 rules book= calls 'em cross-bars) are all derived from the interface/abstract class. This way, when we're calculating routes, we can just pull together all the= objects on the map that are an instanceof(TrainStop). ---Brett. *********** REPLY SEPARATOR *********** On 3/2/2005 at 7:37 PM Erik Vos using eri...@hc... declared: >The pedantic version could be > > / TokenableRevenuePoint >RevenuePoint > \ NonTokenableRevenuePoint > >but perhaps better > > / City >Stop > \ Town > ********** REPLY SEPARATOR END ********** This message sent with 100% recycled electrons. |
From: Brett L. <wak...@ea...> - 2005-03-03 03:22:18
|
>I don't know 2038 and I doubt if we should include it in our project. >But if so, should that "private" then not be classified as a "minor >company"? > Technically it IS an 18xx-style game, but it deviates in a lot of ways from= your standard 18xx game. One big example is that all the tiles are= randomly chosen, then the player selects where he wants to place the tile. A friend of mine has a copy of 2038, so I can probably borrow the rules to= help implement it's ruleset. However, I'd definitely classify 2038 as a game we want to wait to look at= implementing until much later in the dev process. ---Brett. |
From: Brett L. <wak...@ea...> - 2005-03-03 02:40:06
|
For configuring options, I recommend taking a look at Colossus (= http://colossus.sf.net ). I think they do a good job of balancing in-game or pre-game options versus= specialties of variant game types. Granted, their game isn't going to have= quite the extent of "special rules" that we are, but I think it's a good= place to look at for some inspiration. I agree that we're going to have to split out two classes of options:= *mostly* game-independant (e.g. Use an extra optional "6" train, or Bank= starts with X value, etc), and game specific (e.g. Formation of the= Canadian National Railway in 1856). The other option is having a single catch-all user-defined game type where= the user can select the base ruleset (e.g. the user selects that he wants= to play a game with the 1825 ruleset) and from there, certain= customizations are then made available and tailored to what is reasonable= within each ruleset (e.g. an extra 6 train isn't reasonable for a game= that has no 6 trains at all.). Off the top of my head, allowing for a randomly constructed map and= user-defining the total amount of cash in the bank are probably two out of= only a handful of options that is _truly_ game independant. ---Brett. *********** REPLY SEPARATOR *********** On 3/2/2005 at 8:46 PM Erik Vos using eri...@hc... declared: > >There is one interesting idea that I would add, inspired on message #238 >from Gregor Zeitlinger: creating subclasses for game-specific processes. > >The question is to what extent we can configure options in a config file. >At some point things might get so complicated or game-specific that we >need to write special code. >The idea is to do that in game-specific subclasses of generic classes >which handle the more common cases. > >A strong example is the Ferdinandea Secession in 1841, which I don't think >we can make configurable - we will need game-specific code for that. ********** REPLY SEPARATOR END ********** This message sent with 100% recycled electrons. |
From: Brett L. <wak...@ea...> - 2005-03-03 02:20:17
|
> >Players can always cheat and edit a save file, making it a little less >easy doesn't stop them doing (search for 'security through (or by) >obscurity' for more information). I agree. Cheating isn't really a concern of mine unless Rails ends up= being looked at for tournament play. If we get to that stage, I think we can revisit the cheating issue. Until= then, I don't really care if someone can modify the save file to their advantage. The only person they cheat is= themselves. Additionally, in another Java app, PCGen, just last night I was able to fix= a bug in a data set on my own simply because the data format is= human-readable. In the early stages of development, the more we can= facilitate bug discovery, the better. > >You need a human readable format because it makes testing much easier, and >bug hunting later much easier. It is also much, much easier to provide >backward compatibility. Look at the problems Peter Nowak is reporting >getting the new version of the Vassal/18xx to read his old saves. Java >serialisation is great for live system-system communications, it is very >fragile as a persistence mechanism because when you change the class >signature, you find that you cannot load old saves. If your upgrade adds a >new attribute, either your new XML reading code can cope with the absence >from an old save, or you can easily provide a migration script for old >saves. Let's not even get into byte-ordering issues different hardware >classes. > >Basically, 'It's too much like hard work to do human readable saves' is >lazy, and will land in a deep hole later, it's also just not true with XML >as good libraries are freely available to do the hard work. > >It also means that someone else can much more easily write a tool that >will work with your save files: e.g. someone might want to take a game >log, and produce an animation of the map development. If your log is in a >well-known, easy to read format, they'll just get on with it, and suddenly >your project has more features. Keep it friendly for other people to work >with you, and you'll get more friends working with you. > All good points. In my opinion, speed of development is an important issue,= but so is long-term managability. I think XML is widely accepted enough that we won't have too= much of a problem finding tools to work with it. ---Brett |
From: Erik V. <eri...@hc...> - 2005-03-02 22:43:01
|
I used SAX because that I have some experience with that, unlike DOM. I've no problem to try a different approach, though. Any particular package in mind? dom4j? Erik. > -----Original Message----- > From: rai...@li... > [mailto:rai...@li...] On Behalf Of > Iain Adams > Sent: 02 March 2005 23:01 > To: Rails-devel (E-mail) > Subject: [Rails-devel] XMl file handling > > I've just been browsing through Erik's code, and I notice > that he's using > the SAX API for reading XML files. I've generally used the > DOM approach, > which has always seemed to need less code to get going with. > Our likely > model for reading a configuration file is to read a > relatively short file, > and extract content in an arbitrary order, and DOM seems to > me a better fit > for that requirement. > > Just a thought. > > Iain. > > > > > ------------------------------------------------------- > SF email is sponsored by - The IT Product Guide > Read honest & candid reviews on hundreds of IT Products from > real users. > Discover which products truly live up to the hype. Start reading now. > http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel > > |
From: Iain A. <ia...@co...> - 2005-03-02 22:10:12
|
I suggested in a previous post using interfaces for primary datatype definitions: one example of how this is done can be found in the Java Collections framework. Here List is an interface which has a number of implementation classes, which differ in their internal representations: ArrayList LinkedList, etc. StockMarket.getIpoPile() has a return type of ArrayList - this class should be free to change its list representation without an API change, which can be achieved by declaring the method to return a List. Personally, I would also make the member variable ipoPile be type List, and initialise it as a 'new ArrayList()' in the first instance. Iain. |
From: Iain A. <ia...@co...> - 2005-03-02 21:57:52
|
I've just been browsing through Erik's code, and I notice that he's using the SAX API for reading XML files. I've generally used the DOM approach, which has always seemed to need less code to get going with. Our likely model for reading a configuration file is to read a relatively short file, and extract content in an arbitrary order, and DOM seems to me a better fit for that requirement. Just a thought. Iain. |
From: Stewart T. <wsr...@ho...> - 2005-03-02 21:33:10
|
Hi, Attached is a revised version of the object model, adjusted in light of comments. The main changes are as follows: 1) I've collapsed all of the companies into a single class, including the private companies. While there is some consensus that there is nothing intrinsically different between major and minor companies, rolling up private companies as well is a little more contentious. It's not just a case of allowing for all of the current 18xx variations in companies, but also trying to make some allowance for the unknown variations yet to be published. A single class means that the assorted company behaviours have to be constrained with rules. 2) As promised, I've thought more about the issues of representing tiles with multiple and different cities. It is my belief that cities can be adequately represented as properties of the Tile classes. Having consulted my copy of 1856, it is only small cities (aka towns) that can be "downgraded" into straight track, so there is no interference with the location of a token in this process. The revenue generated by a city can also be held as a property of the tile - just as it is in the physical game set. However, there does have to be a way to associate a company's token with a specific large city on a tile that contain multiple large cities, if this cities are disjoint and have different revenue values or track connections. To enable this I've added a subclass of Location called DisjointCityLocation. I envisage most objects being directly of class Location, with only the few special cases being of DisjointCityLocation. In this object model, I am trying to address those objects that need to be persistent in a saved game state. While cities are important for revenue calculation - that is a transient activity that does not need to be saved in the game state. Similarly, the behaviour of a specific train type is also important during revenue calculation, but as long as the behaviour is configured by a game specific rule set, and available to the revenue calculation algorithm, then there is no need to transform the Train class into a hierarchy of different types. cheers Stewart |
From: <ia...@co...> - 2005-03-02 20:54:56
|
>> Has anyone read the 18xx-softdev archive yet? A lot of good >> ground was covered there (not all by me ;-)), and I think the >> discussions here would benefit from using this as a base. >> Specifically look at the thread(s) on a game definition file. >Just looked again, but it is hard so sort out the few pearls from that mess. >The thing I see so far is your data model in message #127, which we >indeed would do well to keep handy (I"ll print it out). >Marco Rocci"s summary of the 1830 private auction process in message #478 >might also be useful. >Any other messages you find worth revisiting? I have a vague overview in my head, I'll have to browse through it again myself to find the good bits. Reading it has value in that there are some useful items (your vote of confidence in my data model appreciated), and some useful discussions, and one can also see many dead-end discussions, which might be avoided here if people have read that list- "Those Who Are Ignorant of History Are Condemned to Repeat." >There is one interesting idea that I would add, inspired on message #238 >from Gregor Zeitlinger: creating subclasses for game-specific processes. >The question is to what extent we can configure options in a config file. >At some point things might get so complicated or game-specific that we >need to write special code. >The idea is to do that in game-specific subclasses of generic classes >which handle the more common cases. [ Decent example snipped for brevity.] >Such classes should be instantiated by a class factory. Yes, with a decent data model, many things are possible through configuration: it is a question of understanding and modelling the range of behaviour a component might exhibit (e.g. company). There will always be a point where a rule in one game is so unusual that it is best dealt with through a new class. This is where defining the datatypes through interfaces, and instantiating them through factories becomes a very powerful technique. It's a little more effort up-front, but the payback is enormous. Iain. |
From: <ia...@co...> - 2005-03-02 20:37:53
|
>> Binary saves are a very, very bad idea: do I really need to explain why? >> Creating and reading XML for the saves is not difficult. >Please explain. It seems to me that the only thing you accomplish by >saving in XML is to enable players to cheat in multiplayer games by >editing the save file. Players can always cheat and edit a save file, making it a little less easy doesn't stop them doing (search for 'security through (or by) obscurity' for more information). You need a human readable format because it makes testing much easier, and bug hunting later much easier. It is also much, much easier to provide backward compatibility. Look at the problems Peter Nowak is reporting getting the new version of the Vassal/18xx to read his old saves. Java serialisation is great for live system-system communications, it is very fragile as a persistence mechanism because when you change the class signature, you find that you cannot load old saves. If your upgrade adds a new attribute, either your new XML reading code can cope with the absence from an old save, or you can easily provide a migration script for old saves. Let's not even get into byte-ordering issues different hardware classes. Basically, 'It's too much like hard work to do human readable saves' is lazy, and will land in a deep hole later, it's also just not true with XML as good libraries are freely available to do the hard work. It also means that someone else can much more easily write a tool that will work with your save files: e.g. someone might want to take a game log, and produce an animation of the map development. If your log is in a well-known, easy to read format, they'll just get on with it, and suddenly your project has more features. Keep it friendly for other people to work with you, and you'll get more friends working with you. Iain. |
From: Erik V. <eri...@hc...> - 2005-03-02 19:46:55
|
Iain, > General comment: > > Has anyone read the 18xx-softdev archive yet? A lot of good > ground was covered there (not all by me ;-)), and I think the > discussions here would benefit from using this as a base. > Specifically look at the thread(s) on a game definition file. Just looked again, but it is hard so sort out the few pearls from that mess. The thing I see so far is your data model in message #127, which we indeed would do well to keep handy (I'll print it out). Marco Rocci's summary of the 1830 private auction process in message #478 might also be useful. Any other messages you find worth revisiting? There is one interesting idea that I would add, inspired on message #238 from Gregor Zeitlinger: creating subclasses for game-specific processes. The question is to what extent we can configure options in a config file. At some point things might get so complicated or game-specific that we need to write special code. The idea is to do that in game-specific subclasses of generic classes which handle the more common cases. A strong example is the Ferdinandea Secession in 1841, which I don't think we can make configurable - we will need game-specific code for that. This would mean, that class names should be configurable too: an 1841 game definition file might contain a definition like "PhaseChangeClass=PhaseChange1841" (or the equivalent in XML), assuming that we have a generic (default) class named PhaseChange. Such classes should be instantiated by a class factory. |
From: Erik V. <eri...@hc...> - 2005-03-02 18:37:43
|
> >- Tokens are sometimes not bound to a location but > >to one of two (or even three) cities on one tile. > >I think we need "City" as a separate object type > >(also for revenue calculation). > >Also remember that the values of two cities on one tile > >are not always equal, see 1841 Venice. > >Cities can merge, be upgraded, or even disappear (1856). > > A good point, and one I want to think about further. I'm not > sure that > having a City class adds any value beyond associating Token > directly with > Tile, as it is the Tile that dictates the number, size and > revenue of the > cities, towns, etc. Neither does a City class solve the > problem of avoiding > all relationship migrations during an upgrade (disappearing > cities sound > like a downgrade!), though maybe that is unavoidable... I will think > further. We also have per-train city properties (does a city/town count for revenue, and if so, with what factor; does a city/town count against the train length). So in some games we have an n:m relationship between trains and tiles, so I wonder if we need a CityType class in between. Whether or not so, we should in any case agree on the nomenclature. The pedantic version could be / TokenableRevenuePoint RevenuePoint \ NonTokenableRevenuePoint but perhaps better / City Stop \ Town Erik. |
From: Erik V. <eri...@hc...> - 2005-03-02 18:25:00
|
> > I have thought about this for a while, but I'm not sure if > > this really is a fundamental distinction. > > > > The only distinction which is really fundamental is between > > companies that lay track, run trains, have a treasury etc, > > and companies that don't. > > > > The latter are commonly known as "private companies", > > although some games call them differently, like > > "mountain railways" (1854). I would also count the 1841 > > "concessions" in this category. > > IMO, even that distinction is not "fundamental" to all games. > Don't forget the TSI private in 2038, which can run a train. I don't know 2038 and I doubt if we should include it in our project. But if so, should that "private" then not be classified as a "minor company"? Erik. |
From: Brett L. <wak...@ea...> - 2005-03-02 17:05:41
|
>> >However, for saving the state of the game, I think that Java >> Serialization >> >would be a better choice. The volume of data involved is >> relatively small >> >and the coding for straightforward serialization is simple, >> certainly >> >several times less effort than mapping all objects in and out of XML. >> >> Sounds good. I agree that the mapping a save file to XML will >> probably be a lot of work. So, >> if there's a simpler way, I'd favor using it. > >Yes, but I think that we also need the other save-related option >originally proposed by Brett: a log of all actions performed. >If only for the post-mortem and/or publication of a game! >(I've myself replayed quite some games published on Internet). My main motivator here, is that there's a Java client for playing PBEM= Diplomacy (i forget the name at the moment) and it allows this mechanism= of replaying past games. I'll see if I can't dig up the name of the app and, if it's open source,= take a peek at how they handle this problem. ---Brett. |
From: Brett L. <wak...@ea...> - 2005-03-02 17:00:38
|
>> >>- Tokens are sometimes not bound to a location but >>to one of two (or even three) cities on one tile. >>I think we need "City" as a separate object type >>(also for revenue calculation). >>Also remember that the values of two cities on one tile >>are not always equal, see 1841 Venice. >>Cities can merge, be upgraded, or even disappear (1856). > >A good point, and one I want to think about further. I'm not sure that >having a City class adds any value beyond associating Token directly with >Tile, as it is the Tile that dictates the number, size and revenue of the >cities, towns, etc. Neither does a City class solve the problem of >avoiding >all relationship migrations during an upgrade (disappearing cities sound >like a downgrade!), though maybe that is unavoidable... I will think >further. > Do you think we'll need a City class for helping calculate routes? >This is both good news AND bad news. Good news, because there is a lot of >literature on graph theory and traversal algorithms. Bad news, because >most >graph traversal algorithms are non-polynomial and fall into the class of >mathematical problems known as NP hard. This means, that the runtime of >the >algorithm is exponentially sensitive to the number of stations that the >train can visit. I suspect this is probably how it was done in the 1830 PC game. A good= indicator is that, even though this is a DOS-based game, it still takes= quite a bit of time calculating the AI's turns on newer processors. >Single train solutions are probably not too bad to calculate as the graphs= >involved won't be too large. I'm more concerned about multiple train >solutions, because a strategy of optimizing each train in turn may not >lead >to the optimal combined solution. What I mean is, that in a hypothetical >situation, the best total revenue for a two train company may be 90 - made= >up of one train running for 50 and another train running for 40. However, >it >may be the case that the optimal single train solution has a revenue of >60, >but that only leaves a maximum revenue of 20 for the second train giving a= >sub-optimum total revenue of 80. In other words, the maximum combined >revenue requires the highest revenue earning train to take a route that is= >less than its individual maximum potential. It's probably best to leave this problem for later and for now, simply= assure that we build in the components needed to work on it when we get to= it. |
From: John D. G. <jd...@di...> - 2005-03-02 13:02:17
|
ia...@co... wrote: > Binary saves are a very, very bad idea: do I really need to explain why? > Creating and reading XML for the saves is not difficult. Please explain. It seems to me that the only thing you accomplish by saving in XML is to enable players to cheat in multiplayer games by editing the save file. |
From: <ia...@co...> - 2005-03-02 13:01:56
|
Route traversal and revenue calculation: I wrote some perl to do this several years ago (avilable at http://www.cosgor.demon.co.uk/Perlbits/revenue.html), it doesn't take long. General comment: Has anyone read the 18xx-softdev archive yet? A lot of good ground was covered there (not all by me ;-)), and I think the discussions here would benefit from using this as a base. Specifically look at the thread(s) on a game definition file. Class structures, general and company: The abstract base class suggestion is almosts right. THe best practice is to define an interface, e.g. CompanyI, which defines the methods that all companies need to implement. You can then have an abstract base class and specific implementation classes for the most common types, but you are free to supply a completely different implementation without the need for inheriting from a specific (abstract base) class. All API methods which work with Company objects should then use CompanyI as the reference type unless a known sub-type is needed. Another advantage of this interface approach is that it permits one class to implement several different functions, e.g. an 1841 company class could implement 'TrainOwnerI', and 'ShareholderI'. In fact an 1830 public company could also implement 'ShareHolderI' to deal with any payments that it could receive from a private company which it owns. On the subject of share structure for companies, why not have a ShareI datatype, and have a 'List<ShareI> getShareStructure()' method on CompanyI? (Notes: a) use of Java5 Generics optional, b) choice of which collection to use also open) A method on ShareI could be 'int dividendForPayout(int payout)' which would calculate the dividend for a given share when the company distributes 'payout' amongst its shareholders. Other possible methods for a share could include 'double getSharePercent()', 'List getValidOwners()' - an 1830 private can be owned by a player or a company, but public company shares may only be held by players (or the bank pool, or the IPO). Iain. |