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...@gm...> - 2006-08-14 19:10:53
|
On 8/14/06, Erik Vos <eri...@hc...> wrote: > Thanks for your comments. > Just one additional remark for now: > > > > A corollary of the above approach would be, that the player > > turn will > > > never be over if the allowed-actions List is not yet empty. > > > So we will need an always-available Done button > > > (in fact the current No Tile and No Token buttons have that role, > > > but for clarity I would prefer to get rid of those). > > > > > > > I'd really like to see the No Tile/No Token button merged with the > > Done button, and just continue to change the text of the button to > > represent it's current action. > > > > However, I don't really like forcing the user to step through each > > phase. I'd really like the UI to do something along the lines of > > SimTex's 1830 game, where you can skip unneeded phases by choosing the > > option you want to do. > > > > I'm not certain we could do this without reworking our phase handling > > a bit, though. > > Hmm, that's a different approach, and one worth thinking about. > > Not sure how to accomplish this, perhaps a menu bar with options, > that grey out as they have been used or skipped. Right, this is basically what the 1830 pc game had. If you skipped past something, you usually couldn't go back to it. > > It does not save many user actions. Currently, users have to click > a button if they want to get *out of* a turn step, whereas in this way > they have to select an option to get *into* a step. > I agree, it's not a huge savings. The one added benefit is simply being able to see all phases of the OR in a neat list, so that you get a reminder of what's coming up. I wouldn't really consider a change like this a very high priority, if we decide to do it at all. > The allowed-action selection, needed to build the menu, will be more > complex, > because we do not only have to worry about what actions are currently > possible, > but also about what later turn steps a player might legitimately jump to. > But that does not look to be insurmountable. > > Handling the jumps should not be a big deal, as the game engine already has > turn step awareness. > > Nice ideas to think about if my coming vacation (the next two weeks) > would turn out to be rainy - it's in mid-Germany, could well be so... :-( > Have a good vacation. One of these days, I'd really like to get to Essen. ---Brett. |
From: Erik V. <eri...@hc...> - 2006-08-14 18:47:07
|
Thanks for your comments. Just one additional remark for now: > > A corollary of the above approach would be, that the player > turn will > > never be over if the allowed-actions List is not yet empty. > > So we will need an always-available Done button > > (in fact the current No Tile and No Token buttons have that role, > > but for clarity I would prefer to get rid of those). > > > > I'd really like to see the No Tile/No Token button merged with the > Done button, and just continue to change the text of the button to > represent it's current action. > > However, I don't really like forcing the user to step through each > phase. I'd really like the UI to do something along the lines of > SimTex's 1830 game, where you can skip unneeded phases by choosing the > option you want to do. > > I'm not certain we could do this without reworking our phase handling > a bit, though. Hmm, that's a different approach, and one worth thinking about. Not sure how to accomplish this, perhaps a menu bar with options, that grey out as they have been used or skipped. It does not save many user actions. Currently, users have to click a button if they want to get *out of* a turn step, whereas in this way they have to select an option to get *into* a step. The allowed-action selection, needed to build the menu, will be more complex, because we do not only have to worry about what actions are currently possible, but also about what later turn steps a player might legitimately jump to. But that does not look to be insurmountable. Handling the jumps should not be a big deal, as the game engine already has turn step awareness. Nice ideas to think about if my coming vacation (the next two weeks) would turn out to be rainy - it's in mid-Germany, could well be so... :-( Erik. |
From: brett l. <wak...@gm...> - 2006-08-14 03:27:55
|
Comments inline... On 8/13/06, Erik Vos <eri...@hc...> wrote: > It's a very old message that I'm replying here to. > I have looked it up because it was about the last time that > we discussed the subject of special properties. > > I'm revisiting this subject, partly because I've encountered it > in a different context in 1835, and partly because I just discovered > that the existing extra tile laying code for 1830 is broken. > > There are two aspects to be considered (applied to tile laying): > > 1. The game mechanics should be aware of extra tiles to be laid, > and, if necessary, extend a player's turn to allow for it. > This worked 7 months ago for 1830. > > 2. Make the user clearly aware of this special situation. > The only clue so far was that the current player highlight did not move > after laying the first tile. To do something about this, > I have just added an extra prompt message (in red) to the > existing prompts above the map about the option to lay an extra > tile or token. > Agreed. I prefer using the prompt messages instead of messagebox popups. > However, my main concern is that the current way in which the UI > and the game engine communicate, pretty complex as it already is, > will not easily accommodate different special property types and > their application rules. I'm always keeping in mind that one day > we want to turn this into a client/server application. > Generic 18xx is a complex endeavor. I don't think we have any choice but to gradually increase the complexity of the main subsystems. > For a solution I would propose the following approaches. > > 1. The game mechanics: > > I think the best approach is to generalise a mechanism that already > exists in some contexts, i.e. train buying and share buying and selling, > and that I have found very fruitful so far. > > The generic mechanism would be, that after each user action the UI would > get a fresh and complete list of all allowed actions at that point, > including state information about who's turn it is etc., > by one or two calls to the Model. > This will reduce (or hopefully completely eliminate) the current need > for the UI to have it's own (partial) state memory. > > For this end we will need a new "allowed actions" class hierarchy, > derived from some abstract base class. The result of the above-mentioned > "what can I do" call would then be a List of objects which are > instances of subclasses of that base class. The existing class > BuyableTrain would become such a subclass. > > An example of such an object would be "Lay a tile on hex XY". > This would already work for the special extra tile lays. > We can't yet restrict normal tile lays, so we would > have a blanket "lay a tile anywhere" object instead. > Once we have route awareness, this would be replaced > by a series of objects, one for each hex where a tile can be laid. > > (I think this approach would also make the future client/server > separation easier: a main component of the client-to-server information > stream could exist of a serialized version of this List). > > I'm looking for a good and shortish name for the base class. > We have already consumed Action, Move and Option. > AllowedAction might do, or UserOption, but I would prefer a short > one-word name that can easily be incorporated in its subclass names. > What about Play? Overall, I like this idea. I think AllowedAction or UserAction are good. The problem with single-words is that they're very ambiguous. I'd like to keep the API reasonably descriptive. Hopefully it will make the learning curve for any new developers slightly less steep. > > 2. The UI: > > A corollary of the above approach would be, that the player turn will > never be over if the allowed-actions List is not yet empty. > So we will need an always-available Done button > (in fact the current No Tile and No Token buttons have that role, > but for clarity I would prefer to get rid of those). > I'd really like to see the No Tile/No Token button merged with the Done button, and just continue to change the text of the button to represent it's current action. However, I don't really like forcing the user to step through each phase. I'd really like the UI to do something along the lines of SimTex's 1830 game, where you can skip unneeded phases by choosing the option you want to do. I'm not certain we could do this without reworking our phase handling a bit, though. > We could still accommodate an automatic end of a player turn if the > allowed-actions list is empty, but we should then tell the user about that. > > What about a popup saying something like "End of turn for A, it's now B's > turn" > that would appear *each* time when a new player (or President) gets the > turn, regardless whether the turn change was automatic or triggered > by pressing the Done button? > As mentioned above, I prefer using prompts rather than pop-ups. I personally get annoyed by applications that overuse modal pop-ups. However, a popup may be something that is necessary when we implement hidden money values, so that we hide all values, pop-up the player change, then redraw only the current player's wallet. > To exercise special actions that fall outside the normal sequence of > events in a round, we could add a menu bar, with options that would > only show up (or be active) when such an action can be exercised. > In 1830, this would apply to buying Privates and the M&H/NYC swap. > > The above is mainly of interest for the OR. > I'm not sure if we should extend this to the SR, where we already have > the situation that Done/Pass must always be pressed to end a player turn. > However, here also we could implement an automatic turn end (with warning) > if there is nothing a player could do (i.e. the allowed-actions list is > empty). > > Agreed. I think most SRs don't really add as much complexity as the ORs. ----Brett. |
From: Erik V. <eri...@hc...> - 2006-08-13 13:42:36
|
It's a very old message that I'm replying here to. I have looked it up because it was about the last time that we discussed the subject of special properties. I'm revisiting this subject, partly because I've encountered it in a different context in 1835, and partly because I just discovered that the existing extra tile laying code for 1830 is broken. There are two aspects to be considered (applied to tile laying): 1. The game mechanics should be aware of extra tiles to be laid, and, if necessary, extend a player's turn to allow for it. This worked 7 months ago for 1830. 2. Make the user clearly aware of this special situation. The only clue so far was that the current player highlight did not move after laying the first tile. To do something about this, I have just added an extra prompt message (in red) to the existing prompts above the map about the option to lay an extra tile or token. However, my main concern is that the current way in which the UI and the game engine communicate, pretty complex as it already is, will not easily accommodate different special property types and their application rules. I'm always keeping in mind that one day we want to turn this into a client/server application. For a solution I would propose the following approaches. 1. The game mechanics: I think the best approach is to generalise a mechanism that already exists in some contexts, i.e. train buying and share buying and selling, and that I have found very fruitful so far. The generic mechanism would be, that after each user action the UI would get a fresh and complete list of all allowed actions at that point, including state information about who's turn it is etc., by one or two calls to the Model. This will reduce (or hopefully completely eliminate) the current need for the UI to have it's own (partial) state memory. For this end we will need a new "allowed actions" class hierarchy, derived from some abstract base class. The result of the above-mentioned "what can I do" call would then be a List of objects which are instances of subclasses of that base class. The existing class BuyableTrain would become such a subclass. An example of such an object would be "Lay a tile on hex XY". This would already work for the special extra tile lays. We can't yet restrict normal tile lays, so we would have a blanket "lay a tile anywhere" object instead. Once we have route awareness, this would be replaced by a series of objects, one for each hex where a tile can be laid. (I think this approach would also make the future client/server separation easier: a main component of the client-to-server information stream could exist of a serialized version of this List). I'm looking for a good and shortish name for the base class. We have already consumed Action, Move and Option. AllowedAction might do, or UserOption, but I would prefer a short one-word name that can easily be incorporated in its subclass names. What about Play? 2. The UI: A corollary of the above approach would be, that the player turn will never be over if the allowed-actions List is not yet empty. So we will need an always-available Done button (in fact the current No Tile and No Token buttons have that role, but for clarity I would prefer to get rid of those). We could still accommodate an automatic end of a player turn if the allowed-actions list is empty, but we should then tell the user about that. What about a popup saying something like "End of turn for A, it's now B's turn" that would appear *each* time when a new player (or President) gets the turn, regardless whether the turn change was automatic or triggered by pressing the Done button? To exercise special actions that fall outside the normal sequence of events in a round, we could add a menu bar, with options that would only show up (or be active) when such an action can be exercised. In 1830, this would apply to buying Privates and the M&H/NYC swap. The above is mainly of interest for the OR. I'm not sure if we should extend this to the SR, where we already have the situation that Done/Pass must always be pressed to end a player turn. However, here also we could implement an automatic turn end (with warning) if there is nothing a player could do (i.e. the allowed-actions list is empty). This was a long story, I hope it is clear enough. Any comments? Erik. > -----Original Message----- > From: rai...@li... > [mailto:rai...@li...] On Behalf Of > Brett Lentz > Sent: 26 January 2006 21:51 > To: rai...@li... > Subject: RE: [Rails-devel] M&H > > > >> Also note: If the swap is done before the president's share > >> is bought, this swap sets the par value for the NYC. > > > >I don't think so. The free PRR share that comes with the C&A > >does not have a price either, until the PRR is opened by > >buying the presidency. AFAIK the same holds for the NYC. > > > > > Hmm... I'll doublecheck the rule book. I'd swear I remember > encountering this with 1830 pc game, and seeing that it > forces you to set the par value if it's unset. > > > >> I finally got a chance to check out your updates. I think the > >> extra button in the status window is perfect. It's not > >> intrusive, but it let's the player owning the M&H know that > >> his ability is available. > >> > >> I think we should do this same sort of thing for the other > >> special abilities, especially the C&StL. Right now, after a > >> company purchases the C&StL, the UI inexplicably maintains > >> the "Lay Tile" buttons after the lays it's normal tile, and > >> doesn't give any sort of notification that we're allowing for > >> the C&StL tile lay before moving on to laying tokens. > > > >Yes, I agree, but I have not yet found a good way to do that. > > > >Perhaps we should add a message line over the full width of the > >SR and OR windows in which we can show a one-line message about > >what the player having the turn is supposed to do. Here we could > >also add a reminder about special properties that can be exercised. > > > > That would be helpful. > > Currently, I think we do just fine with the turn order flow. > There's some minor UI cleanups I want to do, but overall I > think we're doing well enough. The only exception being that > when we deviate, we need to tell the user why we're altering > the normal turn order. So, maybe a good thing to add is > changing the text over the UpgradesPanel to indicate we're > allowing for the C&Stl Optional Tile Lay. > > I think that, ideally, we should just provide a button for > jumping outside the normal turn order, to activate the > special ability, and then return back to the normal turn > order at the same point we left. > > Perhaps rather than a new message line, we should just set > the Title on the JFrame to indicate the current stage of the > turn. That would be a bit less intrusive. What do you think? > > > ---Brett. > > > ------------------------------------------------------- |
From: Erik V. <eri...@hc...> - 2006-08-03 16:55:00
|
> If there > is a file containing the list of games, the information about that > status of the game can be kept there as well. That is what I proposed a while ago. Erik. |
From: brett l. <wak...@gm...> - 2006-08-03 01:29:34
|
On 8/2/06, John A. Tamplin <ja...@ja...> wrote: > brett lentz wrote: > > The XML isn't read until after Game.initialize() has been called. We > > can't initialize more than one game (or maybe I just don't know how to > > uninitialize it). > > > > So, we can't get at the variant XML data in the Options window. > > > > Is there something I'm missing? Is there an easy way around this? > > > How does it find the list of games to present in the dialog? If there > is a file containing the list of games, the information about that > status of the game can be kept there as well. > Currently it uses a directory list (bad). I agree, once we have the central XML that provides information about game development status, we should include variant info there as well. ---Brett. |
From: John A. T. <ja...@ja...> - 2006-08-03 01:17:24
|
brett lentz wrote: > The XML isn't read until after Game.initialize() has been called. We > can't initialize more than one game (or maybe I just don't know how to > uninitialize it). > > So, we can't get at the variant XML data in the Options window. > > Is there something I'm missing? Is there an easy way around this? > How does it find the list of games to present in the dialog? If there is a file containing the list of games, the information about that status of the game can be kept there as well. -- John A. Tamplin ja...@ja... 770/436-5387 HOME 4116 Manson Ave Smyrna, GA 30082-3723 |
From: brett l. <wak...@gm...> - 2006-08-03 01:11:43
|
On 7/29/06, brett lentz <wak...@gm...> wrote: > On 7/29/06, Erik Vos <eri...@hc...> wrote: > > > > A selection box after selecting 1835 will now ask for the opening > > > > variant to play: Standard, Clemens or Snake. The Start > > > round variants > > > > work, except for some validation rules (cash!). > > > > > > Rather than a separate pop-up, I think we should include this in the > > > Options dialog. > > > > > > I think some sort of "when game X is selected, we populate the dialog > > > with the available options" mechanism would work. > > > > Fine with me, but I'll leave the work to you, if you don't mind. > > You can find in Options how I populate the selection. > > > > Sure. I can do that. > I just noticed a problem with doing this. The XML isn't read until after Game.initialize() has been called. We can't initialize more than one game (or maybe I just don't know how to uninitialize it). So, we can't get at the variant XML data in the Options window. Is there something I'm missing? Is there an easy way around this? ---Brett. |
From: brett l. <wak...@gm...> - 2006-08-02 00:50:44
|
It looks like we've got a few nice additions to release. Barring any objections, I'll release v.1.0.2 on Sunday, the 6th. Here's the current list of changes: * Red Tiles now display their values. * Improved UI clarity - Load/Save buttons are disabled to reduce confusion. * Undo and Redo for the Stock Phase is mostly complete. - Undo across player turns is not currently supported, but will be added in the future. In other words, once you move on to another player's turn, you can't go back to your turn. ---Brett. |
From: Erik V. <eri...@hc...> - 2006-07-30 20:38:40
|
In the past few days I have added a few bits to 1835. Stuff that already worked long ago and has now been retested: - Minors. - 3 different variants for start packet distribution. Now added: - The map. - Majors can lay 2 yellow tiles in the yellow phase. - Tile upgrade rules can vary per hex (e.g. non-Y and Y cities get different yellow tiles). Not yet done: - Private special properties. - Prussian formation. - Certificate selection (10% or 20%) on buying from and selling to the Pool. - Nationalisation. - Perhaps a lot more; it's long ago that I played this game, I don't have all the finer details clear in my mind now. 1835 required the ability to have 2 home tokens in one hex. To facilitate this, the home and destination hex configuration has been moved from Map.xml to CompanyManager.xml. I have also implemented the correct revenue display for the red off-board hexes per phase. The different values are specified in Map.xml, and the change triggers have been added to the Phase definitions in Game.xml. 1856 and 18AL currently do not properly initialise; I will sort that out later. Erik Vos |
From: brett l. <wak...@gm...> - 2006-07-29 18:04:53
|
On 7/29/06, Erik Vos <eri...@hc...> wrote: > > > A selection box after selecting 1835 will now ask for the opening > > > variant to play: Standard, Clemens or Snake. The Start > > round variants > > > work, except for some validation rules (cash!). > > > > Rather than a separate pop-up, I think we should include this in the > > Options dialog. > > > > I think some sort of "when game X is selected, we populate the dialog > > with the available options" mechanism would work. > > Fine with me, but I'll leave the work to you, if you don't mind. > You can find in Options how I populate the selection. > Sure. I can do that. > > > I have chosen this game because (1) it's already partly done, > > > (2) it adds some interesting new game aspects, and (3) the > > > extra's are probably not too difficult to implement. > > > In particular, there are no special private properties > > > beyond what we already have (except for the Prussian formation). > > > It is a well-known game too, at least in Europe... > > > > > > > Sounds good to me. Will coding the Prussian formation be generic > > enough to also handle the CNR in 1856? Or are there specifics about > > each that might require special-case coding? > > It is very different. In 1856, the CGR is formed from other > major companies under certain conditions, and it is an automatic process. > > OTOH, in 1835 the Prussian forms out of minors and privates, > and players have several occasions to decide if they want to convert or > not, first at the start of the first 4-train, and then further > at the start of each SR and OR. > I will try to reuse the existing M&H/NYC swap mechanism to implement > a first version of this process. > Ok... I haven't played 1835, so I wasn't really sure if it was at all similar to any other game. > > > Another simple game that should be easily doable is 1851; > > > only the start round needs extra coding. > > > > > > > Is there an easy way we can differentiate between playable and > > unplayable games in our UI? Right now, users have no way of knowing > > what isn't fully implemented until they try to play it. > > > > I suspect this may require changing how we populate the game list, but > > perhaps that might be a good thing for a few different reasons. > > Yes, that is a very good suggestion. > Rather than looking for subdirectories of 'data' we could put a > 'catalogue' file in that directory. That file could contain > a list of games with a status value for each game. > Status values could be: > - Playable (or finished) > - Partly playable (or unfinished) > - Unplayable (under development) > > Options could include a selection of what minimum status level > should be applied. On publication, this should be preset to 'playable' > (but of course I will set it much lower). > > We also need a properties file to store parameters > like this preset level, language etc. > I like that. Let's do this. ---Brett. |
From: brett l. <wak...@gm...> - 2006-07-29 18:01:48
|
On 7/29/06, Erik Vos <eri...@hc...> wrote: > Your proposal looks like a change to Tiles.xml, but that is > definitely not the right place, as this file should > only contain game-independent tile features. > The off-board revenue values should be defined in Map.xml. > > In fact I have this item high on my list of next-to-do things. > > I would do it like this: > > 1. Put the values per step in Map.xml, e.g. like (for 1830) > > <Hex name="A9" tile="-901" orientation="0" values="30,50"/> > > 2. Put the change conditions in Game.xml per Phase. > The default would be step 1. Only the change point needs be > defined, e.g. like > > <Phase name="5"> > <Tiles colour="yellow,green,brown"/> > <Privates close="yes"/> > <OperatingRounds number="3"/> > <OffBoardRevenue step="2"/> > </Phase> > > If it's OK with you, I can do this after I have fixed token laying. > Sure, you can do this whenever you like. I was more just trying to find a good place to include this information. |
From: Erik V. <eri...@hc...> - 2006-07-29 10:02:20
|
Your proposal looks like a change to Tiles.xml, but that is definitely not the right place, as this file should only contain game-independent tile features. The off-board revenue values should be defined in Map.xml. In fact I have this item high on my list of next-to-do things. I would do it like this: 1. Put the values per step in Map.xml, e.g. like (for 1830) <Hex name="A9" tile="-901" orientation="0" values="30,50"/> 2. Put the change conditions in Game.xml per Phase. The default would be step 1. Only the change point needs be defined, e.g. like <Phase name="5"> <Tiles colour="yellow,green,brown"/> <Privates close="yes"/> <OperatingRounds number="3"/> <OffBoardRevenue step="2"/> </Phase> If it's OK with you, I can do this after I have fixed token laying. Erik. > -----Original Message----- > From: rai...@li... > [mailto:rai...@li...] On Behalf > Of brett lentz > Sent: 26 July 2006 23:08 > To: Development list for Rails: an 18xx game > Subject: [Rails-devel] Getting Red Tiles to display correct values. > > I've been looking at how to address this problem. > > It seems that there's a limitation to our current XML definitions for > Tiles.xml . > > Having "value" as a property of the station means that we can't > specifiy any deviations when there are two copies of the same tile > with differing values on the map. > > I propose a change to our XML: > > This is our current version: > > <Tile id="-901" colour="red"> > <Station id="city1" type="OffMapCity" value="-1" position="0"/> > <Track gauge="normal" from="city1" to="side2"/> > </Tile> > > This is what I suggest to allow us to solve our red tile > display issues: > > <Tile id="-901" colour="red"> > <Station id="city1" type="OffMapCity" value="-1" position="0"> > <Hex location=A9 values="30,50" upgradeTrigger="Trains > Available" upgradeWhen="5"> > </Station> > <Track gauge="normal" from="city1" to="side2"/> > </Tile> > > > I think we should keep the value parameter as deprecated just to allow > for a way to globally set the value of all tiles of that type. > However, we should add the Hex tag with parameters that can override > the global value for a specific hex on a specific map. > > How does this sound? > > ---Brett. > > -------------------------------------------------------------- > ----------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the > chance to share your > opinions on IT & business topics through brief surveys -- and > earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge > &CID=DEVDEV > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel > > |
From: Erik V. <eri...@hc...> - 2006-07-29 09:52:55
|
> > A selection box after selecting 1835 will now ask for the opening > > variant to play: Standard, Clemens or Snake. The Start > round variants > > work, except for some validation rules (cash!). > > Rather than a separate pop-up, I think we should include this in the > Options dialog. > > I think some sort of "when game X is selected, we populate the dialog > with the available options" mechanism would work. Fine with me, but I'll leave the work to you, if you don't mind. You can find in Options how I populate the selection. > > I have chosen this game because (1) it's already partly done, > > (2) it adds some interesting new game aspects, and (3) the > > extra's are probably not too difficult to implement. > > In particular, there are no special private properties > > beyond what we already have (except for the Prussian formation). > > It is a well-known game too, at least in Europe... > > > > Sounds good to me. Will coding the Prussian formation be generic > enough to also handle the CNR in 1856? Or are there specifics about > each that might require special-case coding? It is very different. In 1856, the CGR is formed from other major companies under certain conditions, and it is an automatic process. OTOH, in 1835 the Prussian forms out of minors and privates, and players have several occasions to decide if they want to convert or not, first at the start of the first 4-train, and then further at the start of each SR and OR. I will try to reuse the existing M&H/NYC swap mechanism to implement a first version of this process. > > Another simple game that should be easily doable is 1851; > > only the start round needs extra coding. > > > > Is there an easy way we can differentiate between playable and > unplayable games in our UI? Right now, users have no way of knowing > what isn't fully implemented until they try to play it. > > I suspect this may require changing how we populate the game list, but > perhaps that might be a good thing for a few different reasons. Yes, that is a very good suggestion. Rather than looking for subdirectories of 'data' we could put a 'catalogue' file in that directory. That file could contain a list of games with a status value for each game. Status values could be: - Playable (or finished) - Partly playable (or unfinished) - Unplayable (under development) Options could include a selection of what minimum status level should be applied. On publication, this should be preset to 'playable' (but of course I will set it much lower). We also need a properties file to store parameters like this preset level, language etc. Erik. |
From: brett l. <wak...@gm...> - 2006-07-29 01:37:22
|
It just occurred to me that I haven't really written out how I make the SVG tiles. Here's the basic process: 1. Export postscript files from TileDesigner 2. Use pstoedit to convert the ps to svg. ( http://www.pstoedit.net/pstoedit/ ) $ for x in `ls *.ps`; do pstoedit -f plot-svg $x $x.svg; done 3. Rename all of the svg files so they don't have the double extension $ rename .ps.svg .svg *.svg 4. Open the new svg in Inkscape, and make several adjustments to the canvas size and positioning of the hex. ( http://www.inkscape.org/ ) Edits made in Inkscape: 1. Delete invisible white background layer, so that it's now a transparent background. 2. Set hex location to (0,0) 3. Set hex size to 720x720 pixels (the size of the canvas) 4. In Document Properties, Set canvas size to 100x100 pixels It's not a terribly pretty or efficient process, but it works. If there's a Ghostscript wizard around that knows a better way of doing the conversions, I'd love to hear it. ---Brett. |
From: Erik V. <eri...@hc...> - 2006-07-28 22:31:49
|
I have changed home base token management such that one hex can contain multiple home bases in multiple stations (cities). This was needed for 1835 Berlin. Homes are now defined in the company XML rather than the hex XML. This is more logical, ans also simplifies some code. The 1830 and 1835 XMLs have been changed accordingly, the other games not yet. Also changed ImageLoader such that a missing preprinted tile does no longer throw an exception (the hex now stays empty). Erik Vos |
From: brett l. <wak...@gm...> - 2006-07-28 21:32:21
|
I've been looking at how to address this problem. It seems that there's a limitation to our current XML definitions for Tiles.xml . Having "value" as a property of the station means that we can't specifiy any deviations when there are two copies of the same tile with differing values on the map. I propose a change to our XML: This is our current version: <Tile id="-901" colour="red"> <Station id="city1" type="OffMapCity" value="-1" position="0"/> <Track gauge="normal" from="city1" to="side2"/> </Tile> This is what I suggest to allow us to solve our red tile display issues: <Tile id="-901" colour="red"> <Station id="city1" type="OffMapCity" value="-1" position="0"> <Hex location=A9 values="30,50" upgradeTrigger="Trains Available" upgradeWhen="5"> </Station> <Track gauge="normal" from="city1" to="side2"/> </Tile> I think we should keep the value parameter as deprecated just to allow for a way to globally set the value of all tiles of that type. However, we should add the Hex tag with parameters that can override the global value for a specific hex on a specific map. How does this sound? ---Brett. |
From: brett l. <wak...@gm...> - 2006-07-28 19:06:27
|
On 7/24/06, Erik Vos <eri...@hc...> wrote: > For a break with the Undo stuff, I will try to implement some more > aspects of 1835, of which I had already done several bits a year ago. > Sounds good. > A selection box after selecting 1835 will now ask for the opening > variant to play: Standard, Clemens or Snake. The Start round variants > work, except for some validation rules (cash!). Rather than a separate pop-up, I think we should include this in the Options dialog. I think some sort of "when game X is selected, we populate the dialog with the available options" mechanism would work. > I have chosen this game because (1) it's already partly done, > (2) it adds some interesting new game aspects, and (3) the > extra's are probably not too difficult to implement. > In particular, there are no special private properties > beyond what we already have (except for the Prussian formation). > It is a well-known game too, at least in Europe... > Sounds good to me. Will coding the Prussian formation be generic enough to also handle the CNR in 1856? Or are there specifics about each that might require special-case coding? > Another simple game that should be easily doable is 1851; > only the start round needs extra coding. > Is there an easy way we can differentiate between playable and unplayable games in our UI? Right now, users have no way of knowing what isn't fully implemented until they try to play it. I suspect this may require changing how we populate the game list, but perhaps that might be a good thing for a few different reasons. ---Brett. |
From: brett l. <wak...@gm...> - 2006-07-26 23:30:33
|
I committed a couple quickie changes to disable the load/save buttons in the UI. This should decrease some of our user's confusion until we have load/save implemented. I've also disabled the Set Scale option in GameStatus until we can get a chance to actually get map rescaling to work right. ---Brett. |
From: Erik V. <eri...@hc...> - 2006-07-24 21:18:54
|
I have added Redo now, and 'normalised' some more localised texts. For a break with the Undo stuff, I will try to implement some more aspects of 1835, of which I had already done several bits a year ago. A selection box after selecting 1835 will now ask for the opening variant to play: Standard, Clemens or Snake. The Start round variants work, except for some validation rules (cash!). Next thing will be the map, and then the pre-Prussian certificate swaps. The initial version will not enforce the Company availability sequence and the Prussion formation start and end times, all of which will initially be left to the player's honesty. I have chosen this game because (1) it's already partly done, (2) it adds some interesting new game aspects, and (3) the extra's are probably not too difficult to implement. In particular, there are no special private properties beyond what we already have (except for the Prussian formation). It is a well-known game too, at least in Europe... Another simple game that should be easily doable is 1851; only the start round needs extra coding. Erik Vos |
From: Erik V. <eri...@hc...> - 2006-07-22 23:10:20
|
Undo should now cover all Stock Round actions, including company start and flotation, but still except player turn changes. As expected, implementing undo strongly enforces a discipline of implementing various action types in a generic way. Simple certificate buy and sell actions were easy, because these were all handled through a few central routines. But starting a company (i.e. buying the presidency) followed a different path, and quite a number of changes were needed to align this action with the other code. This even affected the StartRound code (because of B&O). So it is all for the good, but a lot of work... The Priority Deal is now shown in the Status window ("PD"). On localisation: I think two types of text should not be localised because it is pointless: 1. action commands, as there are internal and never displayed, 2. prints to System.out, which are usually forgotten debug messages. Erik Vos |
From: John A. T. <ja...@ja...> - 2006-07-20 01:52:02
|
Ok, I have spent some time figuring out Iain's code and thinking about the different games that need to be implemented, and here is the basic algorithm I am working on: Bitvectors are used to store connectivity between nodes and edges. Nodes can be various types of stations (cities, towns, off-board areas) or internal connectivity nodes (corresponding to junctions between hexes). Edges are essentially track. These connectivity bitvectors are incrementally maintained as tile is placed. A RouteSet object stores a set of Routes, as well as a bitvector of all edges used in any routes. Each Route knows the train type it is building a route for, a bitvector of nodes that have been used on the route, a list of nodes used (the bitvector is only used for speed, you could do it by simply searching the list repeatedly), an array of bitvectors keeping track of the nodes/edges left to be explored for each depth in the route, and the statistics of the route in question (the total value, how many stations of different types have been seen, etc). Unlike Iain's code (which generated all possible routes, then tried all possible assignments of trains to routes), this algorithm will build them together. I believe that this will be more efficient, but also it will be necessary to easily implement some of the constraints various games place on sets of routes. The top level algorithm looks like this: public void RouteSet.buildRoutes(RouteRecorder goodRoutes) { for(int train=0; train<numtrains; train++) { route[train].reset(); } while(1) { int curtrain=0; while(curtrain<numtrains && route[curtrain].nextRoute()) { curtrain++; } if(curtrain>numtrains) break; if(isValid()) { goodRoutes.saveRouteSet(routes); } } } So basically, it goes through all the trains and for each train every possible route (including 0 or 1 nodes) that doesn't interfere with the routes of other trains. For each one, if it is legal (which would include things like 1860's requirement that the runs of all a corporation's trains intersect), then it is saved for use by the caller. The algorithm (in pseudo-Java, especially making up for lack of operator overloading) for iterating through all possible routes: // returns true when no more possible routes public boolean Route.nextRoute() { int depth=numNodes; boolean f; while(depth>=0) { while((v=next[depth].getNext())>=0) { // for depth=0, the next[] bitvector contains node numbers of stations reachable by the current company // for other depths, it contains edge numbers if(depth>0) { f=appendEdge(v); } else { f=appendNode(v); } // if node was acceptable, we have a new route if(f) return false; } // can't add more, so try removing one and going to the next possible node removeNode(); } // nothing to remove, reset for next pass reset(); return true; } BitVector.getNext() finds the next set bit, clears it, and returns its index or -1 if there are no more set bits. When a node is appended, the possible candidates are loaded into the next level's bitvector, which is gradually depleted. This could all be done without bitvectors and doing an exhaustive search through the list of nodes each time, keeping a list of edges per node, etc, but I think this is much cleaner and faster. As an example, here is how simple appendNode/appendEdge/reset are: public boolean Route.appendNode(int nodeIdx) { Node node=getNode(nodeIdx); // could check criteria related to total train length or types of nodes // a train may use if(notAcceptable(node)) return false; nodes[numNodes++]=node; // show that we have used this node and any mutually exclusive with it // (for example, on the same hex where not allowed) seenNodes|=node.mutexNodes; routeStats.add(node); // see if this is a node where we dead-end, or are blocked by tokens // can also query routeStats to handle things like 1860's ability to // run past a single token if(node.blocked(routeStats) || (numNodes>1 && node.deadend())) { // no possible extensions next[numNodes]=0; } else { // plausible edges to investigate are all the ones from this node, leaving out // ones already used, and with a track type compatible with current train next[numNodes]=(node.edges - seenEdges) & train.usableEdges; } return true; } public boolean Route.appendEdge(int edgeIdx) { assert(numNodes>0); Edge edge=getEdge(edgeIdx); Node node=edge.getOtherNode(nodes[numNodes-1]); seenEdges|=edge.mutexEdges; edgeUsed[numNodes]=edgeIdx; if(!appendNode(node.idx)) { seenEdges-=edge.mutexEdges; return false; } return true; } public void Route.reset() { numNodes=0; // only plausible starting points are stations reachable by the current company // and those which the current train may use next[0]=company.reachableStations & train.usableNodes; routeStats.init(); } node.mutexNodes is a bitvector of all nodes that should be marked used if the current node is used, likewise edge.mutexEdges. train.usableNodes and usableEdges are bitvectors of those nodes/edges that are usable by the current train. There are analogous removeNode and removeEdge methods which basically undo what was done in the append* methods. The other methods listed but not defined should be pretty self-explanatory. A bit of housekeeping to avoid duplicate routes (since starting from either end gets the same route) and a few other details are needed. I believe this will cover games with different types of track usable by different trains, games where certain trains may not run certain places or have different values for different trains (1844, 1889), games with specific requirements on how many stations of what types a train may use or may ignore (1826, 1835, etc). It should also handle things like the double track in 18GL, by just having two edges between two nodes that are not marked as mutually exclusive. It does not explicitly handle H-trains, although that should be feasible to handle by looking at the sequence of nodes in a route and counting the number of distinct hexes they are on in routeStats.add(). Constraints on the entire set of train routes being run are easily handled, and special rules about skipping tokens can be handled. So, I believe this basic algorithm will cover most 18xx games currently in print. See any problems with the basic approach? Questions? -- John A. Tamplin ja...@ja... 770/436-5387 HOME 4116 Manson Ave Smyrna, GA 30082-3723 |
From: Erik V. <eri...@hc...> - 2006-07-19 22:31:58
|
I have implemented a very basic Undo facility, currently for stock trading only. The hard part, as expected, is handling the state changes, which are numerous. Each different way of holding some state requires its own Move subclass. For instance, in a stock round, players may not buy shares of companies they have sold before. This state is held in a HashMap of HashMaps (see StockRound.playersThatSoldThisRound), and to manage do and undo of this type of state I need a specific Move subclass, which I have named DoubleMapChange. (I use class names like XxxMove when physical items change location, and XxxChange for state changes). The decision on which level to insert the Action.add() calls is also not always easy. It's mostly done on a pretty low level, sometimes in code that is reused in other actions that are not yet undoable. To cope with this problem, I have implemented Action.finish() in such a way, that is an Action has been opened before (with Action.start()), the moves are added to the action, and executed as a whole (with Action.finish()); in this case Undo is possible. If no Action is open, the move is executed immediately and cannot be undone. This allows for a gradual implementation of Undo. Redo is not yet done, but can be added easily. Beware: not all side effects of share trading are covered yet. Not yet undone are: - Company start (i.e. setting the par price), - Company flotation, - Player turn end (to cope with this, I now empty the undo stack at each turn end). - Some cases of presidency change. - Share price movements (except on selling shares). The Status Window now has an extra Undo menu option, with is greyed out if the Undo stack is empty. I have also 'normalised' a few Log messages around sell buying and selling, using the parameter placeholders (like {0}, {1} etc.) added recently. This is just a start. Erik Vos |
From: Dave M. <da...@mi...> - 2006-07-18 02:17:00
|
On 7/17/2006 04:23 PM, Erik Vos wrote: >Please also keep in mind, that some actions sometimes have side effects >of a different nature. For instance, buying the first 4-train >rusts all 2-trains. Undoing this buy also must move all these 2-trains >back from the bit bucket (actually a Bank portfolio named scrapHeap) >to the companies that last owned these. >All these side effects must be done and undone as one action! > >It is not practical to define separate action classes for each possible >combination of direct and indirect effects. It is much easier >to work with very simple "movements" or whatever you would >like to call these subactions. > >So I would propose: >- An Action class, with do() and undo() methods, containing an >ArrayList of Move objects. >- An abtract Move class, which is the parent of all concrete Moves. >- A bunch of XxxMove class, e.g. CashMove, TileMove, CertificateMove >etc., each of which represents a specific type of minimal change. >Each of the Move objects would also have do() and undo() methods, >undo() being identical to do() with to and from swapped. > >Action.do() would call the do() method of each of the >contained Move objects. Similar with undo. > >Erik. Your example of a Train purchase/Phase advance shows that there is no easy way to Undo an action without knowing what was affected. e.g. how many trains get returned to whom? My take on this problem is that you will have to create a log stream which all the Do actions and Move action write to. This data will be the input to the Undo actions. You will want to structure it appropriately. You will want to write a text log anyways for the player's record. In my game I considered doing this with the actual text of the game log, I played with syntax; recognizable verbs for player actions, and character flags for resulting state changes, but I never built a parser. I implemented Undo, by just checkpointing the game state every player/corp turn, and only allowing a full turn roll back. Dave. > > -----Original Message----- > > From: rai...@li... > > [mailto:rai...@li...] On Behalf > > Of brett lentz > > Sent: 17 July 2006 20:44 > > To: Development list for Rails: an 18xx game > > Subject: Re: [Rails-devel] Undo / Redo design > > > > I was just thinking, that there's another option that exists. > > > > I'm thinking that it probably will require more work than the other > > options, but it may be beneficial for us to do it because of the > > advantages in simplifying some of the complexity of the application. > > > > We can define a parent object (Action) and/or interface (Actionable) > > for our model objects to inherit from. > > > > Each object then, inherits a basic Do and Undo methods that can be > > overridden when needed. For classes that do more than one thing, the > > Do method can take the name of the action to take, and call the > > associated methods that will take the desired action. > > > > Then, the UI code can be reworked to call these Do and Undo methods > > and we can make all other methods private to prevent them from being > > called directly. > > > > >From there, we can create a stack and assure that each Do method adds > > its parent object to the stack. This makes Undoing a matter of popping > > the object off the stack and calling the Undo method. Any calling > > parameters can be accessed via an array held by the object. > > > > > > ---Brett > > > > On 7/17/06, Erik Vos <eri...@hc...> wrote: > > > I have also thought about this subject in the past weeks. > > > > > > Usually an action falls apart in several sub-action > > > (which I tend to call moves). An Action can contain any > > > number of moves; the determining factor is which combination > > > of moves constitute an "atomic" action, i.e. a series of > > > moves (changes) that must be executed and possibly undone > > as a whole. > > > > > > For instance, selling a share involves at least: > > > 1. The movement of a certificate from a player's portfolio > > > to the Bank Pool (another rportfolio), > > > 2. The movement of some cash from the Bank to the selling > > > player (both are CashHolders). > > > 3. A price drop, accompanied by the movement of the > > > company's token on the Stock Chart. > > > > > > One could express this in XML as follows (this does not mean > > > that I want to store the Undo stack in that way, although > > > it is an option): > > > <Action> > > > <MoveCertificate company=PRR seqno=2 from=Player-1 to=Pool/> > > > <MoveCash amount=67 from=bank to=Player-1/> > > > <MovePrice company=PRR from=G6 to=G7/> > > > </Action> > > > > > > For many type of actions this is easy to implement, as many > > > movements already exist in much this way in the existing code > > > (see for instance Bank.transferCash() and > > Portfolio.transferCertificate()). > > > Of course, it becomes tricky when state changes enter the picture. > > > For instance, a just floated company must be unfloated in an Undo, > > > and such an activity does not yet exist. > > > > > > I am thinking to build up an Action gradually. > > > As soon as the user's request has been validated in StockRound or > > > OperationRound, Action.start() is called, which creates a > > new (empty) > > > Action object. > > > Then the changes are executed, each being registered in the > > > Action object as additional moves, > > > e.g. with Action.add(new MoveCash (...)). > > > Finally Action.end() is called, closing the action (and perhaps > > > executing it, see below). > > > > > > Action.undo() should then undo the last action. > > > > > > Stacking can be easily added this way. > > > > > > One main decision to take is whether the changes should be executed > > > parallel to creating the Action object (so that the existing code > > > remains much the same), or that it is the Action object that, > > > when finished, actually performs the changes. > > > > > > Perhaps the latter option is better, as it enforces developers > > > to implement all changes, including state changes, in a > > symmetric way. > > > > > > I think this is a similar (or perhaps the same) choice as you > > > have presented below. > > > > > > Erik. > > > > > > > > > > -----Original Message----- > > > > From: rai...@li... > > > > [mailto:rai...@li...] On Behalf > > > > Of brett lentz > > > > Sent: 17 July 2006 07:31 > > > > To: Development list for Rails: an 18xx game > > > > Subject: [Rails-devel] Undo / Redo design > > > > > > > > I've been thinking about how to approach implementing Undo/Redo. > > > > > > > > It seems to me that there are two basic strategies that we > > > > can attempt. > > > > > > > > In each of them, we need to create a stack to store > > actions. Then, we > > > > can place the stack in front of or after the code to execute the > > > > action. > > > > > > > > The basic flow would look something like this: > > > > > > > > Stack before Action (Stack as EventHandler): > > > > 1. Stack object receives call from UI to take an action. > > > > 2. Stack stores action taken > > > > 3. Stack object calls model object to resolve action. > > > > > > > > Stack after Action (Stack as a Listener): > > > > 1. Model code receives call to act. > > > > 2. Model resolves action > > > > 3. Model notifies Stack object of action just taken. > > > > > > > > > > > > I haven't really done much of an analysis of which > > approach would be > > > > more work or have additional implications. There also > > could be other > > > > approaches I haven't thought of, as well. > > > > > > > > What are your thoughts on this? Is there a solution with an > > > > obvious advantage? > > > > > > > > > > > > ----Brett. > > > > > > > > -------------------------------------------------------------- > > ----------- > > Take Surveys. Earn Cash. Influence the Future of IT > > Join SourceForge.net's Techsay panel and you'll get the > > chance to share your > > opinions on IT & business topics through brief surveys -- and > > earn cash > > http://www.techsay.com/default.php?page=join.php&p=sourceforge > > &CID=DEVDEV > > _______________________________________________ > > Rails-devel mailing list > > Rai...@li... > > https://lists.sourceforge.net/lists/listinfo/rails-devel > > > > > > > >------------------------------------------------------------------------- >Take Surveys. Earn Cash. Influence the Future of IT >Join SourceForge.net's Techsay panel and you'll get the chance to share your >opinions on IT & business topics through brief surveys -- and earn cash >http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV >_______________________________________________ >Rails-devel mailing list >Rai...@li... >https://lists.sourceforge.net/lists/listinfo/rails-devel |
From: Erik V. <eri...@hc...> - 2006-07-17 22:03:54
|
I have committed some basic Action-related classes in a new package game.action. These classes should enable implementing an undo for simple share buying actions (without side effects), which I will try to do later this week. Erik. > -----Original Message----- > From: rai...@li... > [mailto:rai...@li...] On Behalf > Of brett lentz > Sent: 17 July 2006 21:43 > To: Development list for Rails: an 18xx game > Subject: Re: [Rails-devel] Undo / Redo design > > I think that looks like it would hit most of the important points I > was thinking of. > > I think that might work. > > ---Brett. > > > On 7/17/06, Erik Vos <eri...@hc...> wrote: > > Please also keep in mind, that some actions sometimes have > side effects > > of a different nature. For instance, buying the first 4-train > > rusts all 2-trains. Undoing this buy also must move all > these 2-trains > > back from the bit bucket (actually a Bank portfolio named scrapHeap) > > to the companies that last owned these. > > All these side effects must be done and undone as one action! > > > > It is not practical to define separate action classes for > each possible > > combination of direct and indirect effects. It is much easier > > to work with very simple "movements" or whatever you would > > like to call these subactions. > > > > So I would propose: > > - An Action class, with do() and undo() methods, containing an > > ArrayList of Move objects. > > - An abtract Move class, which is the parent of all concrete Moves. > > - A bunch of XxxMove class, e.g. CashMove, TileMove, CertificateMove > > etc., each of which represents a specific type of minimal change. > > Each of the Move objects would also have do() and undo() methods, > > undo() being identical to do() with to and from swapped. > > > > Action.do() would call the do() method of each of the > > contained Move objects. Similar with undo. > > > > Erik. > > > > > -----Original Message----- > > > From: rai...@li... > > > [mailto:rai...@li...] On Behalf > > > Of brett lentz > > > Sent: 17 July 2006 20:44 > > > To: Development list for Rails: an 18xx game > > > Subject: Re: [Rails-devel] Undo / Redo design > > > > > > I was just thinking, that there's another option that exists. > > > > > > I'm thinking that it probably will require more work than > the other > > > options, but it may be beneficial for us to do it because of the > > > advantages in simplifying some of the complexity of the > application. > > > > > > We can define a parent object (Action) and/or interface > (Actionable) > > > for our model objects to inherit from. > > > > > > Each object then, inherits a basic Do and Undo methods that can be > > > overridden when needed. For classes that do more than > one thing, the > > > Do method can take the name of the action to take, and call the > > > associated methods that will take the desired action. > > > > > > Then, the UI code can be reworked to call these Do and > Undo methods > > > and we can make all other methods private to prevent them > from being > > > called directly. > > > > > > >From there, we can create a stack and assure that each > Do method adds > > > its parent object to the stack. This makes Undoing a > matter of popping > > > the object off the stack and calling the Undo method. Any calling > > > parameters can be accessed via an array held by the object. > > > > > > > > > ---Brett > > > > > > On 7/17/06, Erik Vos <eri...@hc...> wrote: > > > > I have also thought about this subject in the past weeks. > > > > > > > > Usually an action falls apart in several sub-action > > > > (which I tend to call moves). An Action can contain any > > > > number of moves; the determining factor is which combination > > > > of moves constitute an "atomic" action, i.e. a series of > > > > moves (changes) that must be executed and possibly undone > > > as a whole. > > > > > > > > For instance, selling a share involves at least: > > > > 1. The movement of a certificate from a player's portfolio > > > > to the Bank Pool (another rportfolio), > > > > 2. The movement of some cash from the Bank to the selling > > > > player (both are CashHolders). > > > > 3. A price drop, accompanied by the movement of the > > > > company's token on the Stock Chart. > > > > > > > > One could express this in XML as follows (this does not mean > > > > that I want to store the Undo stack in that way, although > > > > it is an option): > > > > <Action> > > > > <MoveCertificate company=PRR seqno=2 from=Player-1 to=Pool/> > > > > <MoveCash amount=67 from=bank to=Player-1/> > > > > <MovePrice company=PRR from=G6 to=G7/> > > > > </Action> > > > > > > > > For many type of actions this is easy to implement, as many > > > > movements already exist in much this way in the existing code > > > > (see for instance Bank.transferCash() and > > > Portfolio.transferCertificate()). > > > > Of course, it becomes tricky when state changes enter > the picture. > > > > For instance, a just floated company must be unfloated > in an Undo, > > > > and such an activity does not yet exist. > > > > > > > > I am thinking to build up an Action gradually. > > > > As soon as the user's request has been validated in > StockRound or > > > > OperationRound, Action.start() is called, which creates a > > > new (empty) > > > > Action object. > > > > Then the changes are executed, each being registered in the > > > > Action object as additional moves, > > > > e.g. with Action.add(new MoveCash (...)). > > > > Finally Action.end() is called, closing the action (and perhaps > > > > executing it, see below). > > > > > > > > Action.undo() should then undo the last action. > > > > > > > > Stacking can be easily added this way. > > > > > > > > One main decision to take is whether the changes should > be executed > > > > parallel to creating the Action object (so that the > existing code > > > > remains much the same), or that it is the Action object that, > > > > when finished, actually performs the changes. > > > > > > > > Perhaps the latter option is better, as it enforces developers > > > > to implement all changes, including state changes, in a > > > symmetric way. > > > > > > > > I think this is a similar (or perhaps the same) choice as you > > > > have presented below. > > > > > > > > Erik. > > > > > > > > > > > > > -----Original Message----- > > > > > From: rai...@li... > > > > > [mailto:rai...@li...] On Behalf > > > > > Of brett lentz > > > > > Sent: 17 July 2006 07:31 > > > > > To: Development list for Rails: an 18xx game > > > > > Subject: [Rails-devel] Undo / Redo design > > > > > > > > > > I've been thinking about how to approach implementing > Undo/Redo. > > > > > > > > > > It seems to me that there are two basic strategies that we > > > > > can attempt. > > > > > > > > > > In each of them, we need to create a stack to store > > > actions. Then, we > > > > > can place the stack in front of or after the code to > execute the > > > > > action. > > > > > > > > > > The basic flow would look something like this: > > > > > > > > > > Stack before Action (Stack as EventHandler): > > > > > 1. Stack object receives call from UI to take an action. > > > > > 2. Stack stores action taken > > > > > 3. Stack object calls model object to resolve action. > > > > > > > > > > Stack after Action (Stack as a Listener): > > > > > 1. Model code receives call to act. > > > > > 2. Model resolves action > > > > > 3. Model notifies Stack object of action just taken. > > > > > > > > > > > > > > > I haven't really done much of an analysis of which > > > approach would be > > > > > more work or have additional implications. There also > > > could be other > > > > > approaches I haven't thought of, as well. > > > > > > > > > > What are your thoughts on this? Is there a solution with an > > > > > obvious advantage? > > > > > > > > > > > > > > > ----Brett. > > > > > > > > > > > -------------------------------------------------------------- > > > ----------- > > > Take Surveys. Earn Cash. Influence the Future of IT > > > Join SourceForge.net's Techsay panel and you'll get the > > > chance to share your > > > opinions on IT & business topics through brief surveys -- and > > > earn cash > > > http://www.techsay.com/default.php?page=join.php&p=sourceforge > > > &CID=DEVDEV > > > _______________________________________________ > > > Rails-devel mailing list > > > Rai...@li... > > > https://lists.sourceforge.net/lists/listinfo/rails-devel > > > > > > > > > > > > > > > -------------------------------------------------------------- > ----------- > > Take Surveys. Earn Cash. Influence the Future of IT > > Join SourceForge.net's Techsay panel and you'll get the > chance to share your > > opinions on IT & business topics through brief surveys -- > and earn cash > > > http://www.techsay.com/default.php?page=join.php&p=sourceforge > &CID=DEVDEV > > _______________________________________________ > > Rails-devel mailing list > > Rai...@li... > > https://lists.sourceforge.net/lists/listinfo/rails-devel > > > > -------------------------------------------------------------- > ----------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the > chance to share your > opinions on IT & business topics through brief surveys -- and > earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge > &CID=DEVDEV > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel > > |