In this article, you will learn how to design a group Sudoku game. The idea is simple, when you update a cell, the same cell should get updated for all members of the group so that all can solve the same problem faster, together.
Introduction
There is a famous saying: "None of us is as good as all of us" (by Kenneth H. Blanchard). This simply means that if we solve a puzzle together as a team, we can solve it faster than anyone else in the team. Let's try it out with Sudoku. Yes, this Sudoku here is not about competing with your rival, this is about solving the Sudoku as a team player. Here, each one solves the Sudoku puzzle written in Angular js, which will synchronize with others screen via signalR.
SignalR and web sockets has proven itself to be a mind blowing technology when it comes to real time update from the server in web application any field. Some of the examples include cricket score update, stock market relate app, chat application, or multi-player online games. This article will demonstrate the use of SignalR with AngularJs in group/team Sudoku web application. Technically, this article can be treated as a simplified solution on how we can use SignalR with AngularJs to solve problems together, even if we reside at different geographical locations. To keep things simple, no database has been used. All data resides in static dictionary/variable, which, you might want to keep in persistence storage in your real application.
Background
Sudoku is one of the most popular puzzle games of all times. When we used to solve Sudoku, we used to get to solve it together on paper where my colleague used to help and we still used to note the time how long it took to solve it. This puzzle is just the re-invention of the same wheel, but, with multiple steering. The idea is simple, when you update a cell, the same cell should get updated for all members of the group so that all can solve the same problem faster, together.
About the Game
The rule of the game is the same as that of popular Sudoku game. The only difference is: here you will play with your colleague instead of against him. (And all will have a win-win result. :P). If you are unaware of the rules of the Sudoku game, please visit http://www.sudoku.com/.
Below are the screenshots of the puzzle:
Using the Code
Now gear up to understand the code written to build the game. This game is developed in Visual Studio 2015, AngularJs, and SignalR.
Sudoku Class
The Sudoku
class contains the grid, group name and level. The Sudoku grid contains is a collection of GridRow
which in turn contains an array of GridCells
. GridCell
stores the cell value along with other information like RowIndex
, ColIndex
, whether the cell is part of puzzle (Freezed
property), etc.
SudokuHub and SignalR Communication
The SudokuHub
class is basically the signalr hub that communicates between client and server to send the set of messages. Two of the major functions of this class are GetSudoku
and UpdateCell
. GetSudoku
method is called when user is entering for the first time to the Sudoku Group. After that, UpdateCell
will be called each time user updates the cell and the same cell will be broadcasted to all members of the group.
public void GetSudoku(string groupName)
{
var group = _Gropus.FirstOrDefault(x => x.Name.Equals(groupName));
Clients.All.getSudoku(db.GetSudoku(groupName));
}
public void UpdateCell(string groupName, GridCell cell)
{
db.UpdateSudoku(groupName, cell);
var sudoku = db.GetSudoku(groupName);
var updatedCell = sudoku.Grid[cell.RowIndex].Cells[cell.ColIndex];
Clients.Group(groupName).cellUpdated(updatedCell, sudoku);
}
AngularJs View
The AngularJs view is simply a grid that contains 9x9 cells. This is achieved by using ng-repeat
on sudoku.Grid
model.
//
<div class="sudoku">
<div class="sudoku-row" ng-repeat="row in sudoku.Grid">
<input type="number" class="sudoku-cell"
ng-repeat="cell in row.Cells"
min="0" max="9" step="1"
maxlength="1" ng-readonly="cell.Freezed"
ng-class="{'sudoku-cell-readonly': cell.Freezed,
'has-success': cell.IsCorrect}"
ng-change="onCellChange(cell);" ng-model="cell.Data" />
</div>
</div>
//
sudokuService Service
AngularJs service named sudokuService
has been used for all communication to the signalR server. The service mainly contains three methods: init
, on
and invoke
. As the name suggests, init
method is used to initialize the signalR server connection, on
method can be used to register the event handler where a custom signalR event can be registered at client side. You need to have corresponding signalr
method at server side in your signalr hub. invoke
method can be used to call the server side signalr method explicitly from the signalr hub.
service.init = function () {
var deferred = $q.defer();
$.connection.hub.start().done(function () {
deferred.resolve();
}).fail(function () {
deferred.reject();
console.log('Could not Connect!');
});
return deferred.promise;
};
service.on = function (event, callback) {
service.sudokuHub.on(event, function (result) {
if (callback) {
callback(result);
}
if (!$rootScope.$$phase) {
$rootScope.$apply();
}
});
};
// Please see attached code for full source code.//
The above code snippet demonstrates the signalr service. service.init
method returns the promise
object so that any call can be done easily once signalr connection has been started. This can be used the same way any promise is being used in angularjs. service.on
method takes 2 parameters, the event
and the callback
. callback
is the JavaScript function that user wishes to call when the event has been triggered.
sudokuPlayCtrl
sudokuPlayCtrl
is the Angularjs controller for Sudoku play view which handles all UI related logic for it. It mainly triggers three methods of sudokuService
:
init
: to get and initialize the sudoku of present room onCellChange
: This method is called when user updates the value in Sudoku grid cell. In this case, it triggers updateCell
method at server side to broadcast the same update to all members of the room. cellUpdated
: This event is triggered when someone else updated the Sudoku grid cell.
Create Group
Now, you can create your own group and play with your friends, colleagues or family members. For that, just click on create group link on Sudoku home page and then other members can join the same group. Each group should have separate set of Sudoku game and can be filled by any user in the group.
Things To Do
Just like any other prototype or concept, this prototype is also evolving and has a way to go to be rich in feature. Following are the things I have planned to implement in the near future depending on the feedback and my available time for it.
Create Sudoku
Currently, the concept has a hard-coded single sudoku puzzle. To make it more effective, the puzzle needs to be generated dynamically with difficulty level. I will try to provide the same soon.
Create Rooms and Invite Friends
The fun with team Sudoku will really come when you will be able to create a private room and be able to invite only the friend you wants to play with. You may expect this in my next update soon.
Auto-Validation Option
You may not be correct everytime. Once your friend has entered a wrong value in any cell, you might not want to get misled. In such case, validation while broadcasting the updated cell make sense.
Coloring and Status
It is also needed to have the status that each member filled how many cells and assign a color to each member. So, you can easily see each members contribution and their filled items in a different color.
More Updates
As and when I get the feedback, I will try to implement them over here and make it more feature rich. For now, this is just a simple group Sudoku game where you can solve a puzzle collectively. Hope you will play and enjoy the game.
Points of Interest
Apart from SignalR communication with Angularjs, this article can also be treated as a sample on some basic elements of Angularjs for beginners, like, how to call $q
service, how to call Angularjs service, etc.
Update: Since this project became older, I am working to re-write this in .NET 6 and Angular 12. Stay tuned for the next release.
History
- 8th December, 2015: Initial version
- 18th December, 2015: Created group feature added + Issue fix