Monday, February 12, 2018

how to write a game in c++ from scratch

Disclaimer: I am in no way a game developer, this is the story of my tries and errors.

So, we decided to create a project to exercise c++17. Let it be a game. It has been decided to use cmake and gtest and tdd. Perfect. And then we realized we have no idea how to build an architecture for a game. Googled it. Found this outdated tutorial:

Well, at least the author provided some basic architecture we can use. So, let's write a ping-pong game!

The tutorial is easy and I thought I could have it running in a day. But alas! 3 days in we are stuck with environment configuration.

This is how it goes: we use sfml as our graphics lib. At first I wanted to use cmake to fetch the master from github, build and link it, just as it is done in the gtest how-to. But, it has around 10 dependecies. We cannot rely on the developer to install all of them by hand, right? Right? So, it has been decided to pre-build sfml statically. Does it mean that I will have to build all 10 deps statically too? And what if each of them has 10 dependencies? omg.

Monday, December 4, 2017

haskell, yesod and Kabbalah

That moment when you try to google haskell-yesod for more tutorials, stumble upon a something called Kabbalah, thinking "wow, that's such a good naming, the words fit really good together, with their Hebrew origin" and then realize it's not some piece of software, it's actual Kabbalah.

Tuesday, November 28, 2017

Yesod tutorial for beginners, haskell web programming

Well hello

So, I started to learn web programming with haskell and yesod. Yesod book was too hard for me to grasp and I couldn't find a plausible entry-level tutorial, that would not be written 5 years ago and could compile. So I took an article by  yannesposito and fixed it.

I saw some effort to fix the tutorial on the school of haskell here, but its formatting gave me an impression, that it is not maintained anymore.

Prerequisites: a basic understanding of haskell. If you lack it, I recommend you to read this.

1. Work environment setup

I use stack instead of cabal. I, together with yesod manual, really recommend you to use it. Not to mention, that using yesod you don't really have a choice. The only way to create a new project is to use stack  ¯\_(ツ)_/¯.

1.1 So, let's get us some stack!

It's as easy as running either one of the two.
curl -sSL | sh
wget -qO- | sh

I strongly recommend using the latest version of stack instead of just apt-getting it. Ubuntu repos often contain older and buggier versions of our favorite software.

[optional] Check what templates are available
$ stack templates

1.2 Generate a template project.

You can generate a yesod project only using stack. The init command has been removed from yesod.  Use yesod-sqlite template to store you blog entries (see "Blog" chapter). Of course, if you don't intend to go that far with this tutorial, you can use yesod-simple. So, let's create a new project called "yolo" with type yesod-sqlite.
stack new yolo yesod-sqlite

1.3 Install yesod

You should be able to run your  project, for this you have to install yesod. This takes about 20 min.
stack install yesod-bin --install-ghc

1.4 Build and launch

Warning, first build will take a looong time
stack build && stack exec -- yesod devel

And check your new website at http://localhost:3000/
(3000 is the default port for yesod).
For more detailed reference about setting up yesod look here.

My versions of stuff:
stack:  Version 1.5.1, Git revision 600c1f01435a10d127938709556c1682ecfd694e
yesod-bin version:
The Glorious Glasgow Haskell Compilation System, version 8.0.2

2. Git setup

You know it's easier to live with a version control system.
git init .
git add .
git commit -m 'Initial commit'

3. Echo

Goal: going to localhost:3000/echo/word should generate a page with the same word.

Don't add the handler with `yesod add-handler`, instead, do it manually.

Add this to config/routes, thus adding a new page to the website.
/echo/#String EchoR GET
#String is the type of the input after slash and haskell's strict types prevent us from getting SQL injections, for example.
EchoR is the name of the GET request handler, GET is the type of supported requests.

And this is the handler, add it to src/Handler/Home.hs.
getEchoR :: String -> Handler Html
getEchoR theText = do
    defaultLayout $ do
        setTitle "My brilliant echo page!"
        $(widgetFile "echo")

This tiny piece of code accomplishes a very simple task:
  • theText is the argument, that we passed through /echo/<theText is here>
  • for it we return a defaultLayout (that is specified in templates/defaultLayout.hamlet and is just a standart blank html page)
  • set page's title "My brilliant echo page!"
  • set main widget according to templates/echo.hamlet
 Also, remember that RepHtml is deprecated.

So, let's add this echo.hamlet to the <projectroot>/templates! As you can see it's just a header with the text that we passed after slash of echo/<word here>.
<h1> #{theText}

Now run and check localhost:3000/ :)

If you're getting an error like this
 Illegal view pattern:  fromPathPiece -> Just dyn_apb9
    Use ViewPatterns to enable view patterns
 Illegal view pattern:  fromPathPiece -> Just dyn_aFon 

then just open your package.yaml file, that stack has automatically created for you and add the following lines just after `dependencies:` section:
default-extensions: ViewPatterns

Else if you're getting something like this
yesod: devel port unavailable
CallStack (from HasCallStack):
  error, called at ./Devel.hs:270:44 in main:Devel
that most probably you have another instance of site running and thus port 3000 is unavailable.

If you see this warning
Warning: Instead of 'ghc-options: -XViewPatterns -XViewPatterns' use
'extensions: ViewPatterns ViewPatterns'

It's okay, so far stack does not support 'extensions' section in .cabal file. Catch up with this topic in this thread.

If you see this warning
Foundation.hs:150:5: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for ‘isAuthorized’:
        Patterns not matched: (EchoR _) _

That means, that you need to add this line to Foundation.hs
isAuthorized (EchoR _) _ = return Authorized 
All it does is grants permissions to access localhost/echo to everybody.

 4. Mirror

Goal: create a page /mirror with an input field, which will post the actual word and its palindrome glued together, as in book -> bookkoob or bo -> boob.

Add the following to config/routes to create a new route (i. e. a page in our case).
/mirror MirrorR GET POST

Now we just need to add a handler to src/Handler/Mirror.hs
    import Import
    import qualified Data.Text as T

    getMirrorR :: Handler RepHtml
    getMirrorR = do
        defaultLayout $ do
            setTitle "You kek"
            $(widgetFile "mirror")

    postMirrorR :: Handler RepHtml
    postMirrorR = do
        postedText <- runInputPost $ ireq textField "content"
        defaultLayout $ ($(widgetFile "posted"))

 Don't be overwhelmed! It's quite easy to understand.

And add the handler import to src/Application.hs, you will see a section, where all other handlers are imported

import Handler.Mirror

Mirror.hs mentions two widget files: 'mirror' and 'posted', here's their contents


<h1> Enter your text
<form method=post action=@{MirrorR}>
    <input type=text name=content>
    <input type=submit>

<h1>You've just posted
<p>#{postedText}#{T.reverse postedText}
<p><a href=@{MirrorR}>Get back

There is no need to add anything to .cabal or .yaml files, because stack magically deducts everything on its own :)

Don't forget to add the new route to isAuthorized like in the previous example!

Now build, launch and check out your localhost:3000, you must see something similar to my pics

stack build && stack exec -- yesod devel

And after you entered some text in the form, you should get something like this

5. Blog

Again, add Handler.Article and Handler.Blog to Application.hs imports.
This is contents of Blog.hs

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}

module Handler.Blog
    ( getBlogR
    , postBlogR
    , YesodNic
    , nicHtmlField

import Import
import Data.Monoid

import Yesod.Form.Nic (YesodNic, nicHtmlField)
instance YesodNic App

entryForm :: Form Article
entryForm = renderDivs $ Article
    <$> areq textField "Title" Nothing
    <*> areq nicHtmlField "Content" Nothing

getBlogR :: Handler RepHtml
getBlogR = do
    articles <- runDB $ selectList [] [Desc ArticleTitle]
    (articleWidget, enctype) <- generateFormPost entryForm
    defaultLayout $ do
        setTitle "kek"
        $(widgetFile "articles")

postBlogR :: Handler Html
postBlogR = do
    ((res, articleWidget), enctype) <- runFormPost entryForm
    case res of
        FormSuccess article -> do
            articleId <- runDB $ insert article
            setMessage $ toHtml $ (articleTitle article) Import.<> " created"
            redirect $ ArticleR articleId
        _ -> defaultLayout $ do
                setTitle "You loose, sucker!"
                $(widgetFile "articleAddError")

Article.hs contents

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}

module Handler.Article

import Import

getArticleR :: ArticleId -> Handler Html
getArticleR articleId = do
    article <- runDB $ get404 articleId
    defaultLayout $ do
        setTitle $ toHtml $ articleTitle article
        $(widgetFile "article")

Add this to conf/models

    title   Text
    content Html

This to conf/routes

/blog               BlogR       GET POST
/blog/#ArticleId    ArticleR    GET

And add these lines to src/Foundation.hs. This is a hack, but you cannot view the contents unauthorized, right? :) Drawback: all users on the internets will be able to see your post.

    isAuthorized BlogR _ = return Authorized
    isAuthorized (ArticleR _) _ = return Authorized

All done! What will you see:

Wednesday, November 22, 2017

haskell first steps

Well hello

So I started to learn haskell.
And I know it's old news, but still, look how short haskell's quick sort implementation is!

qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) =
    let smaller = qsort (filter (<= x) xs)
        bigger = qsort (filter (> x) xs)
    in smaller ++ [x] ++ bigger

And my first steps with haskell are:
  1. learnyouahaskell
  2. exercism/haskell
  4. Real World Haskell, but I must say, that this book is incredibly vague, obfuscated and is the opposite of clear. It is the most hard to get book that I've read so far, and it's not that haskell is complicated, no. It's the book.
  5.  Web services for haskell -- yesod (how-to).

Wednesday, November 15, 2017

Best free courses from coursera: 2017 reality check

Well hello

Coursera was the sublimation of the ultimate good on the Internet: free courses on programming, machine learning, probabilistic graphical models and so much more! But alas, all good has to come to an end. As of Dec 2017 Daphne Koller and Andrew Ng has made quite a few steps towards monetizing the platform (and who can blame them? they are a startup after all). All the legendary courses, whose names were well known among my fellow programmers were either deleted (Standford Compilers) or turned into paid specializations (Stanford Algorithms and even the Probabilistic Graphical Models by the previously mentioned founder of the Coursera Daphne Koller!).

Compilers course logo /

 But, there's still some fun to explore for me and my fellow penniless adventurers! And here is the top of best free courses on coursera, 2017 reality check:

1. Algorithms I and Algorithms II by R. Sedgewick of Princeton.


The top of the top in my personal courses list of all time. Sedgewick, who actually invented the red-black tree with his colleague in Stanford, in addition to being a real life grandpa from Up! is a brilliant teacher, it is quite impossible not to understand what he wants you to understand :) He goes sometimes into so much details, that I had to listed at speed 1.5x, but for some people it could be quite a good pace. Also, you get to solve 5 puzzles in each course for free! And they are really cool. Highly recommended, 100/100.

2. Machine learning by Andrew Ng of Stanford.


The legendary founding father of coursera keeps his first course free of charge, and I'm quite happy with that! Extremely engaging lecture and even more so programming assignments keep you busy for the whole of 11 weeks! Loving it!

3. Cryptography I by D. Boneh of Standford.


In his work, Boneh goes through all the basics and details of -- you guessed it -- cryptography. I would say, the course contains enough material for the whole undergraduate course.

4. Introduction to Mathematical Thinking by K. Devlin of Stanford.


Haven't seen a lot of this course, but it was enough to decide to definitely return to it in the future.  Introduction to Mathematical Thinking will help you develop a creative way of thinking and solving all kinds of problems, for example, how to prove a theorem, that nobody was able to solve before.

5. Game Theory by   M. O. Jackson and K. Leyton-Brown of Stanford and British Columbia.


Never thought what to do if we play the game against another player, that knows that we play the game and also knows what is our best strategy, as do we know about his. Who will win in this situation? Game theory can answer that. It's not your usual application on game theory for competitive programming problems, neither is it a game development course, but it's quite interesting and kinda gets you on the other plane of thinking.

And down here, let me have a quick rant on coursera specializations. They ruin all the magic of free education, they really do! And the platform is constantly shoving them down my throat to that extent that it's impossible to search for courses only, one can only search for the keywords, like "machine learning", and then get 100000 "only $49 a month!" specializations, which is absolutely not what one was hoping for. 

So, coursera, please give us our free education back! I understand you need machine time to review the programming assignment, but come on! I can volunteer you some of mine, and I think many of us will! I will even pay for certificates, I promise :)

Sunday, November 12, 2017

Rich father poor father, magic of thinking big and other books of the year

Well hello

The year is getting to its end, who would not think it's the most suitable time to analyze the books I've read so far?

1. The magic of thinking big by D. J. Schwartz

 / penguin random house /

The most inspiring book so far.

2. Rich dad poor dad by R. T. Kiyosaki

/ wikipedia /
#1 personal finance book of all time? Looks more like garbage to me.

3. You are a badass at making money by J. Sincero
 / /
To some point inspiring. Bullshit to a lot of other points.

4. #GIRLBOSS by S. Amoruso

 / goodreads /

Total bullshit, a poetic retelling of main character's bio.

5. Take your time by Easwaran
  / goodreads /

Total bullshit, the content of this small book can be expressed in one sentence: less bustle, more meditation.

6. Accelerated C++ by A. Koening and B. E. Moo


As the authors state at the beginning of the book, it is a transcript of the course they used to teach to C programmers. Agonizingly obvious at times and mediocre at others.

Next year I'll try to read at least one book a month.

Saturday, March 25, 2017

Как я стала тем, кем я стала

... или как стать лучше меня.

На недавнем митапе в честь Outreachy вокруг меня собралось некоторое количество девушек, одна из которых задала мне вопрос, обозначенный в описании. Не знаю, что именно она имела в виду, но тем не менее, здесь я хочу грубо очертить мой путь начинающего разработчика ПО.

1) Линукс, у меня Дебиан.
2) ACM ICPC и codeforces.
3) Курсера.
4) Изучение разнообразных иностранных языков, в первую очередь английского.
5) Восприятия учебы как нечто, что продлится всю жизнь (life long learning), учеба вопреки университету.
6) Больше литературы по программированию и самого программирования.
7) Занятие пассивно проведенного времени, например в маршрутке, очереди или на скучной паре.
8) Общение с более опытными людьми в разных сферах человеческой жизнедеятельности. Некоторые из них могут оказаться полными говнюками, но не переживайте, их немного. Как выразился один мой знакомый: "Нет в здравом уме такого человека, который вместо помощи новичку посмеялся бы над ним".
9) Last, but not least, Google guide.

Надеюсь, дополнить этот список в будущем.