Dot Connect

The Start

I had no intention of coming to the front-end world. I wanted to master back-end with python-django. But my last django project went flop. So, with some frustration, I was thinking what to do next. I decided to dip my toes in the front-end ocean and come back to back-end after that. I asked Ahmed shamim vai for suggestion. He suggested that I work on some small project, as the best way to get first-hand experience is to do real work.

I was looking for ideas. First I thought of building something useful. But as you know it is really hard to come up with something both simple and useful. It seems that bloody everything is already there. So then I started thinking of something ‘useless’. A few days back I saw A.I. Sajib vai posted a photo of a childhood game. Wouldn’t that be cool to be able to play this online with friends miles away? But then it seemed complicated and I was looking for something simpler. I remembered a game Ram-Sham-Jodu-Modhu (I never played though, saw people play). The problem with that was I couldn’t find anybody who knows or remembers the rules. So finally I decided to take the challenge, go knee-depth if necessary and build it. Later I found out that it is not really that complicated.

The Framework

I shared the idea with Shaon vai and he suggested React. I started going through the official React tutorial. I tried React a year ago. I seemed much harder back then. I gave up at that time because the interest was not that much strong then. But this time it came more fluently. The thing here is that coding skill is highly transferable. No matter what you code for, competitive programming, back-end, front-end, coding more and more makes you better thinker. The better thinker you are, the easier it is to catch up new stacks/frameworks. So ‘Whatever you do, it shouldn’t be easy for you.’ is my rule of thumb.

Front-end programming is different though. In other kinds of programming I’ve done so far, program flow is simple. It flows mostly downwards. But in event-driven asynchronous programming, the program flow is more complex. This is why it seems so hard for the first time.

Challenges

The first challenge was how to represent and draw the dots and lines in a web-page. First I thought I would need SVG or something like that. But finally did it with plain HTML and CSS. It was simpler that way.

This is how it looked at first

For representation, I used a js object for each node. So each node has an owner, a right edge and a down edge (which can be on or off).

Then I put together a few logics to make a minimal working version, where you just use the computer screen instead of pen and paper. No score counting, nothing, and only square grids. Shaon vai saw, refactored a bit and suggested to use Redux. This Redux thing seemed super complicated at first. I couldn’t understand why I needed all these complexities. I remember, every time I sat down to read the react-redux tutorial, I gave up in a few minutes, thinking “Oh, I’ll check it out later when I’m in better mode!” 😆😆 The boilerplate codes the redux tutorial uses probably played a role in making redux seem that much complicated.

But when I refactored the app with redux, I saw the sanity in it. The state could be saved, sent and synced very easily. The overall model of react is that you keep some info as state. You write render function to show things to the user according to that state. And then you decide when and how the state should change. Like, when some button is clicked some value in the state should change. Then the render functions are called automatically and the user sees the changes. Using redux takes this idea to a whole new level. Without redux, you have local state in each component. With redux, the state is moved to a central store. I have a feeling that if you love competitive programming, you will love react-redux combination. Because one of the challenges of development with react-redux is to take an old state and calculate a new state, which is much like the problems we solve in CP. Other challenges include figuring out ‘where’ to put ‘what’.

So then using react-redux, I added a few more nuts and screws and it started to look better. Then I deployed it to Netlify. Could use GitHub probably.

Now you can play with a friend. It keeps count of score and doesn’t let you cheat, better than pen and paper 👏

A little better

Now I had to implement communication to enable game-play over the internet. For that, I used socket.io, a simple and powerful WebSocket framework. The basic idea is that a user creates a game using a form in the front-end and a socket.io room is created in the back-end. When a user joins a game they are added to that corresponding room. Now every change in the state is synced.

At this point, I didn’t need to use any DB. The games waiting for an opponent was being stored in a object in the back-end. It is not a permanent storage, as every time the server restarts, the object is lost. Still, it was working. When the user closes the browser window, the game is lost anyway. So didn’t need permanent storage. And as I knew that NoSQL MongoDB enables to store data as objects, that object could be thrown at DB any time.

At this point, I had to start using react-router, because I already had several pages to handle. React router does that pretty neatly. It could probably be done without react-router though.

Look at those shiny connection indicators 😍

Now, to improve the look and feel I used Bulma. I could probably have used bootstrap or something like that. Bulma seemed simple and claimed to be modern. Anyway, it’s all the same to me. I grab a template, modify it here and there. This is how I deal with aesthetic matters.

Using Bulma with react was easy. Included Bulma CDN in the head of the template HTML file and put the root element under some boilerplate. Finally wrap the components in some boilerplate as well to satisfy Bulma.

Much cooler 😎

What if you don’t have a friend right now willing to play with you? You should be able to play with computer. Implemented a function that takes the grid state as parameter and provides a replay. It goes over every possible move in depth of two levels, calculates the maximum possible points and then chooses the best move. Very inefficient and not unbeatable at all. And it works without an internet connection because of the service worker.

At this point, it was completely working. I wanted to share it with the world. But Shaon vai suggested that we save the winning of the users and show a top-chart. And it would also be great to save the games and to be able to continue later. Till now, there was no recognition of an ‘User’. So, had to do some refactoring to associate two users with a game, only they can play that game. An accidental feature that came out is that others can watch the game live using the game link 🙃

Then grabbed the Facebook SDK to implement sign in functionality and to show friends top-chart.

And then had to refactor the server side code to use mongoose instead of {} . I thought I’ll complete it in a few hours. Oh boy! I had to spend more than a week. The thing is that all operations of Mongo in asynchronous. I thought using Promise is all I need to do. But this asynchronous storage operation affects the whole game. It was very frustrating at this point. I was already working on this for more than a month. I just wanted to get rid of it. But bugs kept coming. I forgot why I did many things the way I did them. So when I fixed a bug, another few emerged.

Somehow I fixed all the bugs and it was working again (or so I believe).

Mistakes

I certainly made some mistakes while developing the project. Some of them I can see myself clearly. I haven’t followed many standard best practices, some of them for my indolence, some of them I thought not necessary for this project.

Some Boilerplate

I should’ve kept all the constant strings, like actions types, socket event names in one file. That is to avoid typos I guess. I was just lucky to not face any problem for not following that standard. And I’ve seen that people use action creator functions to create actions. I didn’t do that either. I haven’t discovered yet why It is such a good idea.

Comments

I thought my code is pretty self-explanatory and didn’t put many comments. But as I’ve mentioned already, it was disastrous.

Prop-Types

Then comes prop-types. I started using it in the beginning though. Then I thought it was just waste of time, I had to modify the prop-types every time I change some prop and I was using flexible props for some components. I tell you, it was a great mistake. I wasted a whole day because I wrote xisNext instead of xIsNext somewhere. So prop xIsNext was coming undefined (which yields false ). JavaScript is awesome. You need prop-types.

Tests

I had become a great fan of TDD while learning Django and wanted to write at least some functional tests for this project. But I didn’t know how to write tests with js and was too impatient to learn. I could sure write using python-selenium, but it didn’t seem a good idea.

User Representation

I was too much influenced by the react tutorial tic tac toe game that I implemented the user and gameplay logic almost like that one. Now if I want to enable more than two users, I’ll have to do a painful refactor. I could do better.

Authentication

I didn’t have authentication in mind in the start. It lacks proper authentication system. Now if I want to add proper authentication, a lot of refactoring will be required. I think it is secure enough for a simple game.