Can this be modeled in a state machine pattern? - oop

I wanted to model a game (for practice reasons) using a state machine design pattern involving the following states:
Initial: The game-host sets up the game with some configuration parameters
Published: The game is visible to other players, so that they can join
Ready: As soon as the game is full (maximum number of players are reached), the host can start the game
Running: The game is running
Finished: The game is over, players can see some statistics about the game
However, after reading up on the state machine pattern, it appears to me that it is only applicable when the states all expose a common interface (e.g. the handleInput-method in this article: http://gameprogrammingpatterns.com/state.html).
What I intended to have is for the Game to have a publish method in the initial state, that will guide it into the Published state, where it then has a join method, which will guide it to Ready once enough players have joined, and so on.
The goal is to separate concerns here, I don't want a huge Game class having to deal with gathering all the players as well as handling the actual game logic.
Can this be done with a state machine? Or is there any other design pattern I could use for this?

The states expose a common interface but, this has nothing to do with your actual game.
The minimum requirement is to have the set of transitions from one state to the next and a mechanism to create the resulting state based on the previous state and the transition. The common interface deals only with this aspect.
For your initial state, the host sets some values on a GameConfig object. Pressing a "Publish" button is the transition to the next state. On the transition handler you need to create a GameLobby object.
The GameLobby is created with the game's name and expected number of players and deals strictly with adding players and other lobby related functions (such as player chat, which should also be implemented in their own class).
Here, the transition handler is called each time a player joins the lobby. Only when the total number of players is reached do you transition to the next state, "Game Ready". (If the number of playes is not yet equal to the requirements you can transition to a new GameLobby object with one extra player if you want to keep things immutable.)
Along with the GameConfig object, this new state contains a list of Player objects.
From this state, when the host clicks "Ready", in your transition handler you finally create your GameLogic object, based on the GameConfig object and the list of Player objects.
When the game is won, you transition to the "Finished" state which contains the game's statistics and a final transition to "end program".
Each of these main states can, in turn, contain their own state machines.
So, the state machine related interfaces do not restrict the interfaces of the payload.
I also recommend you separate the part related to displaying items on the screen from the part that determines "what" to display. So, each of those state objects would have something like an Init method where they generate a list of sprites that need to be displayed (and attaches any event handlers that are needed for the transitions). A separate object would then take that list and show it on the screen and call the even handlers on user input.

Related

How to Subscribe to a single Event from multiple classes?

I am creating a Draft Room for a football game I am making and have several classes involved with it.
The DraftPick Class will be responsible for raising an Event once the current team has made their selection. However, there are multiple other classes that need to "know" when this event has been fired as well. The Draft Class needs to know so it can remove the player from the list of available players, restart the clock and update the current team on the clock. The DraftNews Class needs to know about this event so it can update the in-draft ListView with the Pick information, and the DraftTicker class needs to know about the event to add the selection that was just made to the scrolling draft ticker at the bottom of the screen.
I'm working in VB.Net, so its not as straightforward as it would be in C#. However, I am thinking the easiest way would be to make the PickMade Event shared so the other classes would be able to simply access the event via DraftPick.PickMade() and simply use an AddHandler. I was wondering if there is an established "method" for doing this, or if what I am considering doing would be OK.
Any advice would be appreciated, first time I've had the need for multiple classes to be listening to an event...

How do I record a player's response?

Basically what I am trying to do is have the player respond to a message in which they are required to input numbers only. From that point, I could parse the String into an int and use it towards the rest of my code. Also, I am trying to make it so this occurs in my event method. Any help is greatly appreciated!
What you essentially want to do is store the player in a container until the next time they talk, then remove them. This, represented in pseudocode, would look like the following:
on your condition:
add player to collection
on player chat:
does the player exist in the collection?
yes: is input a valid number?
yes: proceed with execution, remove player from collection after
no: print error
no: ignore, let event pass
Since the MineCraft protocol does not allow input verifying, there will be cases where the user may submit non-numerical characters. Integer.parseInt, or its sibling valueOf will throw an exception if this is the case.
To prevent memory leaks, you should remove the player from the collection when they log off. Alternatively, you could store them in a weak reference container. A good one for this scenario would be a WeakSet, which you can essentially obtain via Collections.newSetFromMap(new WeakHashMap()). Weak references get garbage-collected if all other references are eliminated, so this reduces the risk of a memory leak.
You should look into the bukkit conversation API. It for doing exactly this. You can find tutorials online, but basically to set it up you do this.
Build a conversation with the ConversationFactory
ConversationFactory HudConvo = new ConversationFactory(plugin)
.withModality(true)
.withEscapeSequence("exit")
.withFirstPrompt(new HudConversationMain(plugin, player, 0))
.withLocalEcho(false);
Conversation conversation = HudConvo.buildConversation((Conversable) player);
Begin the conversation
conversation.begin();
Make the first prompt as a class that either extends one of the input type prompts (i.e. StringPrompt) or implements the Prompt abstract class.
Fill in the methods getPromptText() and acceptInput(). getPromptText() constructs the message to be displayed to the player and acceptInput() takes what the player types and reacts to it with a new prompt.
I hope this helped. If you have questions, feel free to ask.

WinRT Storing Session State Between Page Navigation

I am new to WinRT and was playing around with session state. I am navigating to a page to collect data and then want to return to the main page. Just before navigation I am using:
SuspensionManager.SessionState["CurrentState"] = someObject;
The object contains lists of other mildly complex objects, etc... All seems to be working but is this the correct way to use the Suspension Manager?
I have looked at other posts on the topic and some people report that it is necessary to use [DataContract] and [DataMember] attributes to all the classes that are serialized. I omitted them and it still works, (getting the data across pages). So what is the recommended approach?
I may be reading too much into one aspect your question, but the role of SuspensionManager and SessionState is to store just enough information to bring your application back to the place the user left it if the application is actually terminated while it's suspended.
In the Windows 8 application lifecycle, your app gets 'suspended' if another app comes to the foreground. While your app is suspended all of its state is retained in memory, and if reactivated (you flip back to it) everything* is restored "for free".
A suspended app could, however, also be terminated by the OS (b/c of memory pressure, for instance) and there is no opportunity to react to that scenario in your app, so what you are really doing with SessionState is storing what's necessary to 'recreate' the last place the user was at IF the application had actually terminated. It's essentially an insurance policy: if the application is merely suspended, SessionState isn't really needed.
The 'what's necessary' is the grey area, I could store all of the information about say a user profile that was in progress OR I could save just the userid that indexes into my persistent storage of all the user profile data. I generally have more of a minimalist view and will retain as little as possible in SessionState - I make the analogy that I don't need to remember everything, I only need to remember how/where to get/find everything.
There's an implication as well in your question that you're using SessionState to pass information between pages in your app, and that's not really the intent. Each page of your app is typically connected with a view model, and when you interact with a page of that app, you'd update the view model and drive additional screens and experiences from the changes already in the view model. Leaving one screen of your app and returning the main one would also imply to me that you've persisted what ever information you collected - certainly to the view model, but also to something persistent like a data base or local storage. When you revisit that page, you'd then pull the data back out of your view model (or that persistent storage); the main page doesn't need that information so why hold on to it?
Lastly, since you mentioned being new to WinRT, you may want to check out App Builder, which pulls together a number of resources in consumable chunks to lead you through building an app over a period of 30-days (though all material is available, so you can consume at any pace you want :)) The discussion of lifecycle management that's germane to your question comes in on Day 17 of that sequence.
*"everything is restored for free" doesn't necessarily mean you don't have any work to do when an app comes out of the suspended state. There may be stale data that requires refreshing, and connections or other transient or short-lived entities may need to be refreshed/recreated.

CLLocationManager initialization

I'm working on a web application that enables users to login, only at specific locations. I'm using CLLocationManager and I initialized and called startUpdatingLocation at AppDelegate -didFinishLaunchingWithOptions. My UIWebView is supposed to pull the location at initialization to determine whether user's within the specified locations. However, at the launch of my application, [locationManager location] is always null and updates after my UIWebView is initialized and displayed therefore already sending an error message to the user.
How do I make my locationManager update its location at initialization?
Sounds like you've coded the location stuff correctly. What you are missing (but have seen) is that the update most certainly does not happen instantaneously. You need to "gate" the rest of your UI's presentation (i.e. your webview) on the location information becoming available. There are a lot of ways to do this. A common tactic is to present a full-screen "HUD" or veil with some indicator to the user that the app is initializing or locating them (with an activity indicator, too, is always a nice touch.) Behind that (out of sight to the user) you can be waiting for the location result and then kickoff the appropriate UI update, and then drop the veil.
Any of that make sense or give you some ideas? I've done this plenty of times. Synchronizing async activities (like location updates) with real-time UI updates that make sense can be challenging, but isn't impossible. :-)
You will need to account for an initial nil value in your applications UI and wait for the first location update.
-location
Discussion
The value of this property is nil if no location data has
ever been retrieved.
It is a good idea to check the timestamp of the location that is
returned. If the receiver is currently gathering location data, but
the minimum distance filter is large, the returned location might be
relatively old. If it is, you can stop the receiver and start it again
to force an update
Also you should check out Region Monitoring since you would like for you users to only be able to login at specific locations.

Use Dojo's Publish Subscribe Model

We are working on a portal environment. On one of our page we have two portlets. When some action happens on one portlet, we have to minimize the other portlet and viceversa.
So we feel that this is a suitable situation where we can use Dojo's publish/subscribe model. But I'm a bit confused if I need to use different topics [One when some action happens on Portlet A, and the second topic when some action occurs on PortletB] or one topic [something like minimize]. Can someone please guide me.
This is really up to you, and depends on your needs.
Topics are free-form texts, so you can arrange it in any text format you like.
My own experiences have been to treat a topic as an "event". Therefore, one topic, one event.
My experience has also been that it is tremendous beneficial to implement "commands" in the same system as events -- so you have a universal command/event system.
Events (therefore topics) do not have to correspond to your portlets. For instance, one portlet can have multiple events (if they make sense), or one event can be shared by multiple portlets (for shared functionalities or for cross-portlet communcations).
Parameters and data can be passed with the event (i.e. topic) as arguments.
Now, a good trick I've learnt is to have "sub-topics" -- i.e. topics that are prefixed with an parent topic, when things want to subscribe to a particular instance of event.
Example: Assume we have an event called "/portlets/showhide" which is published by any portlet when it is shown or hidden, together with the id of the portlet and a boolean variable indicating whether it is shown or hidden.
Now, assume that a portlet will also publish topics called "/portlets/showhide/{id}" (with true/false argument) and "/portlets/showhide/{id}/show" (no arguments) when shown, together with the generic "/portlets/showhide" topic (event).
Now assume some handler object is really only interested when the "xyz" portlet is hidden. It doesn't have to subscribe to "/portlets/showhide" and listen to all those events of other portlets that it is not interested in. It can simply subscribe to "/portlets/showhide/xyz/hide". When number of subscriptions increase in a large system, this kind of optimizations can come in quite handy.
You can use one topic in which pass additional parameters. Something like this:
// PortletA
dojo.publish("onPortletAction", [{sender: "PortletA"}]);
// PortletB
dojo.publish("onPortletAction", [{sender: "PortletB"}]);
....
dojo.subscribe("onPortletAction", dojo.hitch(window, window.processAction));
window.processAction = function(data) {
if (data.sender == "PortletA"){
//to do something
}
if (data.sender == "PortletB") {
//to do something
}
}