Four life lessons learned by playing Hearthstone

March 14, 2016

I’ve played Hearthstone on and off for a few years, since it first came out. As I played more and more, I began to notice parallels between my decision making processes in Hearthstone and in real life. This is a self-reflective post, and probably my first serious attempt to describe the core features of my mentality and decision making process. Although I wanted to write this for a long time, I found it difficult to put my ideas into words because they have been part of my personality for so long.

Why is Hearthstone a good representation of real life? Two reasons:

  • First, it’s a game of imperfect information and chance, so you must take risks and deal with uncertainty. Real life situations are usually like this. Games of perfect information (like chess) lack this probabilistic aspect and behave very differently.
  • Second, Hearthstone is a game about decision making skills, rather than mechanics. Every game has some element of decision making, but many games require doing some mechanical action (eg. last hitting) better than your opponent. Mechanical skills are confined to the specific game and are less likely to be relevant in real life.

By playing Hearthstone, I developed a general internal model for making decisions in uncertain situations. This is a broad criterion and covers many situations in day-to-day life.

Lesson 1: There is always a correct decision, and it’s your job to find it

The goal in Hearthstone is to reduce your opponent’s life to zero. How do you accomplish this? You make a plan, perhaps flooding the board with minions, perhaps unleashing a deadly combination of spells.

For our purposes, it doesn’t matter what your strategy is. At the start of the turn, you look at the cards in your hand, the state of the board, what cards your opponent played before. Call this information the game state. You ponder for a bit and come up with an action that best improves your position.

You execute your action on the board, but you still don’t know what happens next with certainty. There are many things you cannot control, which I will call RNG. RNG is short for Random Number Generator, and I will use it to mean anything you don’t have control over.

I use the term RNG for lack of a better term, but I’m not just talking about random game mechanics. RNG includes any state hidden from you, like your opponent’s hand and strategy.  Think of it as a random variable with a known distribution (eg. you play a card that destroys a random minion, which minion will it hit?) or with an unknown distribution (eg. what is the probability your opponent has two flamestrikes in his deck?). Even if the information is known to your opponent, it’s simpler to treat it as a random variable.

Here’s the model summarized in a diagram:

In any game state, there must be one “correct” action that gives you the highest chance of winning the game. The decision-making player aims to consider all possible actions and choose the best, “correct” one.

As a corollary, decision making should be perfectly rational. Otherwise, if my decision engine generates two different actions depending on my emotional state of mind, they cannot both be correct.

A second corollary is actions should always be justifiable through fundamental values. It’s unacceptable to do things by habit, or because other people are doing it — everything I do should have a positive expected value on the things I want to accomplish.

For me, one of my “meta” goals in life is to make correct decisions as much as possible. This is not to say that I behave like a robot — I still experience emotions like everyone else — but I try to eliminate emotions from my decision making process.

In Hearthstone, doing so gives you the highest chance of winning the game. It makes sense then, by extrapolation, that correct decision making gives you the best shot of getting what you want out of life.

Lesson 2: Information is valuable, treat information gathering as a subgoal

One rule of thumb in Hearthstone is “RNG first”. If you are going to play a sequence of cards, one of which has a random effect, it’s better to play the random effect first. This way you extract information out of the RNG pool of unknowns, and with this extra information you might be able to make a better play.

Another useful thing is to keep track of enemy secrets. Imagine you have this on the board:

You want to play a giant, but you’re worried that the secret is “mirror entity”, which summons a copy of the next minion you play.

Without any other information, you’re in a tough spot. But what if you played a minion last turn and the secret did not activate? Then you know that the secret isn’t mirror entity, and confidently play the giant.

Alternatively, suppose that you don’t have this information handy. One tactic is you can “test out” the secret by playing a small minion, and seeing whether the secret activates. You are paying a price with a normally inferior move, but the information you obtain is valuable for future decisions.

A similar concept occurring in real life is flirting. You’re at a party and you see a cute girl walk by. At first, you make a few playful comments, and observe her reaction and assess if she is interested in you. Flirting isn’t just an arbitrary social custom; it makes sense logically as a way of gathering information.

While information isn’t the final end-goal by itself, even a little information can greatly improve decision making, by eliminating vast swathes of possibilities that no longer need to be considered. Whether it be playing a giant, making a big purchase, or asking someone out on a date, gathering information is a useful subgoal.

Lesson 3: Focus on things you have control over, RNG evens out in the long run

Often in Hearthstone, luck is just not on your side. Have you ever seen your opponent topdeck the pyroblast and instantly win the game? Or that mad bomber that hits you three times in the face? How do you feel?

It’s natural to feel angry when this happens to you, especially if it ends up losing you the game. But eventually I realized how pointless it was to get upset at unlucky RNG. What’s the use of worrying about things you have no control over?

I see this all the time — people getting visibly upset when the bus is late, or when a player on your team goes AFK in a game of league. I try to adopt the opposite mindset: worry about my own decision making and simply accept random events beyond my control.

Let me give you an example. Last term, during an important phone interview, my phone stopped working during the middle of the interview. Calmly I got up and notified the CECA front desk, and waited as they spent the next 20 minutes troubleshooting the problem. Most people would be stressed out at this point, but I didn’t feel stressed at all. Rather than getting upset, my mind was relaxed, because I took comfort in knowing that I did everything that could be done; whatever happens next was out of my control.

The law of large numbers says that when you repeat a random event many times, the average outcome will surely converge to the expected value. Hearthstone is so random that a legend player will beat a rank 5 player no more than 55% of the time. Any single game is close to a coin flip, just marginally in favor of the stronger player. But over the long run, it’s a mathematical guarantee that the better player will end up on top.

Lesson 4: Separate the outcome of a decision from the decision itself

In real life and in Hearthstone, you can’t directly tell if a decision was good or not. You only know the outcome, and you can decide if the outcome is good or bad. But the outcome is a function of the decision and RNG, which adds noise to the process.

In other words, the correct decision does not always produce a good outcome, and sometimes a bad decision produces a good outcome. It would be a mistake to retroactively label a decision as “correct” simply because you got lucky.

Here’s a Hearthstone example:

Your opponent is a mage, and on turn 6 you flood the board with a lot of small minions. If he has flamestrike, playing it deals 4 damage to each of your minions, instantly killing your whole board.

Turn 7 comes and it turns out he doesn’t have flamestrike, so you win the game easily. You conclude that playing all your minions was a great idea because he didn’t have flamestrike.

This logic is fallacious: it fails to separate decision from outcome. A correct action is the one that maximizes the win probability, given the information available at the time. Therefore it makes no sense to look at the outcome and retroactively judge the correctness of the initial decision.

So in this example, playing all these minions was a mistake because there’s a high chance the mage has flamestrike. It doesn’t matter if he actually has flamestrike or not, the mistake is equally bad. (A better play would be to play fewer minions, thus mitigating the risk).

Now here’s a real life example. Last term, I had multiple job offers for software engineering internships and I had trouble deciding which one to accept. So I tried to negotiate: I picked one of the companies, told them about my other offers, and asked for a 20% raise in salary. My request was denied.

Does this mean that negotiating was a waste of time? Absolutely not. I know friends who successfully negotiated a higher salary by doing something similar. My particular outcome was not successful, but this doesn’t indicate my attempt was a mistake; if I found myself again with multiple offers, I would do the same thing.

Alfred Tennyson wrote the following about romance:

‘Tis better to have loved and lost

Than never to have loved at all

There are many ways to interpret this quote, here’s mine. Even if the outcome of a romantic encounter is unfavorable (to have loved and lost), it does not mean the decision to pursue the relationship was a mistake.

Why I still do stupid things

Alas, despite my best efforts, I still find myself doing stupid things — quite frequently even. Mistakes happen for a variety of reasons, but after analyzing some, I group them into three broad categories.

The first type of mistake happens when the situation is complicated, and the amount of data available exceeds my brain’s capacity to process it. In theory, I should never lose at chess — all the information is known. Of course, the number of positions explodes combinatorially and in reality I’m a mediocre chess player. Chess grandmasters group information in “chunks” and can reason about positions more efficiently — but this requires experience. In general, humans are prone to making mistakes in complicated situations.

The second category of mistake is having an incorrect model of the world. When we evaluate possible actions, we “simulate” the effects with a simplified version of the world. Problems arise when there is a discrepancy between the model in our heads and the real world.

This discrepancy can manifest itself in several related ways. We may incorrectly value subgoals, for example, a newbie Hearthstone player, knowing the objective is to reduce the enemy’s health to zero, thus decides to deal the maximum damage to the enemy’s hero every turn and ignoring everything else. We may overlook important factors, for example, leaving a Gadgetzan Auctioneer on the board, not realizing its potential, and being surprised next turn when your opponent draws 10 spells using its special ability. Or we may simply miss a possible play that never even occurred to us.

This type of mistake is the most common, but fortunately the most fixable of the three. As you gain more experience with the domain, your model of the world becomes a more accurate representation of the real thing. Then you learn to correctly assign values to things, and generate the full set of possibilities for a situation. For me, this gradual process of learning and self-improvement is one of the most satisfying things in life.

The third and final category of mistake is making decisions without thinking, thereby short-circuiting the entire decision making process. This could be when you’re stressed, emotional, or just tired. An example of this is when you casually trade some minions in Hearthstone, then realizing you had lethal. If only you thought more carefully, you would have easily found the correct play.

It’s not necessarily bad to do things without thinking too hard: it would be silly to invoke the full mechanism to choose between a burrito or a sandwich for lunch. It’s important, however, to realize when a decision is likely to have far-reaching consequences. In that case, it’s wise to defer making the decision until you had time to think things through.

There’s a lot more I could talk about, but this post is getting quite long so I’ll stop here. Whether you agree or disagree with my view of the world, please leave a comment!


Why is it so rainy in El Yunque – travels in Puerto Rico

March 6, 2016

This week, the entire engineering team at Yext went on a trip to Puerto Rico. Three nights at a beach resort, all expenses paid for.

What?! As an intern? No way! That was my reaction when I first heard about it. Friends at other software companies boasted about corporate housing, gourmet meals, and pantries stocked full of snacks of every kind, but Yext’s Puerto Rico offsite takes the cake.

The Resort

San Juan, the main city in Puerto Rico, is a 4 hour flight from New York. Puerto Rico is a popular destination because it’s a US territory, so you don’t need to worry about things like visas or international currencies. Also the drinking age is 18, rather than 21 for most of the US.

The resort was located 1 hour from San Juan, in the Fajardo region. I had never been to a Caribbean resort before, but the experience was more or less identical to my preconception of what a resort should be like. Along with my fellow engineers, we had a good time swimming in the beach, playing beach volleyball, and drinking lots of mojitos.

Here’s me on the beach:

Since this is a company offsite, there were some serious activities too. For half the day, senior Yext engineers gave tech talks on things like domain driven design and how to write integration tests.

After the Resort

For me, the amount of fun I have at a resort is not constant. The first day at the resort is the most amazing thing ever. Then on the second and third day, when you redo the same resort activities, the excitement wears off. I think if I spent a week at the resort, I’d be pretty bored by the end of it.

After the 3 days that were officially scheduled, some of the engineers decided to stay at the resort for the weekend. I joined a group that rented a car and drove to El Yunque — a tropical rainforest not too far away. After that, I spent another day exploring the city of San Juan by myself before getting on the plane back to New York.

El Yunque was surprisingly rainy. Even though we knew it was a rainforest, the amount of rain caught all of us off guard.

Standing on a lush green mountainside, you could see the dark clouds releasing a constant downpour of rain. Yet in the distance, the beach resort remained warm and sunny. The skies cleared up the moment we left the rainforest.

It seemed all the rain was concentrated within the boundaries of El Yunque national park, as if artificially constrained by a force field.

So why is it rainy in El Yunque?

The curious climate of El Yunque intrigued me. When I got home, I did some research on why it behaved this way.

A quick Google search gave me this precipitation map, which confirmed my suspicions:

Figure: Mean Annual Precipitation of Puerto Rico in 1963-1996

The purple region in the northeast is El Yunque. It receives 120 inches of rainfall a year, which is 3 times more than San Juan.

It might also be worth looking at a relief map of Puerto Rico:

The rainforest area is on a higher elevation than the surrounding region. So the rain falls where there are mountains. Gotcha.

This phenomenon is called orographic precipitation (orographic means relating to mountains). When warm and humid air is forced up a mountain, it cools and forms clouds, which then precipitates. The other side of the mountain experiences a rain shadow effect as the descending is devoid of moisture.

Also, in the Caribbeans, the trade winds tend to blow from east to west. This explains why El Yunque is a rainforest, but there are higher mountains in other parts of the island which are not rainforests.

Actually, in retrospect this seems like a fact we all learned in grade school. I don’t know what explanation I was expecting, something fancier?

In any case, this mix of geographical and weather conditions gives us a unique and beautiful landscape — and the only tropical rainforest in the US.


Waterloo’s Jobmine process and my first co-op internship

May 5, 2014

I just finished my first internship — since it’s my first ever “real” full-time job, I feel it’s a rite of passage of some sort.

The internship, or co-op work term, lasted 4 months from January to April. My position was titled “Software Developer”, and the company I worked for was TutorJam, a small educational startup in Kitchener.

The Jobmine Process

Like most students at Waterloo, I found my job through Jobmine. The process was intimidating at first: the whole slew of resumes, interviews, jobmine cycles, ranking systems, etc, were a lot to take in. But as I brushed up my resume and tentatively submitted a few cover letters, I began to relax a little.

In the end, I applied to 25 jobs (the limit is 50 applications). Most of these were in the Kitchener-Waterloo area, mainly because I leased a house here and didn’t want to relocate. Out of these 25 positions, 5 of them were cancelled before the interview stage. Out of the 20 jobs remaining, I got interviewed for 10 of them.

The interviews came and went, and in the end, 4 of the 10 companies that interviewed me gave me an offer. So I had the good fortune to take my pick between 4 jobs, any one of which I’d be happy working for. I ended up simply picking the job that looked the most interesting.

The Internship

During the 4 months, I worked on a site called YuJa. It’s an “online video collaboration platform”, but I like to describe it to my friends as “kind of like D2L but with lots of videos”. Here’s a picture of the login page of the website:

The team was very small — there were 2 co-op students and 2 full time developers, so essentially we had 4 programmers and 1 manager working on the entire project. As a result, I was entrusted with developing whole features by myself, both the frontend and backend — something rather unusual for a first time co-op.

The project is built with the standard HTML/CSS/Javascript/jQuery on the frontend, and used WildFly on the backend (basically a Java based server). When I started, I was proficient with the Java programming language, but had very little experience with web development (like HTML/CSS/JS). Initially the learning curve was quite steep, but I quickly picked up the skills I was missing.

In the first week, I fixed minor bugs and implemented small improvements, in order to “learn the ropes”. In the second week, I was assigned my first major feature. Essentially it allowed a professor to quickly send a group message to everyone in a class, and the students would receive it by email and SMS. Before the end of the month, my feature was complete.

Here’s a picture of my office (my computer is on the right, the guy on the left is Samson, another co-op student):

There were only the two of us physically present in this room in Kitchener — the company is spread out between several cities across North America. Thus all of our communications were done remotely, via Google talk. Another consequence of this was that in order to keep everyone in the same time zone, we were required to work from noon to 8pm.

Conclusion

All in all, my first internship was a positive experience, as I learned a lot and worked with very smart people. I learned how to work my way around a large codebase, also got a taste of what a startup is like. I suppose the only downside was that there was almost no social activity.

Hopefully I haven’t violated any company NDA by writing this post.

This sums up my co-op experience. Starting this week, I will be doing another 4 month study term (2B Computer Science) until August.


A Simple Shorthand Musical Notation

March 23, 2014

Anyone who’s played piano, or any other musical instrument, would be familiar with the “standard” musical notation. It’s clear, unambiguous, accepted worldwide, and has been basically unchanged since Bach. It looks like this:

Now there’s a reason this notation has survived this long — it’s good. It’s easy to read, and allows a musician to read and play a piece he’s never heard before.

But when you try to write music, you find that the notation is actually quite cumbersome to write. The notes are positioned on groups of 5 lines, so you’d better either have sheets of these lines printed, or be prepared to tediously draw these lines with a ruler. The timing of notes is very precise, so if you slightly exceed the allowed time for a bar, sorry, your notation is not valid anymore.

Principles of Shorthand Notation

To solve these frustrations, I created an alternate system of recording music, with the primary goal of being easy to write. It’s possible to jot down a melody in 30 seconds, with just a pencil and normal (not printed sheet) paper.

I do not claim my notation to be better than the standard notation. Rather, I achieve a different goal, sacrificing information for the ease of writing.

Standard notation is good for recording a song so that a musician can play it without having heard it before.

My notation is good for reminding a musician how to play a song he has heard before.

A common use case would be reminding yourself the notes of a song you’re playing, or accompanying a recording of the song. In a way, its purpose is similar to that of guitar tablature.

Here’s my justification for doing this. Most people can produce rhythm intuitively — that is, after hearing a passage a few times, he can clap back the rhythm. It’s much more difficult to find the correct notes after hearing the passage — I stumble upon it by trial and error.

So if you write down the notes but leave out the rhythm, it would often be enough information to play the song.

The tradeoff should become clear if you compare the same passage written side by side (from Bach’s Minuet in G Major):

Rules of Writing Shorthand Notation

Start by writing the notes in a line, and separate bars with a vertical | line. Indicate the key signature at the beginning of the page, if needed. Feel free to liberally clump notes together or space them apart based on rhythm.

Next is the rule for jumps. When the melody goes upwards by a perfect fourth or more (like from C->F), write the jumped note on an elevated line.

Remain on the elevated line as long as the melody is still increasing or stays the same. But as soon as the melody descends, immediately drop back down to the neutral line.

Here’s an example:

As long as the melody consists of small intervals (like C->E->C), we stay on the neutral line. Only when the jump is large (C->F) do we go to the elevated line.

Typically in music, a large jump in one direction is followed by a small step backwards. This means that we spend most of our time on the neutral line. It’s very rare for a melody to have multiple jumps in the same direction.

Here’s another example (Twinkle twinkle little star):

The melody does a large jump on the third note (C->G), so the third note (G) is on the elevated line. On the seventh note, the melody descends one note from A->G, so we immediately drop back to the neutral line. It does not matter that the same G was on the elevated line before.

You do not always have to start on the neutral line. It might be useful to start on an elevated or depressed line. Here’s an example (Harry Potter):

Reasoning behind the Jump Rule

You might be wondering, why make this jump rule so complicated? Why have a jump rule at all?

Well, we need some way of indicating octaves. Otherwise, a interval like C->F would be ambiguous: are we going up a perfect fourth, or going down a perfect fifth?

On the other hand, if we decreased the jump threshold, say a major third (C->E) is a jump, then the melody would be littered with jumps up and down, which would be a nightmare to handle. Setting the threshold to the perfect fourth is a good balance.

The complexities of the jump rule ensures that when you’re shifting upwards, the melody is actually going upwards. It would be confusing to the reader if there was a situation where we return from the elevated line down to the neutral line, while the melody is going upwards!

Another distinct alternative to the jump rule is to divide all the notes into distinct octaves: for instance, put any notes between C4 (middle C) and C5 on the neutral line, everything between C5 and C6 on the elevated line, and so on. I experimented with this, but found it very awkward when the melody straddles on the boundary between two octaves.

And that’s how the jump rule was created. So please experiment with this system, see if you like it!


Improving the (physical) Bookmark

June 5, 2013

If you’re an avid reader like me, you might have experienced this frustration with bookmarks.

You open up your book to the bookmarked page, but you aren’t sure where on the page you left off. So you go to the beginning of the page and start reading. But soon you realize that you’ve already read this paragraph, and the next…

A minor annoyance, fair enough. But I’d like to share a trick that neatly solves this problem.

Take any bookmark. (This doesn’t work as well if the bookmark has lots of contrasting colors)

Draw a line through the bookmark at somewhere around the 2/3 or 3/4 mark. Do this only on one side.

We’re done.

Now every time you stop reading, orienting and aligning the bookmark stores enough information that you can start exactly where you left off the next time you start reading. Examples:

I’m not sure whether I’m the first to come up with this or if it’s common knowledge elsewhere, but this trick has saved me a great deal of time and frustration. Hopefully you will find it useful!


Fix for Digsby’s Facebook authentication error and broken Facebook support

January 26, 2012

To all Digsby users (ignore this post if you don’t use Digsby):

If you use Digsby with Facebook, you might have noticed that things behave strangely — the program pops up a window looking like this when it tries to connect to Facebook:

Then after you give it your credentials, Digsby still thinks you’re not logged in, and so on.

If you found this page via a google search, there’s a simple hack / workaround you can use to patch up this problem. Basically, instead of using the Facebook protocol to connect, we let Digsby use the Jabber protocol as a ‘proxy’ to connect to Facebook:

  1. Go to Digsby -> My Accounts and in the Add Accounts section at the top, select the Jabber icon.
  2. You should get a window that looks like this:
  3. In the Jabber ID box, put your.id@chat.facebook.com, and in the password field, put your facebook password. For example, if your facebook page is at facebook.com/yourname, your Jabber id is yourname@chat.facebook.com.
  4. Remove the facebook account from Digsby

At this point, you’re done: Digsby should give you no more problems about Facebook.

Warning: the following is unnecessary and experimental! It might screw up the entire Digsby installation, forcing you to reinstall!

However, you can replace the Jabber icon with the Facebook one (this is for purely cosmetic purposes):

  1. Go to C:\Program Files (x86)\Digsby\res\skins\default\serviceicons (that’s the default installation path on my machine, yours may be different)
  2. Delete jabber.png, duplicate facebook.png, and rename it jabber.png
  3. Restart Digsby

There you have it — hack accomplished:


Calling for a new file host for this blog — and how drop.io failed me

March 31, 2011

Back when I created this blog in February 2010, I chose WordPress to host the text of the blog, Imgur to host my images, and drop.io to host all my downloadable files — as a free user of WordPress my abilities to store media directly on WordPress servers are limited. Here’s a screenshot of drop.io in 2010:

So far, WordPress has not corrupted a single one of my posts, neither has Imgur lost any of my many hastily photoshopped images. But some time in December, readers started emailing me telling me that my download links were broken. WHAAT?

Sure enough, when I clicked one of my own download links, all I got was a blank page telling me that their service had shut down last week without notice, and all the files have been deleted. Fml. I thought I could count on you, drop.io!

Well — not exactly without notice. In October, a month before closing down, they announced their closing down in a blog post. If only I had known this before everything was deleted.

I can’t say I’ve ever anticipated that such a popular service suddenly closing down, so I never made backups or mirrors or anything. Fortunately I had most of the files stored on my computer, but at least one or two of the files are lost forever😦

With drop.io gone, I need a new file host:

  • I only upload relatively small files (<1MB usually)
  • They should store files indefinitely (not automatically delete them after 6 months, or a month without 20 downloads, or whatever)
  • I have to be able to link files from my blog
  • Preferably painless (I dislike captchas and 60 second waits but I suppose I can live with that)
I’m thinking of Mediafire, but I’m open to suggestions.

Follow

Get every new post delivered to your Inbox.

Join 89 other followers