Hyston blog
About • Archive • RSS

Developer diaries #2 2D Iterators

October 19, 2018

One of the first thing, that people learn about programming is control flow and, in particular, loops. I can clearly recall how we have implemented two dimensional loop in qbasic in middle school. It’s very simple task, nevertheless, recently I have found a way to make it complex and cumbersome. May be task, that I will explain below, would be good for a interview.
Let’s imagine, that we have two-dimensional array W x H. Simplest way to iterate throw would be double loop directly from 6th grade:

for(int i1 = 0; i1 < H; i1++)  
       for(int i2 = 0; i2 < W; i2++)  
	      var el = array[i1 * W + i2];  

I hope I didn’t make a mistakes here, I haven’t checked this
But what if we need to get chunks of data from left to right?

var container = array[]
for(int i1 = 0; i1 < H; i1++)
    for(int i2 = 0; i2 < W; i2++)
	    container.add(array[i1 * W + i2]);

This is basically transforms one array to another, not good. We need to use iterators. What is iterators? Here is abstract interface:

protocol BaseIterator
{
   T? next();
   func clear();
}

We should have ability to create iterators from containers and call next() until it will not return null (or nil or whatever crap, which mean, that array is over). Internally it should store some counter or pointer to next element. clear() function set counter back to the beginning of collection.
For one dimensional array, that allocates in memory lineally, such pointer is trivial. But what should we do in case two dimensional array?

protocol CellsIterator {
    
    func next() -> LineCellsContainer?
}

class BaseCellsIterator {
    
    internal let gameModel : GameModel
    internal var line = LineCellsContainer()
    
    internal var y: Int = 0
    internal var x: Int = 0
    internal var w: Int { return self.gameModel.fieldWidth }
    internal var h: Int { return self.gameModel.fieldHeight }
}

Here is cropped version on baseIterator in my game and also protocol for cells iterator. I use them both because protocols with associated types (PAT) exist and annoy me, but that is a theme for another post.
So, here I store:

    func next() -> LineCellsContainer? {
        // clear container
        line.clear()

        // if end of line, increment to next one        
        if x >= w {
            x = 0
            y += 1
        }

        // if it was last line, then we need to stop        
        if y >= h {
            return nil;
        }

        // iterate through end of the line        
        for _ in x ..< w {
            
            let cell = getCell(x, y)
            
            x += 1
            
            if(cell.isBlocked) {
                break
            }

            line.add(cell)
        }
 
        // return container
        return line;
    }

I have added comments to make it more readable, although it is already pretty simple. Unfortunately, swift doesn’t allow creation of for loops with outside variable, otherwise it would be even simpler for(;x<w;x++).
Another remark: because of the game logic (cell.isBlocked), it is possible, that loop should stop, return current container and continue with new one.
This all seems very simple, however it took for me several days to figure out how to do it right. And now I have iterators not only for 4 directions (up, down, left, right), but also by diagonals. I’m using this to check game logic for player move and at another place, to check, can player make any move at all.
DRY


Half-Life

September 26, 2018

Last time I have played Half-Life twelve years ago, on my first fall semester, when I got cold, stayed in bed for couple days with fathers laptop. I have played multiplayer a lot since, but never a storyline.
It was my favorite game in school and, at some point, i swear, I remembered all maps from the beginning until, at least, to chapter "surface tension". But twelve years later I have found, that although I still remember chapters order, but have completely forgot all small details and the entire feeling from game is slightly shifted from regular first person shooter to brilliant sci-fi story action game.
And 20 years old graphic technology is not breaking experience of watching slightly scary movie about brave scientist.
Half-Life
Enterance to final boss is magnificent


Month with Android

September 9, 2018

Day 0.

Holding camera button lead to device reboot. Double sized control panel is awesome.

Day 1.

This morning I got notification "what's new?", it advertised some games from play store.
Spotify launches much faster, than next train stop.
Where is my keyboard magnifier???

Day 2.

Separate button for app switcher is good, but why it doesn't show all apps?
I took some photos, deleted all, but one. Half hour later: they are all in my Google photos. What the ... ??
Reordering grid of icons on home screen is similar to playing brocken Tetris.
I really miss Drafts and good markdown editor. I'm sure, that there are good Android alternatives, just don't have time to find one.

Day 3.

Photos inverse scrolling direction. Weird.
Piece of lint dropped to headphone jack and I cannot connect headphones anymore. This is silly and not related to iPhone, but in last 20+ years of using 3.5mm jack I met this problem once a couple months, but not on a third day of using phone. Just coincidence.
Twitter official app started ads on opening client, and, when I have tried to close it (show Android software buttons), it turned volume on. Instant delete. Started looking for alternatives.

Day4.

Download icon, that appear, when some apps started internal downloading something is awesome.

Day5.

Here maps already know where is home and where is work. I have installed it in Saturday at home and now is afternoon Monday. How??..
Also, have found good apps: Fenix for Twitter, PocketCast for podcasts and JotterPad for markdown.
"What's New?" app shared personal data with Sony by default. This app was preinstalled and it is not possible to uninstall.

Day.6

Google maps showing small preview in screen, when switching to other app is brilliant idea, by first glance. However, this pip rect always blocked something important on current app - send button on messenger or play in podcast player. Yesterday I made 10 km walk in new area, and, as always in this case, I have constantly switching between four apps - camera, maps, messenger and podcast player. Greatest benefit compare to my old iPhone 6 is that I have never experienced dropping application out of memory, all four apps worked fine and coordinate with each other. Biggest flaw was lack of smartwatch connection and Bluetooth headphones, so most of my 2hour walk I have done with phone in my hand, with cord to my ears, which is not perfect, but definatelly not a Android miss.

Photos ordering is wrong. It's that I have used to another swipe direction, latest content should be on right bottom side! At least, in countries, where people reading from left to right and from top to bottom.

Day 22

I have a lot of problems more and I can't wait to buy new iPhone. Even if it would be just two-years old SE or 7, I really miss some apps, airpods and apple watch connectivity.


Developer diaries #1: Mock

September 4, 2018

Summer is over, and I'm trying to remind myself, that I have a blog. I have almost finished a post, how I used Android for a week (spoiler alert: it's fine, but I don't like it), but for now I want to throw couple things, that appear during my joby-job job:


20-80

July 5, 2018

20% of work make 80% of job result. Thats the difference between big and small companies: when I have worked on small company, we skipped last mile and we have worked on these 20%, that can be done by one or two developers. So we had made core app, all interesting tasks, but we didnt polish everything, we didnt fix errors, that were not frequent, we cut a corners here and there.
That is the difference for a big companies: they can not skip some part of work. If they will skip not 20%, but even 2%, it can lead to lose tens of thousands of %currency_name%. And were small team can consist of couple developers, enterprise require tens of developers, most of which will do boring, sometimes repeatable job, sometimes with double and triple checking everything. And tens of developers require proper management team, they need HR, PO, CTO and all that shit. Just to be sure, that 100% is done.


← Next Previous →