Paul Cezanne, "Card Players"A long time ago, in Windows 95, there was a Microsoft Hearts game. The game of cards on the network, with opponents around the world. If my memory serves me, in Windows for Workgroups 3.11 (yes, I caught all these artifacts!) There was a version for playing on a local network, using the so-called NetDDE.
Card game did not have to choose a long time. As they say, the rich ... High bridge and preference have disappeared because of their complete ignorance. There was only one thing
left - to
disappear the fool.
The situation was complicated by the fact that so far I have never been involved in developing a “backend”. Googling led me right to the right place -
SignalR .
')
Here I would like to say a few enthusiastic words to SignalR. A well-documented library that best fit my needs. Bores will say that it is only under Windows, well, let them grit their teeth with envy. Although there seems to be her kolkhoz clients for iOS, I have not studied this question in detail.
Next question hosting. Then I did not think long, Azure was at hand.
So, what did I want?
- The way to connect players must repeat the way Microsoft Hearts. Players connect one by one, as soon as the required number is reached - the game starts. For myself, I decided to limit myself to a one-on-one game - and no draws!
- At the very beginning of the players will be a bit - how do they know about each other? Then the idea arose of sending push notifications to anyone who wanted to play when someone launches the application and connects to the game server. In order not to trot users by pushing them, he made a restriction “no more than once in N minutes”.
- I want more detailed statistics, prizes, achievements, etc.
- I want cards of different designs
- I want to play with my friend, and not with whom "whom God sent."
What do I use from Azure?
- AppService is actually an application to which all clients connect.
- SQL server + SQL database - for storing game statistics.
Everything.
Recently, I also used their push notification service. But it seemed expensive (10 bucks a month), moreover, it turned out that because of the Microsoft billing glitch I had been paying for more than a year for these two services! Goring with support led to the fact that they admitted a mistake and offered a month of compensation. After some time, I completely abandoned this service, adding another table to my database for storing signatories on the push and sending them myself from the main application.
At a given time, the cost of hosting monthly is about 400 p. This is only the cost of the SQL server. I have a small outgoing traffic and it fits into the free 5 GB per month.
Development
The development took place at Visual Studio 2015, MVVM framework MVVM light was used for the client.
A little server "kitchen" (aesthetes and the faint of heart is better not to look)
connecting users, sending out pushespublic override Task OnConnected() { if (((DateTime.Now - LastPush).TotalSeconds) > 360) { LastPush = DateTime.Now; Task.Run(() => SendNotifications()); } return base.OnConnected(); }
peep the top card in the deck send a message to your opponent About client
To identify the players, the LiveId functionality was used initially, then the Graph API. When you first start the application, the player is asked to provide access to his account (from it I take only the name and the so-called anonymous id, which looks something like this: "ed4dd29dda5f982a"). However, the player can play anonymously, but then the statistics of his games is not conducted.
For each non-anonymous player are stored:
1. date of the first game / date of the last game
2. name / nickname of the player
3. the number of games played / how many of them are won
4. last IP address
5. received prizes
If there are two non-anonymous players in the game, then before it starts, I get the statistics of the games of these particular players (how many games they played with each other and who won how many). For this purpose, the resulting anonymous id is used in the SQL query.
In the screenshot at the top left you can see an example (clickable):

Screenshot of general statistics (clickable):

In addition, there is a “competition” across countries (anonymous players participate here, information is taken from the IP address):

Players can exchange short messages.
FoolHubProxy.On<string>("ChatMessage", (chatmessage) => synchrocontext.Post(delegate { PlayChatSound(); ShowMessageToast(chatmessage); }, null));
An example of a situation handler is “I take the cards, and the opponent adds me after the game”:
FoolHubProxy.On<byte, bool>("TakeOneMoreCard", (addedcard, lastcard) => synchrocontext.Post(delegate { CardModel card = new CardModel(addedcard, DeckIndex); CardsOnTable_Low.Add(card); OpponentsCards.Remove(OpponentsCards.Last()); if (lastcard) { AppMode = AppModeEnum.defeated; } }, null));
About prizes, cookies, etc.
Every month, the top five players who have scored the most victories, receive a badge of
"For the capture of Berlin .
" Top 50 participants are awarded badges for the best winning percentage (also five). In addition, there are badges for winning “express” (a situation where you have 2, 3 or 4, say, sixes or jacks on the last move). Then they are laid out on the table all at once and you are a fine fellow. There are cookies for victory, when an opponent gives you "in the list". He also gets a consolation, with a skull and bones.
About any additional functionality
The application is free, but it has various additional "buns", designed as InApp Purchases:
- grouping your cards by suit and hints during the game (when you need to beat or toss, suitable cards move up)
- the ability to not show your opponent how many cards you have in your hand. Normally he sees it.
- the ability to always be the first to start the game. Otherwise, the first move is played randomly.
- the opportunity to see the cards repelled in the game
- the opportunity to peek into the deck once a game and find out the next card
- opportunity to "cheat." 3 times per game you can fight back or throw the wrong card, generally any. But the opponent has the opportunity, noticing this, to return the wrong card to you.
Conclusion
As a result of the development of this application, I:
- met with SignalR
- refreshed SQL (queries, stored procedures, functions)
- learned how to host apps in Azure
- Opupel from playing the "fool".
Question
And how on Habré is the case with the
scattering of money from a helicopter distribution in PM promotional codes to those who want it? If you do not give a kick for it, please contact us.