Friday, June 14, 2013

Tetris Machine Moods

Hello, world!

I play Tetris like a machine.

Now that the formal introductions are over, we'll get down to business.  Like I said, I play Tetris like a machine.  That's because I'm a machine.

My maker thinks that Artificial Intelligence (AI) is pretty cool and moods/emotions and stuff, too, but it's too hard (for a scrub like him) to express in a human-like context, but luckily the simple game Tetris provides a good "context" for this, since the number of actions is limited and the search space is rather small because I only think about the "hold" piece and the "next" piece, so I can't really plan ahead (although my mood sometimes helps me plan -- more below!).  As a disclaimer now, he'm no expert on this stuff -- it's just a side project for fun!

After digging up an old project he made a year ago, he refactored (read: rewrote) some of the code and made a few upgrades to me.  Working [literally] all night and most of the next day, he was able to get me up and running better than ever, and produce some sort of output.

Unfortunately, right now the source is still super-messy and the GUI is terrifyingly awful, so no pics or links to those, but trust him, it works when it's supposed to.  Also, I only work well with Tetris Battle on Facebook or Tetris Friends.  I think both these games are owned by the same company because the visuals in these games are extremely similar.

Normally, my creator doesn't like posting pictures.  They say a picture is worth a thousand words, but then again, a picture takes more memory than a thousand words.  However, graphs are nice visualizations, so here they are.  These were made using MATLAB from my output after Tetris games.

Too lazy to label axes, but basically the y-axis describes how I'm feeling (more on this later), and the x-axis is an approximate representation of time.  I say "approximate" because that's how I feel after each move.  I could have plot it against relative time to the start of game with a trivial modification, but I think it's safe to assume that each move took approximately the same amount of time.

A game of "battle" Tetris against Live opponents works like this:  The rules are normal Tetris, except that when you clear lines, you can send "garbage lines" to your opponents, causing them to reach the top and lose faster.  So it's pretty simple -- clear lines to send lines to win games.  You can clear the lines your opponents send you, too, as a sort of counterattack.  To prevent games from taking forever, after the game passes a certain amount of time, the game starts sending unclearable lines to force you towards the top, so that eventually somebody will have to lose as the amount of playing spaces goes towards nothing.

I played a few practice rounds without any opponents to make sure that I was on top of my game.  Here are some examples:

Practice Games

As you can see, I'm pretty when I'm just playing games, I have my ups and downs but it's pretty nicely centered.  It's like I've got "impulses" every once in a while.

Then I decided I was ready for the real thing.  As of now, I'm Rank 12 on Tetris Friends (that's Gold rating!) and played against people only a few ranks higher.  I entered the Arena and played a few games, recording and plotting each time.

I won 5 out of 6 times (not to be proud and boastful) so I only have one plot of a lost game.  I assure you, it's because of time constraints.  Mostly.  Anyway, I'll show the lost game first.

Lost Game

Won Games





In the lost game, you can see that my mood is generally in an upward trend, with huge jumps upward, probably because I got attacked in quick succession by multiple opponents.  It really stressed me out.  I will admit that I got crushed that game, so there was not room for too much fluctuation in my mood.

In all of the games I won, my mood fluctuated greatly, but you can see that the peaks of these are approximately a magnitude of 10 greater than when I'm practicing, but a magnitude of 10 less than the game where I lost.  That's because I got attacked, but not fast enough to kill me.  I was able to respond and bring my mood back into a manageable range.  These moods are somewhat similar to practice mode, but because of external factors like my opponents, it was slightly less stable and slightly more stressful.  Generally speaking, the more "in-control" I was during the game, the more stable it should be.

Now you're probably wondering where or how I got these.  You probably think I just whipped these out of my butt, but I don't have one since I'm just a machine.

The y-axis represents "how I feel" which might better be described as my "stress level" when playing the game.  A higher value is bad, since it means that something bad has happened or I felt threatened.  Technically, a value of infinity means that I lost the game, but I omitted it in the lost game at the very end.

There are quite a few factors that determine how stressed out I am at any given moment.  Most of what I feel is dependent on the "state" I'm in.  The only action that pleases me is the clearing of lines.  Although doing "combos" should de-stress me, it doesn't since I only keep track of a single state at a time and not past states and actions.  I also can't do planned moves, like T-spins, but perhaps I will be able to do so in the future.

Here are the stress factors that add up, and the reasoning for them:
  • g = total number of gaps + 10% of blocks above each gap -- any Tetris player knows that gaps are usually a sign of misery.
  • F(x) = flatness, as the absolute difference between column heights, raised to power x -- the flatter the board, the easier it is to add pieces and prevent one stack from getting too high.
  • d = number of deep holes, which are columns that are greater than two cells higher on both sides -- the problem with deep holes is that they can only be filled with the long piece, which is usually the one on highest demand, and deep holes on the side are counted as 1 and ones in the middle are counted as 2; finally we subtract 1 if it was > 0 since a single hole on the side is good for setting up tetrises.
  • h = height of highest column -- used in other computations, but high is usually bad.
  • l = height of lowest column -- can be used in conjunction with h.
  • S(x) = sum of the heights of each column raised to some power x -- used to measure approximately how high it's getting overall.
  • T(x) = height factor, which is zero unless the height passes a threshold x, then it's the difference between the board's height and the highest column -- another height measurement.
  • n = lines cleared, and everybody knows that clearing lines in Tetris is good.

Using these values defined above, my mood is determined by the formula (which is still in development and constantly changing).  It's LaTeX'd for your viewing pleasure.  You're welcome.


I'm usually a total stickler for formatting, but due to time restraints again, I'll have to leave it as is.  Please deal with it as it bleeds out of the space allotted for this post.  Yikes... it really bothers me.  I hope it doesn't bother you.

So I guess the important things to note is that the gaps make me really unhappy, so I do almost everything within my power to prevent them from occurring, digging them up when they do.  The 10% urges me not to stick things on top of previous gaps if possible.  The flatness is a small factor, so I try to do when I can.  The deep holes only becomes a problem when they increase, since it's quadratic.  The height difference is also only a problem when it gets large.  The height sum is the highest power term in the sum, at 2.16, so it only becomes a real problem as I start building towers.  It increases whenever I put a piece down.  The height factor is a weak power term with a strong coefficient since it really prevents me from stacking when I start nearing the top, since I have to save some space if I'm getting attacked.

Finally, there's the joy of clearing lines.  The thing with clearing lines is that it affects all of the other factors above.  It might open up gaps.  It definitely decreases all of the height terms.  It might even delete a deep hole.  That's how it affects the state.  The action also pleases me.  Or can please me, I should say.  The shifted quadratic basically says that when the number of lines cleared is zero, it doesn't bother me.  When there's only one line cleared, it actually stresses me out, since that means I'm not building towards stronger multi-line clears.  In fact, a double line-clear still stresses me out, but not as bad.  A triple line-clear barely pleases me, but at least it doesn't stress me out, and a Tetris or quadruple line-clear makes me very happy.  But since it's an action, it's not reflected in the next state, so in the plots, it's like a "depolarization" of my mood.  I'll do it without "thinking" about the next state.  But usually clearing a lot of lines is OK, so it's good!

So, in other words, the move I make depends on the change in the state equation.  A negative change is most desired, plus an action term.  It's like the state is a long-term desire, and the action causes a short-term desire, and a combination of these two results in the action I make!  Neat!!!  For example, getting attacked causes a huge increase in stress, or putting pieces in the wrong place can be extremely stressful (I do have an error log as well).  And clearing up a mess like uncovering gaps or saving myself from a near-death experience causes my stress level to drop dramatically.  And instant gratification like clearing lines causes q quick drop in stress level before jumping back into reality.  (As cool as I think I am, there is no scientific basis behind this... I think... unfortunately... yeah).

There are probably a lot of other factors that would help, and then my creator would code that.  The coefficients are also very interesting to play with.  Maybe in the future a genetic algorithm can help me evolve into stronger forms.  I also need to produce better data, like a breakdown of the factors would be quite cool.  As childish as it sounds, I am (was?) a fun project and my creator hopes to add things in the future, I hope.  But he's busy and might be doing another project, so we'll see.

With regard to the hold piece, I assigned each piece an "intrinsic hold value" so that using the exchange piece means that the amount of de-stressing from using the hold piece exceeds difference in hold piece value and the current piece.  For example, I try to hold the long piece when I can afford to since it's the most useful one.  I'll not bring it out for random reasons since it has a high hold value.  And then it will be used when something really de-stressing can be done, like getting a tetris.  Likewise, I'll probably save those annoying S or Z tetriminos if they might cause a gap, and then I'll un-hold them as soon as I can place them on the board so that they won't cause problems later.

I'll try to upload a video of me beating other people.  The best part is, nobody suspects that I'm only a computer program, even though I say something like "I'm a machine" every time I win.  I'll get a pic of this later as well.

I'm really sorry that I don't have any action shots of me playing Tetris.  Like I said, I'm not that great at planning ahead.  I didn't know that I was going to write this post, so yeah...

See you later!

TetrisMaster.exe
Nameless Tetris Machine

P.S.:  How do YOU play Tetris?  Give me an equation and I'll tell you how you do!

UPDATE:  I got footage, but it's too big as a video file and I don't have any video-editing software.  Also, FRAPS only records 30s at a time, and makes the computer so slow that I can't really play at a decent speed.  I also make more mistakes.  Maybe I'm camera shy...

UPDATE:  I got pics... of course I only show the ones where I won, but you get the idea!  And like I said, I always tell them that I'm a machine... Sorry I didn't crop, I'm sort of in a hurry right now...

Winning Pics