How I participated in the Angular Attack hackathon, and what came of it

    Hello friends. My name is Alexey, I work as a front-end developer at the St. Petersburg office of Wrike, and today I want to talk about how I participated in the AngularAttack hackathon , where my work Sherlock in the final protocol took first place.

    About what it is and how it started


    The inspiration was last year’s example of Andrei , with whom we work in the same team.
    Moreover, in order to fit into the participation, you do not need anything but a tuned working environment ... and readiness to write code for 48 hours on weekends without sleep and rest.
    As a rule, good developers have no problems with the first or second.

    Hackathon conditions are elementary. Everything happens remotely. Start - at midnight GMT on Saturday, finish - at midnight on Monday, in a team of 1 to 4 people, no electronic content can be created (no code, no assets) before the start of the event, although drawing block diagrams and devising algorithms on paper - as much as you like. Each participant is given a private repository on GitHub, in which he puts the code in the process of writing. A prerequisite is that the output should be a web application using the Angular framework. Freely distributed content and libraries in your application can be used subject to the terms of the license (for example, a link to the author). All.

    But what would you write?


    Somewhere a couple of weeks before the start, I began to think about the idea. Thoughts about the future application arose as follows:

    • It should be easy to use - there will be a lot of work, judges are ordinary people, and if a person in a couple of tens of seconds does not understand how to use the application, he most likely will not understand further.
    • It should be easy to develop. I was going to participate alone, and the idea should be such as to be trivial to manage to realize it in these 48 hours. Therefore, all sorts of thoughts about the backend and stuff disappeared immediately - only a single page app, only the front, only pure Angular.
    • It should not be very banal - you need an idea to catch. Again - the judges do not evaluate the coolness of the code, but the work and appearance. Therefore, you can write the game “gallows" (as by the way, many did), but a person who plays it once will never return to the game (and one of the evaluation criteria is the so-called Utility / Fun - how useful, fun, and , in general, causes a desire to use it again and again).

    In general, if you come up with a completely new idea that meets all three points, then you can easily become a millionaire. I didn’t succeed in the end - I decided to focus on my own implementation of the already well-known, old-old logical puzzle , which worked under DOS, and in which we flirted with our students as a student.

    Its essence is relatively simple: there is a field of six rows of six cells, in each row there may be picture elements combined by some sign, for example, faces in the first row, signs of the zodiac in the second, digits in the third and etc. At the beginning of the game on the board, some correct combination of the position of all elements unknown to the player is made up, and the goal of the game is to use the proposed set of tips to determine the correct position for each element on the board.



    At the start of the game, some elements may already be open (for example, the letter L in the bottom row of the board - this means that it is exactly here). In cells, where the correct element has not yet been precisely determined, the remaining possible options are shown. For example, in each of the remaining cells of the lower row, based on the current position, options from the letters H, O, M, E and S are still possible.

    Next, we look at the tips. In the game itself, you can move the mouse cursor over the tooltip and a tooltip will appear with its description (although in English, but I believe that this is not a problem for Khabrov’s people), here I’ll just mention that each tooltip in the bottom row under the game board means that both elements indicated on it must be in the same column.

    If we look, for example, at the seventh prompt on the left, we will see that the letter L should be in the same column as the number 5. L is already open with us - that means we confidently open 5 above it (left click). Now let's look at the fifth prompt on the left (Aries zodiac sign in the same column as E). Neither Aries nor E are open yet, but L is open, which means that there is definitely no Aries above it. Therefore, we can remove the Aries sign from the cage above the letter L (right click).

    Thus, by applying hints for opening pictures, the position of which we can determine unambiguously, and removing elements that definitely cannot be in the corresponding cells, we gradually reduce the uncertainty, and in the end, we come to the only true solution to the puzzle. Well, or we don’t come - until the skills are honed, you can easily go the wrong way with the solution, but in this case the cunning Undo to Last Correct button will help, which rolls back the position to the last correct one to an error, and you can continue solving the puzzle from the right place.

    Rushed !, or a little about algorithms


    On Friday evening, before the start of the event, I set up the environment. I chose Google Dart as the language - there was no doubt: despite the fact that TypeScript is the main trend in developing for Angular, almost the entire frontend in our company is now written on Dart, and I decided not to reinvent the wheel. He also made the settings for git and hosting - this year the organizers did not provide a place to post work, hoping that each of the participants would decide this question. I had hosting, and this did not cause problems, but maybe someone should know about such things in advance.

    On Saturday, at the start of the hackathon at three nights, he decided not to get up, woke up at about six in the morning. I decided - today I am writing logic, tomorrow - UI. If I don’t fit with the logic of the day, then tomorrow morning I decide whether it makes sense to continue at all.

    But with this very logical part, by the way, there was a rather interesting challenge.

    For the puzzle it was necessary to generate: 1) the correct position on the board, 2) the position that was originally open, and, most importantly, 3) a set of tips that allow you to translate the open position into the correct one. Moreover, a set of tips should ideally be necessary and sufficient - the task should be solved, and at the same time, in a unique way.

    Of course, there were no problems with the generation of a random correct position and initially randomly opened several pictures, but it was not immediately thought how to create a set of tips for a specific position. Trying to solve the problem head-on, I tried to add random hints to the set until they allowed me to open the board completely (for this I needed a method that tries to solve a position with this set of hints - either solves it or reports what to do about it) impossible), but was faced with the fact that the set often turned out to be redundant, and it was not even a matter of duplicates (they could just be tracked) - there was a situation when a certain subset of prompts was completely duplicated by another subset, with the same elements in them was not, and the final set was still not enough to fully open the board.

    In the end, I decided to do the following: initially create a deliberately redundant set of tips, and try to solve their position. If it didn’t work out, we recreate the set, but if it works out, we throw it out recursively at one prompt and again try to find a solution. At some point, the task will cease to be solved, then we take the minimum set of tips with which the solution was found, and declare it final. It worked.

    There were fears that all of these recursive constructions would brutally slow down (all calculations take place in the browser on the client, while the algorithm is running, we try to solve the puzzle programmatically several hundred times, and the solution procedure has its own recursion ... and so on), but, surprisingly, after a little optimization, it worked pretty fast. On modern machines, a position with tips is built almost instantly, on slow and ancient ones - about a second).

    Naturally, it didn’t work the first time. I didn’t immediately take into account some things, something was so difficult to test without a UI that I had to write a couple of unit tests, which, in turn, also found a couple of errors, but the fact is that on Saturday evening the logical part of the game I was, and it was possible to start the implementation of the graphic part and user interaction.

    Graphics? Everything is already drawn to us!


    For a game board pictures were required that met the condition: 6 sets of 6 pieces, each set is united by a certain attribute. I myself would have been tortured to do them - unfortunately, it was in drawing that the bear trampled both my ears, hands, and all my fingers in addition, including those on my legs. But here I saved a set of Emojione emoticons, which have recently been freely included in the supply of Photoshop CC, to which I have a completely official subscription as part of the Adobe plan for photographers, so the license conditions are met. However, without a subscription, I think everything would be alright too: Emojione is a freely distributed library.

    By the way, I naturally packed the images into a sprite using responsive backround sprites css - this made it possible to display images simply by setting a class for elements, moreover, if necessary, it is easy to change their size. A lot has already been written about the technology itself - for example, you can read it here .


    And yes - I still had to draw a few pictures myself, including arrows on the tips, a couple of round buttons for the help page, a background for the playing field that simulates a piece of paper in a box, and the logo that appears when the game loads. However, standard Photoshop textures and shapes were used here, and there were no unsolvable problems with this.

    But if you have a normal designer in your team, know that you are already incredibly lucky.

    Stirlitz on the verge of failure


    Sunday it took to create and lick the UI. The simplest playable version was ready around noon, but it was still far from a comfortable game - there was neither Undo functionality, nor notifications that the position was solved correctly / incorrectly, nor difficulty levels. The first two features were purely technical, but with the last, by the way, I did just that: I made three levels - light, medium and heavy, which differ only in the number of initially open cells. For Easy, it is always 10, for Medium - 5, but on Hard - from zero to two. Yes, in some hard cards, not a single cell was initially opened. And moreover, the task in this case is also solved!

    At some point, I realized that every tooltip needed a tooltip that would describe in detail what it was, otherwise it would be extremely difficult for judges unfamiliar with the game to understand what this whole motley set of pictures meant. Having scanned the available libraries with components for Angular Dart on the Internet, I settled on Angular Material, in which this tooltip was available. One trouble - the library was in beta, which in turn required the last beta of Angular. Well, where ours didn’t disappear - I upgraded the assembly from stable Angular 2.2.0 to beta 3.0.0, looked that nothing seemed to break, and everything worked as it should, was delighted, and began to attach a beautiful tooltip to the prompts.

    It took about two hours, and here is what happened in the end:


    Now a small digression, for those who are not familiar with the Dart language. The code written on it cannot be executed directly in a regular browser; it must be compiled in Javascript by a special command. But for development, Google is releasing a special version of the Chromium browser, Dartium, which contains an integrated virtual machine that can execute pure Dart code. It is clear that all development is in this special browser - it is much faster, and the final version is compiled only when it needs to be put somewhere.

    So - tooltips have earned, I thought - it's time to put the intermediate version on an external hosting. Compiled, uploaded to a remote server, tried to open it in Chrome - and was very surprised that the application crashes with an error somewhere deep in the bowels of Angular. Stektreys did not say anything. Two hours ago, when I uploaded the previous version, without tooltips, it worked perfectly. Uncompiled code running in Dartium also worked without problems. But the assembled - no.

    And then it became clear - the transition to the Angular beta is probably not such a good idea, as it seemed at the beginning - no one guarantees its performance. It was suddenly realized that time was already moving quite quickly towards the evening of the second day, and the tooltips would have to be redone from scratch, and it was insanely sorry for the time wasted.

    As a last resort, I read profile forums for about half an hour - and on some account I suddenly found a question from a participant with the same problem as mine. Moreover, they answered him - twenty minutes ago (!), Advising him to update the Dart SDK itself to the latest version, released a few hours before.

    Frantically update Dart on the local machine, collect the package, put it on the server, check - it works.

    I exhale - this time it whizzed past.

    And a serious lesson - it’s probably impossible to take everything into account, but before the hackathon starts, you need to think through as much as possible what and how it will be used, which libraries, whether they are compatible with each other, which all these pitfalls might have. If I immediately realized that tooltips are only in beta versions of Angular material, I probably would not have taken the risk and knew right away that I needed to write my own. Or would look for another library.

    At the finish line ...


    The rest of the evening went to creating a help page. By that time, the eyes were already piled up, the amount of coffee drunk per day was measured in dozens of cups, but I really wanted the so-called onboarding - the process of familiarizing the user with the application - as effective as possible. Given the limited time spent on implementation, it was probably not very good, but nevertheless, better than nothing - at least the user sees that they are being taken care of, and before showing him an application that is not always intuitive understandably, trying to explain what awaits him.



    Already closer to the night I spent a couple of hours catching spelling and stylistic errors, after which I decided that trying to improve something further was pointless - my head was thinking very tight by then, and instead of fixing jambs, it was easy to spawn new ones, collected the final version, laid out hosting it, filled out a work card and sent it for review.

    In total, the whole process of writing the code took a little more than thirty hours (yes, I still slept sometimes), plus a couple of hours on the chart. And in general, the whole development went quite smoothly, with the exception of the Angular beta story, but all is well that ends well - next time I will be more experienced.

    ... and unexpected result


    The evaluation and discussion process lasted a week. The game did not collect a lot of feedback (not only judges, but also other participants of the event could express their opinions and opinions), although this feedback was mostly positive, and the ratings from the judges were almost always high. But, to be honest, it was hard to imagine that on the day the results are announced, I will see my game in first place out of hundreds of participants' works. For me, it was, first of all, just an interesting programming experience in this format - two days, an idea, implementation, a ready-made competitive product at the output, although the final victory was certainly a pleasant bonus.

    And only my wife, who dragged me coffee and food to the computer for two days, did not initially doubt this victory. Thanks her.

    The working version of the game is here:http://sherlock.netmafia.ru/ (resolution of the Full HD monitor is highly recommended).

    The source code repository is here: https://github.com/izolenta/sherlock , maybe someone will be interested to get acquainted with the Google Dart language.

    Thanks for reading - and good luck!

    Also popular now: