I am in the final stages of putting this game together - I'd say that at this time I have a working demo that encompasses of the following:
Before I get into the details of describing some cool JavaScript code all behind this, you may be wondering where/how do I test all this. I have a local test environment (running a heavily customised Ubuntu server) but I have also rolled this project out to a small amount of friends - and my choice was to use Amazon EC2. If you haven't used the EC2 environment before -- it allows you to run your own virtual machine in the cloud - accessible everywhere, and the best thing is that for new users, it's free for a whole year. There is a lot of material out there that can help you to setup a virtual server with the necessary options, as well as recommendations on how to setup the virtual machine to run a node.js project. I found this post by Ben Nadel the most useful.
Let me share a screenshot of the application now (compare it with the screenshot shown in episode 2 of the article series) of the gameplay and the GUI (or should we say, WUI?).
The initial screen that players see - both have got 5 cards assigned and the first card in the discarded pile is placed automatically.
During the gameplay, you can see how many cards the other player has in their hand.
And finally, announcing the winner.
You have probably noticed the "It's your turn" and "It's your opponent's turn" messages, it's a great addition to the game as before the only indication a player had whether it's his/her turn or not was to either see the discarded pile updated or the remaining cards counter decrease by one (indicates that the opponent draw a card) - none of these are pretty, so a solution had to be made. Without anything further to do, I give you the Messaging
module - a new JavaScript class that essentially sends messages to players connected to the websocket server, with some extras added - it can:
Messaging.prototype.sendToAll = function (event, message, socket, player) {
for (var i = 0; i < player.length; i++) {
socket.sockets.socket(player[i].id).emit(event, message);
}
};
Messaging.prototype.sendToAllButPlayer = function (
event,
message,
socket,
players,
player
) {
for (var i = 0; i < players.length; i++) {
if (players[i].id != player.id) {
socket.sockets.socket(players[i].id).emit(event, message);
}
}
};
Messaging.prototype.sendToAPlayer = function (
event,
message,
socket,
players,
player
) {
for (var i = 0; i < players.length; i++) {
if (players[i].id == player.id) {
socket.sockets.socket(players[i].id).emit(event, message);
}
}
};
And the server calls the appropriate functions in the draw
and play
methods.
messaging.sendToAPlayer(
'turn',
{ myturn: false },
socket,
room.players,
player
);
messaging.sendToAllPlayersButPlayer(
'turn',
{ myturn: true },
socket,
room.players,
player
);
The frontend is always listening for the turn
message to be emitted by the server and acts accordingly:
socket.on('turn', function (data) {
if (data.myturn) {
$('#progressUpdate').html("It's your turn.");
} else {
$('#progressUpdate').html("It's your opponent's turn.");
}
});
And there you have it, messages are being sent between client(s) and the server, making the necessary updates.
The project is nearly finished and once the code is cleaned up, I will commit the codebase to GitHub, however there are still a lot of things to do. I need to implement Room/Table creation, additional rules for the card game (there are a number of action cards, which, upon played, allow the player to make special requests - i.e. if an Ace is played, the player can ask for a suit, and the next player has to either play a card of the requested suit, or counter with another Ace and make a new request). Also, the frontend needs some makeover. Until next time!