chaitu236 / TakServer

Server to handle online TAK games
https://www.playtak.com
GNU General Public License v2.0
35 stars 8 forks source link

Alternate Rule Objects (e.g. to test FPA solutions) #22

Open TreffnonX opened 8 years ago

TreffnonX commented 8 years ago

The USTak Association has set up a committee to test and evaluate solutions to first player advantage (mostly, but not solely in regards to tournaments). To test those, it would be of great help, if people could select alternate game rules when creating games. The idea is to attach rule objects to all games starting with the introducing patch. That class would define things like turn order, for instance. Ultimately they would regulate the flow of any in progress games, and the respective identifier for that rule would be stored with the database entry, to identify this game as variation game, and signify which variation was played. The class could then be extended to represent different rules and prototypes could server as copy-blueprints for the objects actually used in the games. This would be both a server- and client side modification, and heavily impact the way the server functions. The potential benefits are that we have the chance to test rules otherwise not practically testable with a large number of players.

I can modify the server myself and send you the pull request for review, but truth be told, it would probably require a lot of modifications to solidly implement. I would set it up with a bunch of JUnit tests to prove base functionality. Would you consider taking those changes into consideration?

chaitu236 commented 8 years ago

Sure, I'm open to take the changes. Though I'd like to help with implementing this, I don't have much time - but keep me in loop for the design decisions - I could maybe contribute there. Let me know how you plan to implement.

TreffnonX commented 8 years ago

Great, I'll try to formalize the general idea, so you can cross check it. The basic idea is to enable the rules object to control the game flow. so whenever an expected input arrives, it is directed to the rules object, which then handles the execution and initiates the expected followup move. It would behave like a state machine, and access the game state to modify the rules. The state machine would grant input privileges to the client and await the respective response. Possible inputs would probably be:

...and possibly others that I just can't think of right now.

The server also needs to evaluate the end of the game individually. For that, the rule object offers a function to evaluate the board. This is required for any scoring methods and for flat komi variations, where the final game state is actually relevant. So in that sense the rule object would take over the evaluation of the board on game end.

All this is just a basic expression of the idea. Interface- and class wise I have not started to put thought into it yet, as I first wanted to see, if you would go with it.

chaitu236 commented 8 years ago

Wouldn't it be better to have a derived class for each kind of Game with the minimum functionality present in its base class instead of having a rules class?

I may be misunderstanding but are you saying that the client will have generic changes to handle any kind of variant instead of variant specific changes?

TreffnonX commented 8 years ago

Wouldn't it be better to have a derived class for each kind of Game with the minimum functionality present in its base class instead of having a rules class?

The idea was to minimize the effort of introducing a new variant, so the idea was to set it up with configurations for rule objects. So I planned it with a single governing class, but it's also possible to do this with polymorphism and derived classes, though that would mean changing/writing code each time a new variant is introduced, instead of adding a configuration, which seemed more stable and flexible in the long term.

I may be misunderstanding but are you saying that the client will have generic changes to handle any kind of variant instead of variant specific changes?

My initial thought was to set up 'steps' which can represent calculatory steps or client inputs steps (on the server). So a game would be set up as state machine made up of a graph of states which handle either calculation or input. The client would not know by which rules it played other than by an identifier for the rules object, for example 'classic' or '3P' or '3PFK' or thelike. Those identifiers would show in the games list and in a selection box on game creation (also in PTN, maybe the notation, etc). But ultimately the client does not know the sequence of steps. It would get told by the server, if an input is expected from the client. This way, once initial changes are made to the client (moving from expecting a certain sequence of game steps towards expecting input requests and updates) the client can handle any kind of variant that is covered by the input types the client can provide. If a new input type is required, minimal changes to the client are required (adding an input type and an identifier for it). if no new input type is required to run a new kind of variant, no adaptions to the client need to be made. The list of available variants would be sent to the client on login. I had this in mind this way, because it would mean a medium amount of modifications at the start, and a minimal amount of changes later on (adding configs for game variations, adding input types, if ever they become essential).

There is an additional bonus to doing things this way. It is very easily testable with unit tests. Testing one class for various configurations and making it work is more solid than making a base class and overriding behavior each time. By taking the programmatic sequence out of the client, and putting it solely on the server, we would also reduce a potential breaking point.

TreffnonX commented 7 years ago

I will go for this and try to make it work. I will make the client recognize it as TAK-protocol-v2, or something, so that the classic behavior is still the default, but if the server greets the client with the protocol update after handshake, the client will activate the alternate protocol and run on that. This way, I can deploy both ends without collision. Then, after the deployment proves successful and stable, the 'old' protocol could be removed (if need be), or left as a fallback in case of serious problems at a later stage.

chaitu236 commented 7 years ago

Ya go ahead. Just make sure nothing in the old breaks, and the new code is easy to maintain and is easy to separate from the rest of the code.

Daenyth commented 7 years ago

I was reading up on this discussion last night and I'm planning to address this in my taklib project - I have some rudimentary designs so far but I'll be fleshing it out more over the week, and I'll talk about how I've laid it out once I'm sure I won't change it too much.

Daenyth commented 7 years ago

I implemented a version here: https://github.com/Daenyth/taklib/blob/289b1349cac419e0a8a46b61dd44773313631bc2/taklib/src/main/scala/com/github/daenyth/taklib/Game.scala#L53-L132

So that client code could do Game.ofSize(5, DefaultRules). I'll add one of the FPA proposals next I think

Daenyth commented 7 years ago

I finally got around to finishing it - it's in master branch now. https://github.com/Daenyth/taklib#add-custom-rules