Pages

Monday, November 8, 2010

Yet Another Tetris

I just uploaded my version of the Tetris.
Go to Games page to play it !-)

In order to get familiar with the JavaScript language I have decided to implement a couple of games. Tetris was the number one on my list. Minesweeper will be the next one.

I've tested my code on Windows XP SP3 and Windows 7 Professional. The following browsers run the game fine:
  • Firefox v4.0 Beta 6
  • Google Chrome 7.0
  • Opera 10.63
  • Safari 5.0.2

Sunday, October 24, 2010

JavaScript and Canvas, woo hoo!

HTML5 standard introduces the Canvas element. We can now draw on a web page with plain JavaScript code. Isn't this exciting?

I have a few old games which I wrote in Turbo Pascal (and Delphi) and I intend to convert them into JavaScript code and post them in my blog, so anyone can play them. Woo hoo!

If your browser does support the canvas tag/element you'll be able to view a white square with a black border below. If so, try rolling the mouse over the square. If no, consider upgrading your browser ;-)


no canvas support



That's my Black Triangle.

Saturday, September 18, 2010

Tic-tac-toe, best move to start?

Tic-tac-toe game has one simple rule: the player who succeeds in placing three respective marks in a horizontal, vertical, or diagonal row, in a 3x3 grid, wins the game.

So what's the best move to start? Well, I don't know.
But I can use a computer to get an answer.
(I lied. I do know)

The tools I've used:

The computer played 10000 "random" games and saved them in a database.

Actually the games are not plain random games. I've embedded the tic-tac-toe rule in the program. The program chooses a random move only if the player can't win or can't block the opponent. The players are considered to be intermediate level tic-tac-toe players.

Even though we've played random games, the best moves dominate over the good and bad ones, and just by counting the results we get our answer:

0 | 1 | 2
--+---+--
3 | 4 | 5
--+---+--
6 | 7 | 8



As we can observe, corners lead to more victories. Yeah baby!

And what's the more defensive opening for tic-tac-toe?
(by defensing I mean a move that leads to more ties)



Hmm, it's the center (cell 4). Interesting.

Here's something way cooler: since we have a knowledge base for tic-tac-toe games, we can query the database for a specific game state and find out the next best move for any player!

An example: let's say that X (player 1) chose the upper-left corner (cell 0).

X | 1 | 2
--+---+--
3 | 4 | 5
--+---+--
6 | 7 | 8


Now what O (player 2) should choose? A move that gives the fewer wins for player X has good odds to be the next best move, right? OK, lets run a query and see...



Hey, statistically, the center (cell 4) causes fewer wins for player 1,  thus it's the next best move for player 2. Neat!


Play on-line Tic-Tac-Toe

You prefer to play with code? Here's what I've crafted:
import random
import sqlite3

def CanTicTacToe(player, cells):
    return cells.count(player) == 2 and cells.count(0) == 1

def SelectWinningMove(player, board):
    # Horizontal
    if CanTicTacToe(player, board[0:3]): return board[0:3].index(0) + 0
    if CanTicTacToe(player, board[3:6]): return board[3:6].index(0) + 3
    if CanTicTacToe(player, board[6:9]): return board[6:9].index(0) + 6
    # Vertical
    if CanTicTacToe(player, board[0::3]): return board[0::3].index(0) * 3 + 0
    if CanTicTacToe(player, board[1::3]): return board[1::3].index(0) * 3 + 1
    if CanTicTacToe(player, board[2::3]): return board[2::3].index(0) * 3 + 2
    # Diagonal
    if CanTicTacToe(player, board[0::4]): return board[0::4].index(0) * 4
    if CanTicTacToe(player, board[2::2][:3]):
         return board[2::2][:3].index(0) * 2 + 2
    return -1

def SelectRandomMove(player, board):
    moves = [i for i in range(0, len(board)) if board[i] == 0]
    if len(moves) == 0: return -1
    return moves[random.randint(0, len(moves) - 1)]

# ([0,1,2,3,4,5,6,7,8], result)
def PlayRandomGame():
    result = 0 # tie
    board = [0] * 9
    moves = []
    player = 0
    while True:
        player = player % 2 + 1 # X: 1, O: 2:
        move = SelectWinningMove(player, board)
        if move >= 0: # victory
            moves.append(move)
            result = player
            break
        # Opponent can win?
        opponent = player % 2 + 1
        move = SelectWinningMove(opponent, board)
        if move < 0: # nope, so ...
            move = SelectRandomMove(player, board)
        if move >= 0:
                moves.append(move)
                board[move] = player
        else: # no more moves; tie
            break
    return (moves, result)

def SaveRandomGames(fileName, n=10000):
    conn = sqlite3.connect(fileName)
    c = conn.cursor()
    c.execute('DROP TABLE IF EXISTS games')
    c.execute('CREATE TABLE IF NOT EXISTS games ('
        'move1 INTEGER, move2 INTEGER, move3 INTEGER,'
        'move4 INTEGER, move5 INTEGER, move6 INTEGER,'
        'move7 INTEGER, move8 INTEGER, move9 INTEGER,'
        'winner INTEGER)')
    for _ in xrange(n):
        game = PlayRandomGame()
        moves = game[0] + [None] * (9 - len(game[0]))
        result =  game[1]
        c.execute('INSERT INTO games VALUES (?,?,?,?,?,?,?,?,?,?)',
            moves + [result])
    conn.commit()
    c.close()

Tuesday, August 17, 2010

4 ways to close an application

I knew these ways
  1. Clicking on the upper-right button aka the X button
  2. Alt + F4
  3. Selecting  the Close command from the system menu (the upper-left icon on a window)
And I just found out a fourth way, after so many years of using Windows.
By double clicking the upper-left icon you execute the default command, which is the Close command.

Hooray!

Sunday, July 4, 2010

Windows, slash or backslash?

In case you didn't know, Windows API accepts both the slash / and backslash \ as path name delimiters.

When I hard code file names, I always use the slash / to avoid doubling (escaping) the backslash. The latter style looks a bit ugly in my opinion.

Sunday, June 13, 2010

Blocked OpenID provider? Can't log in Stack Overflow? A workaround

My favorite browser is Firefox and this post is about modifying Firefox cookies. Geeky solution, I know!

The problem

At my work, various URLs are blocked. For example, I can use Google as my main search engine, but I cannot sign in Google home page. Thus, many of the Google services are inaccessible, including my OpenID.

So, I can't use my OpenID to log in my Stack Overflow account. From my home, of course, I can. And I could use another OpenID provider to activate the second account which SO provides, but I don't want to keep around multiple OpenID accounts.

The workaround

Thankfully (?), Stack Overflow only tracks the cookies in our computer, it doesn't care if we are actually logged in our OpenID provider. If the right cookie exists, then bingo! We are in.

Firefox 3 (v3.6.3 currently) uses SQLite database as a storage format. Text format belongs to the past due to its natural limitations, e.g. provides no support for organizing persisted data. Check out DOM Storage for more info.

In order to modify Firefox cookies we need a SQLite manager and (of course) SQL knowledge. Gotcha!

If you don't have a SQLite manager, you can download SQLiteSpy, which is a single executable and doesn't require installation.

Still reading?

On Windows XP, Firefox cookies.sqlite location is:
\Documents and Settings\USERNAME\Application Data\Mozilla\Firefox\
Profiles\v1egdb8r.default\cookies.sqlite

If the Firefox is running we cannot open the cookies file, because it'll be locked. First we must close the browser.

Now, if we open cookies we'll see something like this:



Every cookie record contains 9 fields: id, name, value, host, path, expiry, lastAccessed, isSecure and isHttpOnly.

To get a list of cookies for a particular site, run a query like:
select * from moz_cookies
where host like '%stackoverflow%'



The cookie with the name usr, is all I wanted. Cloning that cookie in my other computer granted me access to my SO account. Simple or not, it works great ;-)

Saturday, June 12, 2010

timestampToString, Google's obfuscated code sample

When we search on Google, we sometimes see a time-stamp on the results.

Example:


What code does that job?

Well, here it is:
function sa(a,c){var b=c-a;if(b<86400)if(b<45)return"seconds ago";else if(b<105)return"1 minute ago";else if(b<3345){b=Math.floor(b/60)+(b%60>=45?1:0);return"1 minutes ago".replace("1",b+"")}else if(b<6600)return"1 hour ago";else{b=Math.floor(b/3600)+(b%3600>=3E3?1:0);return"1 hours ago".replace("1",b+"")}return g}

1-liner (kinda :-) obfuscated JavaScript code. Yeah, Google obfuscates the source code which is revealed to the public. Most function names, along with constant values, and white-space, are removed or replaced with shorter, meaningless names.

To get the code, go to Google home page, and use whatever option your favorite browser provides for viewing the source code.  In there, search for a URL string like this one:
/extern_js/f/CgJlbhICZ3IrMA ... BROAIsKzBaOAAsgAIV/0JBXC50vuSQ.js

If you attach it at the end of the Google URL, you'll get the whole source code.
ie, http://google.com/extern_js/...

Now, with a proper indentation, sa function becomes readable:
function sa(a, c) {
  var b = c - a;
  if (b < 86400)
      if (b < 45)
         return "seconds ago";
      else if (b < 105)
         return "1 minute ago";
      else if (b < 3345) {
         b = Math.floor(b / 60) + (b % 60 >= 45 ? 1:0); 
         return "1 minutes ago".replace("1", b + "")
      }
      else if (b < 6600)
         return "1 hour ago";
      else {
         b = Math.floor(b/3600) + (b%3600 >= 3E3 ? 1:0);
         return "1 hours ago".replace("1", b + "")
      }
  return g
}

If we know JavaScript, or another programming language with similar syntax, it's pretty easy to see that the time-stamp is displayed only on pages that were updated, in Google Index, in less than a day (86400 = 24 x 60 x 60 seconds).

Here is the final (unobfuscated) version, written in Python this time:
import math
def timestampToString(currentTime, modifiedTime):
   delta = currentTime - modifiedTime
   if delta < 86400:
      if delta < 45:
         return "seconds ago"
      elif delta < 105:
         return "1 minute ago"
      elif delta < 3345:
         delta = math.floor(delta / 60) + (1 if delta % 60 >= 45 else 0)
         return "%i minutes ago" % delta
      elif delta < 6600:
         return "1 hour ago";
      else:
         delta = math.floor(delta / 3600) + (1 if delta % 3600 >= 3000 else 0)
         return "%i hours ago‚" % delta
   return False

Did you notice that the value 3000 was, in the equivalent scientific notation, 3E3? Cool ;-)

FAQ About Time Travel

I have watched dozens of dull movies. This is definitely not one of them. Recommended.

Sunday, May 30, 2010

Property Driven Code

Sometimes I feel like this,



trapped in a hard to maintain spaghetti code. I find myself writing again and again fragile code.
My definition of fragile code is, suppose you want to add a feature - good code, there's one place where you add that feature and it fits; fragile code, you've go to touch ten places.
Ken ThomsonCoders at Work
The program may be structured but that does not exclude spaghetti code. The two are not mutually exclusive. Embedding the application's behavior or logic or -even worse- data properties is a path that leads to spaghetti code; pull it here and something moves on the other side.

But, what do I mean by Property Driven Code and how it can help me to reduce spaghetti code?

In its core lays a Data Driven design along with Property Modeling.
Here is how that kind of model looks like:



The programmer's main job is to write Property Driven Code, that means code that introspects data properties, mostly at run-time, and do stuff accordingly. Introspection, or reflection, is the magic thing that can reduce code complexity and hard-coded outer world knowledge.Yes, properties drive the code.

Properties, or Prototype-based programming, is similar to OOP but not the same thing. You can read Steve Yegge's great article The Universal Design Pattern by which I got inspired and wrote my proto_t data structure so I can use property modeling in my C++ projects.

Now I'll try to illustrate the concept with a simple example. Suppose that we have to load and save tabular data from and into text files. The file formats are from 3rd party software and cannot be change. Some of them are similar to CSV format but they can have slight differences. Or they might not be CSV but just lines with fixed length fields. If you think that's an unlikely scenario then welcome to the world of Electronic Cash Registers. How would you approach that problem? Would you use well known and tested CSV parsers? Write your custom parser? And if you pick up a library to do the job how would you structure the different format cases? By using a switch case? OOP and polymorphic classes? Plain old if-else chains?

Let's suppose we have to parse a file that contains lines like this one:
"hello, world", 42

That's a quoted string followed by a comma delimiter and an integer. If we choose to use Properties to design a solution, we'll have to declare a format object with 2 field entries which could have the below properties:

   name = "Description"
   maxSize = 12
   quoted? = true
   text? = true
   delimiter = ","
   

   name = "Magic Number"
   maxSize = 4
   quoted? = false
   integer? = true
   delimiter = ""


The above properties describe the line format quite accurately, thus they are sufficient for driving code to parse or construct such lines. So, with that format we can construct an appropriate model to store the data, customize a table control to display the data, serialization and deserialization code and what else we might need. Also note that the two fields may or may not share the same properties. In the OOP world, such specialization is a bit of problem and either we'd had to spread the properties among specific classes or put all of them in a base class and just let subclasses to ignore some of them. In a prototypal inheritance, Property model that is, classes do not exist. The properties define the object class.

As an example, our deserialization routine can construct a regular expression from the above format, on the fly, to extract the fields from the line.
Eg, pattern = ^"([^"]{,12})",(\d{,4})$

That way we can create an infinite number of little parsers to extract data, even from cranky formats, simply by taking advantage of regular expressions driven by properties. Cool, isn't it? And the best part is that we don't have to hard code format-logic in our code.

OK, that's the basic idea. The main point is that if we declare data relationships and data properties we can exploit run-time introspection and that's a powerful design technique. Whatever we do we'll have to add  functionalities at some point in the one way or the other. If you don't automate, somehow, the data manipulation you'll have to explicitly do it. No way to avoid that.

Monday, May 24, 2010

Dungeon Master, a draft

I played Dungeon Master in the late 90s. It was a period on which I was playing adventure and role playing games from the 80s and the early 90s. I didn't have a copy of the DM manual and I still don't know if the manual would have a list of the magic symbols and/or any ready spells. I had to collect countless scrolls before I could decipher the symbols on the right top panel of the game.

Unfortunately, I never finished Dungeon Master. I do remember that I had mastered it but I don't recall the reasons I stopped playing it. I was probably just one level before the final boss. The dark wizard, Lord Chaos. I didn't need to draw any maps except from one level. That map is slightly visible on the below sheet, as it was drawn on the back page. Dungeon Master was a great game and I really enjoyed it.


Saturday, May 22, 2010

How to make wealth

How to Make Wealth is a great and enlightening essay. Paul Graham is great writer and thinker.

Here I highlight 3 excerpts (or paragraphs) from the above essay.
I can remember believing, as a child, that if a few rich people had all the money, it left less for everyone else. Many people seem to continue to believe something like this well into adulthood. This fallacy is usually there in the background when you hear someone talking about how x percent of the population have y percent of the wealth. If you plan to start a startup, then whether you realize it or not, you're planning to disprove the Pie Fallacy.

A programmer can sit down in front of a computer and create wealth. A good piece of software is, in itself, a valuable thing. There is no manufacturing to confuse the issue. Those characters you type are a complete, finished product. If someone sat down and wrote a web browser that didn't suck (a fine idea, by the way), the world would be that much richer.

Understanding this may help to answer an important question: why Europe grew so powerful. Was it something about the geography of Europe? Was it that Europeans are somehow racially superior? Was it their religion? The answer (or at least the proximate cause) may be that the Europeans rode on the crest of a powerful new idea: allowing those who made a lot of money to keep it.

Hackers & Painters was a great read and it's one of my all-time favorite books. If you don't want to buy the book you can read the essays at http://www.paulgraham.com/articles.html


By the way, there is a bug in the last index page, of Hacker & Painters. Can you spot it?

Monday, May 17, 2010

PLAN, bindings by name?

PLAN is a small framework which I've developed in C++, so I can declare application's behavior in one place. At the time, it's immature. In the future I intend to add JavaScript support in my projects (Qt4 framework). That will allow me to get rid of C macros and do modifications and inspection at run-time.

It's quite obvious that I repeat object names in the below example. I'm thinking of implementing bindings by name in the future, thus duplicated and error-prone code will be removed.

PLAN(on-download-items, C_(*T*, markItemsModel) <<
                        C_(*T*, @on-download));
PLAN(on-download-bcItems, C_(*T*, markBcItemsModel) <<
                          C_(*T*, @on-download));
PLAN(on-download-clerks, C_(*T*, markClerksModel) <<
                         C_(*T*, @on-download));
PLAN(on-download-groups, C_(*T*, markGroupsModel) <<
                         C_(*T*, @on-download));
PLAN(on-download-departments, C_(*T*, markDepartmentsModel) <<
                              C_(*T*, @on-download)); 
//
PLAN(on-download, C_(~IsDlgMarked, *DROP*) <<
                  C_(*T*, disableDlg) <<
                  C_(*T*, downloadFile) <<
                  C_(*T*, enableDlg));
PLAN(on-file-downloaded, C_(*T*, @on-load-model));
PLAN(on-load-file, C_(*T*, OpenFileDialog) <<
                   C_(*T*, @on-load-model));
PLAN(on-load-model, C_(*T*, detachView) <<
                    C_(*T*, loadModel) <<
                    C_(*T*, attachView) <<
                    C_(*T*, customizeView));


By the way, if I tell you that I use dialogs and tables to display data, can you understand how my application behaves? Imagine that a button click can trigger a "on-download-items" event, for example.

Sunday, May 16, 2010

Leverage work that has already been done

Anders Hejlsberg: Leverage is everything today. Your computer is, from a programming perspective, basically a bottomless pit. You could write code from now until the day you die and you would never fill it up. There's so much capacity, and end user expectations keep going up and up and up. The only way you really succeed is by finding smart ways to leverage work that has already been done. That wasn't the case if you go back 25, 30 years ago. You had 64k of memory, well, gee, that would fill up in a month or two.
[Masterminds of Programming]

Saturday, May 15, 2010

Restartable Blocks

Michael Abrash (an assembly guru) coined that term in his book Graphics Programming Black Book.
Restartable blocks; that is, reading a chunk of data, operating on the data until it runs out, suspending the operation while more data is read in, and then continuing as though nothing had happened.

I've used that technique many times in the past. As an example, in one of my projects I had to serialize and deserialize a tree structure. I didn't use a 3rd party library at the time to do the job for me and loading small data packets from a hard disk, in a loop, isn't quite efficient. Anyway, the routine "loadNode()" was using restartable blocks. It was loading let's say 1000 data records from a file on a buffer, in one read, and it'd return only one node at a time; sort of a generator routine.

teaser:
With Quake, Carmack realized, he wanted both a programmer who could work with his engine and someone who could experiment with his early work. Romero had once assumed both roles. With the distractions of Doom's success, it seemed to Carmack, he would assume neither.

[...] For the programming, there was no one better in Carmack's mind than the veteran coder Michael Abrash. It was Abrash's book on power graphics programming for computers that Carmack and Romero had used to learn  how to program the graphics for their earlier games.
[Masters of Doom: How Two Guys Created an Empire and Transformed Pop Culture]

DOOM, the last bug

This is an excerpt (~5 minutes) from Romero's interview on Matt Chat. If you want to get the full interview in MP3 format, check out my previous post.


[01:28:30] The last bug that we had in DOOM was the most mind stumping bug that we had. But we only had that bug for 2 days. (laugh) And the thing about that was... the game when we were doing our final burn-in tests on it, just running it on everybody's machine in the office to see what' d happen if it run, yeah I mean it was like...

We looked in Nintendo for everything, right? We've looked it, and Nintendo's design and their quality and all of that stuff, to gauge our own quality against. So, the thing about Nintendo games is you can leave them plugged into a cartridge and they will run forever because they had their Q&A process down to a science. I mean they would not let any game come out if it had a glitch on the screen. So that was what we wanted to do and we didn't have a Q&A team at id. We were Q&A, the developers were the Q&A team, so, you know, that didn't exist.

So you know, as precises as we were with our programming and as the nasties as we were with our design and everything, we used all of that on testing our games as well. And so we left those, we left the game running on everybody's computers just to see if anything will happen; we don't want that Nintendo glitch kind of issue to come up because it needs to be fixed. It can't be one single thing wrong.

And randomly computers would lock up forever. Seemingly forever. They're just like... the game is like be running in demo mode, you know, and during the demo loop somewhere it was like kchh, freeze, everything, and it was just like woooow, what is going on? This is really nuts! And it was random, it wasn't like it was any specific time and Carmack was trying to nail it down like what could be stopping the game from running, you know?

And he finally found what that was and it ended up being... we were using the timer chip in the PC to time the refresh, you know, how fast the game should run. The game simulation part of the game ran at 10 frames a second and the refresh of the screen was at 35 frames a second. It was half of Wolfenstein's. But it insured that it was going to run at the frame rate; at 35. And what was happening was the timer chip in the PCs, they would have... you can setup the timer chip to be a certain number, and it would just time like crazy and you  would... if you set it to zero it would time out to 4 billion, you know, in days, so you know that's not really an issue. (laugh)

But yeah, we didn't want to have our game locking up and what happened was when the game was running we never did clear the timer chip value so it was some random number and when that value flipped over from all the FFFFFFFF over to zero, that's when the game froze. Because it was looking for a bigger number than that and it wasn't one; it was a lower number. So you're locked in this check that it was not going to happen again, ever.
Carmack simply fixed it by zeroing that out at the beginning of when the game run, and then every once in a while just zero it like at the beginning of I guess the level loader or something, and that fixed it! And so that was only like a 2 day bug, but that was like a crazy insidious bug. We had one on Quake that was pretty crazy as well.

Thursday, May 13, 2010

Machinarium, concept art

Dedicated to adventure games aficionados ;-)
Amanita Design studio was established in 2003 by Jakub Dvorsk after finishing art school, he created his first flash game Samorost 1 as part of his diploma. Later joined by former schoolmate animator Valav Blin and together with musician Tomas "Floex" Dvorak and sound maker Tomas "Pif" Dvorak he created sequel Samorost 2 along with a couple of other smaller flash games and some music videos. They were joined by programmer David Oliva, painter Adolf Lachman and 2nd animator Jara Plachy to form the team that created Machinarium. Amanita are based in the Czech Republic, in 3 different cities (Prague, Brno and Pardubice).

Inventing the whole Machinarium world and then each place, location and every detail took us pretty a long time, but it was maybe the most enjoyable part of the whole development process. It required hundreds of sketches and notes and of course you must literally live in that world for some time.

It's not easy to say how much time we need for each location, but we have spent about three years on this game so it's more then on month for one location.

A lot of inspiration came from old rusty machines, abandoned factories and industrial buildings. Besides that we are influenced by many science fiction books and films (Stanislav Lem, Douglas Adams, Jules Verne, Ray Bradbury, Stanley Kubrick, Karel Zeman) and also by older adventure games (Grim Fandango, Myst, Gobliins, Discworld, Neverhood or Monkey Island).

Tuesday, May 11, 2010

Machinarium, Runaway 3, Black Mirror II (reloaded)

Hey, check out what ACS courier delivered to me this morning!


Notice the "Collector's Edition Includes: Game DVD, Music CD, Booklet and Poster"  on the machinarium title. I love such stuff!

When laptops refuse to start-up

My sister called me today at work.

Catherine: "Nick you've got to check out my laptop. It doesn't start-up!"
Me: "What? Did you broke it?"
Catherine: "Noooooo"

It was about my old Acer Aspire 5101 ANWLMi laptop which she now owns. My sister uses it only to surf the Internet, checking out her Facebook profile, emailing, writing documents, e.t.c. Aspire 5101 is a fine machine for that stuff.

And here I am, ready to check it out.
Boot. BIOS screen. System checking. System test loops infinitely. Motherboard problem?

Ah, good bye laptop. RIP. You served us well.
That was my initial thought. Well, it lasted only 10 seconds because I had already experienced a similar problem with my new laptop, which you can view in the About page.

A different version of the same problem, to be more precise. My (new) laptop didn't display a BIOS start-up screen. Just a black screen. Plus when I tried to switch it off, it would refuse to obey me, and its heat started to rise. The only solution, of course, was to unplug the battery. OK, I did that. I waited 2-3 seconds, then I put the battery back in the laptop, turn it on, and voila. It worked!

I don't think the battery caused the laptop to malfunction (in my case) but rather the mainboard. The batteries on both laptops work fine, and the recurrence of the same problem on a different laptop testify (?) my allegation. And yes, the battery trick worked on the Acer laptop, too, thankfully.

To be honest, I wouldn't have the slightest clue if I hadn't experienced the "black screen" mystery in the past. The automatic "system testing" on the Acer laptop was misleading and I would had thrown in the towel and sent it to professional technicians to resurrect it.

Sunday, May 9, 2010

Replace your LED mouse

I had a Microsoft optical (LED) mouse for years. It came along with my new (back then) desktop PC. Before that I had a mechanical mouse. The optical mouse was a welcomed change, since it was lightweight, had better precision and I didn't have to clean a rubber ball and the rollers every now and again. But wait, it had a few problems. At random moments, the mouse cursor would jump on a screen edge or it would start moving across the screen without touching it! I was playing Diablo at the time and that glitch was irritating!

What was causing it? My intuition was saying that LED technology does not work well on unexpected surface changes. By that I mean that I don't drag the mouse too much, left-right or in circles. Instead, I constantly lift it a bit to reposition the device. With that technique I move the cursor wherever I want and the device remains on a specific location (it's a habit of mine which I find convenient); Could that mess up the tracking algorithm? Others say that dirty surfaces cause such effects. Maybe. Maybe not. I tried vainly various mouse pads with the prospect to stop the undesirable behavior. No result. Well, I don't care anymore.

About a year ago, I said to myself: "There must be better optical tracking technologies nowadays. Why not try a different one?".

OK then, I surfed the Internet, and I was surprised to see that companies like Microsoft and Logitech develop their own advanced surface tracking technologies.
I decided to buy Logitech Corded M500 Mouse laser device.

BINGO! Problem solved.

Plus it has nice touch feeling, backward/forward buttons and an awesome wheel with hyper-fast scrolling mode, which I now consider a must feature!

Machinarium, Runaway 3, Black Mirror II

I just ordered 3 adventure video games. Woo hoo!





Wednesday, May 5, 2010

Received vs Perceived information


This is a powerful concept to keep in our minds.

What Scott McCloud is saying is that the way our brain works, we receive/understand concrete and realistic visuals faster than more abstract entities. In the latter case, the brain must first compose things together, transform them into more concrete entities, and finally convert them into thoughts or images.

Simple example:
  • line 1
  • line 2
  • line 3
<li>line 1</li>
<li>line 2</li>
<li>line 3</li>

I am quite sure that the first bullet list can be seeing (percepted) by anyone (fast); the second only by those who are familiar with the HTML syntax.

It's not an accident that sophisticated programming editors support (at least) a syntax highlighting feature.
Syntax highlighting helps us to receive information hidden in the code quickly.

I'm really looking forward the day in which the current model of software writing will not require nested function calls or if-else chains, thus behavior diffusion across the code, but rather a way of expressing data relations and behaviors among object entities, in a totally different manner. Let's say fast-receive-perceive (?) techniques for modeling our programs.

Understanding Comics: The Invisible Art is a 215-page non-fiction comic book, written and drawn by Scott McCloud and originally published in 1993. It explores the definition of comics, the historical development of the medium, its fundamental vocabulary, and various ways in which these elements have been used. It discusses theoretical work on comics (or sequential art) as an artform and a communications medium. It also uses the comic medium for non-storytelling purposes.

Tuesday, May 4, 2010

An actual Turing machine!

A month ago I saw this post on programing reddit,
"While thinking about Turing machines I found that no one had ever actually built one"

and it's about the site http://aturingmachine.com/


Of course, Turing machines were not devised to be used like actual computers.
The Art of Computer Programming, Volume 1
1.4 Some Fundamental Programming Techniques
1.4.5 History and Bibliography, pg 230.

[...] The first interpretative routine may be said to be the "Universal Turing Machine", a Turing machine capable of simulating any other Turing machines. Turing machines are not actual computers; they are theoretical constructions used to prove that certain problems are unsolvable by algorithms.
Nevertheless, that's a really impressive work.

(*) I won't be surprised if you tell me that this is the first time you encounter the term "interpretative routine".

Knuth, emphasis on function as well as form is basic to design problems

The Art of Computer Programming, Volume 1
2.2 LINEAR LISTS
2.2.1 Stacks, Queues, and Deques, pg. 238

[...]

We must decide in each case how much structure to represent in our tables, and how accessible to make each piece of information.  To make such decisions, we need to know what operations are to be performed on the data.  For each problem considered in this chapter, therefore, we consider not only the data structure but also the class of operations to be done on the data; the design of computer representations depends on the desired function of the data as well as on its intrinsic  properties.  Indeed, an emphasis on function as well as form is basic to design problems in general.

A Visit to id Software, 1993

Joe Siegler IM'd me a couple weeks ago and said he found a VHS tape that had some DOOM footage on it before its release and if I didn't want it he was gonna throw it out.

I said, "Send it to me immediately."

So now I finally got it, ripped it to digital and then used iMovie to present it to anyone with an interest in DOOM history. The Vimeo page has more explanation on it so I won't go into detail here - check it out!

 - Romero

Sunday, May 2, 2010

Elements of Programming, Notes

Here I'll post notes from Elements of Programming (Alexander Stepanov, Paul McJones) that are interesting and insightful, IMO. That takes (will take) a lot of time because I do it in my free time.

here we go,
  • As with other areas of science and engineering, the appropriate foundation of programming is the deductive method. (pg ix)
  • Discovering the architectural principles of the book should be the reader's goal. (pg ix)
  • Starting with a brief taxonomy of ideas, we introduce notions of value, object, type, procedure, and concept that represent different categories of ideas in the computer. (pg 1)
  • A central notion of the book, regularity, is introduced and elaborated. When applied to procedures, regularity means that procedures return equal results for equal arguments. When applied to types, regularity means that types possess the equality operator and equality-preserving copy construction and assignment. (pg 1)
  • Categories of Ideas: Entity, Species, Genus.
  • An abstract entity is an individual thing that is eternal and unchangeable, while a concrete entity is an individual thing that comes into and out of existence in space and time. (pg 1)
  • A function is a rule that associates one or more abstract entities, called arguments, from corresponding species with an abstract entity, called the result, from another species. (pg 2)
  • A datum corresponding to a particular entity is called a representation of the entity; the entity is called the interpretation of the datum. We refer to a datum together with its interpretation as a value. (pg 2)
  • A datum is well formed with respect to a value type if and only if that datum represents an abstract entity. (pg 2)
  • An object is a representation of a concrete entity as a value in memory. An object has a state that is a value of some value type. (pg 4)
  • Values and objects play complementary roles. Values are unchanging and are independent of any particular implementation in the computer. Objects are changeable and have computer-specific implementations. (pg 4)
  • Functional programming deals with values; imperative programming deals with objects. (pg 5)

Saturday, May 1, 2010

Prince of Persia, the Movie


plot: Set in medieval Persia, the story of an adventurous prince who teams up with a rival princess to stop an angry ruler from unleashing a sandstorm that could destroy the world. Which is why after the prince was tricked by a dying Vizier to unleash the Sands of Time that turns out to destroy a kingdom and transforms its populace into ferocious demons. In his effort to save his own kingdom and redeem his fatal mistake, it's up to the prince and the princess to return the sands to the hourglass by using the Dagger of Time, which also gives him a limited control over the flow of time.
I've played the first Prince of Persia (mastered it, to be precise) and the PoP 2: The Shadow and the Flame video games, but none of the 3D titles. The movie is based on the The Sands of Time, a 3D title. Nevertheless, I'm looking forward to watch it :-P

Prince of Persia, IBM version

Memories: Prince of Persia (1989 version) was pre-installed in my (now prehistoric) IBM PS/1, along with Duck Tales: The Quest for Gold and Rick Dangerous II



Thursday, April 29, 2010

Making and Breaking the Grid

Thoughts on Structure: An introduction
[...]
Like items are arranged in similar ways so that their similarities are made more apparent and, therefore, more recognizable. The grid renders the elements it controls into a neutral spatial field of regularity that permits accessibility - viewers know where to locate information they seek because the junctures of horizontal and vertical divisions act as signposts for locating that information. The systems helps  the viewer understand its use. In one sense, the grid is like a visual filing cabinet.


I read about the typographical grid (an organizing principle in graphic design) in the book About Face 3: The Essentials of Interaction Design, Part II: Designing Behavior and Form. Whoa! I was struck by a bolt of lightning. I learned something really useful and powerful at the same time. From that moment, I see graphic interfaces from a totally different perspective. Now I consider grid a must in my designs. Not only it arranges elements in more appealing, to human eye, positions but it also gives you a form to work with. To learn more about the grid and get a feeling of how professional designers make use of that technique, I bought a copy of the book, which I already mentioned,  Making and Breaking the Grid.

Well, I began to use that technique and manually arrange, and resetting, the GUI elements. By manually,  I mean that I had to write extra code. Unfortunately, the programming environment I used did not support grid-like behavior.

And then the Qt framework came.

A couple of weeks ago I decided to stop wasting time with inferior programming frameworks and switch to a better one. I choose Qt. Every time I explore Qt,
I have a that's great, that's cool, that's f*cking awesome, moment.
( I had a similar experience with the Lisp programming language.)

Yeap, Qt has layout managers; Qt classes that do all the dirty work for us.
You can either write code to handle the layout objects or use the Qt Designer,
which is of course much easier, especially for beginners.






Qt Designer in action. Watch and observe the grid structuring and the
auto arrangement of the objects, while we are resizing the form.




Bonus link: Let's Build a Grid

Sunday, April 25, 2010

How good things are made

Good programmers, designers, architects or creators of any kind are simply thoughtful. They are so passionate about making good things, that they will study any discipline, read any book, listen to any person and learn any skill that might improve their abilities to make things worthy of the world. They tear down boundaries of discipline, domain or job title, clawing at any idea, regardless of its origins, that might help them make a better thing.

Scott Berkun: Why Software Sucks
http://www.scottberkun.com/essays/46-why-software-sucks/

What is the role of math in computer science and programming in particular?

In the book Masterminds of Programming, Peter Weinberger gave an answer which,  in my opinion, is a good one.

Peter: My degree is in math, so I'd like to believe that math is fundamental. But there are many parts of computer science, and many kinds of programming, where one can be quite successful without any mathematics at all.
The use (or usefulness) of mathematics comes in layers. People with no feeling for statistics or randomness will be misled over and over again by real-world data. There's mathematics in graphics, there's lots of mathematics in machine learning (which I think statisticians think of as a form of regression), and there's all sorts of number theory in cryptography. Without some mathematics, people are just cut off from understanding large parts of computer science.

Never heard of  Peter Weinberger?
How about the AWK programming language?
Al Aho, Peter Weinberger, Brian Kernighan

Sunday, April 18, 2010

Cloudy with a Chance of Meatballs

I watched it yesterday. What a funny movie!
Geeks will love it ;-)

John Romero on Matt Chat

Dr. Matt Barton is a professor of English at St Cloud State University in St Cloud, MN. He is the author of two books on video-games: Dungeons and Desktops and Vintage Games (co-authored with his friend and colleague Bill Loguidice). He is the co-founder of Armchair Arcade (website) and a lifelong gamer. Many of his articles and reviews have been published online as well, particularly at GamaSutra, Game Studies, and Adventure Classic Gaming.


I really like, and appreciate, Matt Barton's work on retro video games.
His Matt Chat, YouTube channel, rocks!

Well, as the title indicates, this blog post is about John Romero interview on Matt Chat. And yes, I'm a fan of John Romero :-)

But before jumping on the interview videos, I want to mention a few additional links:


My copies of Vintage Games and Masters of Doom, side by side.

















Here is Romero's interview in 5 parts:









Sunday, April 11, 2010

Compile Qt libraries for static linking

Here I describe a Qt4 setup for static linking the libraries in order to
distribute executables on Windows platform, with no DLL dependencies.

First of all, download and install the Qt SDK for Windows (LGPL) version,
which is based on MinGW.

Lets say that we install it on K:\Qt.

While developing our applications it's wise to use the shared
(DLL) Qt configuration, because it has faster build time.
Moreover, I won't even configure the static Debug mode because
it produces huge (>100 MB) executables! The static Release mode
is just fine.
(BTW, I switch to static Release mode only if I have to
test it, or, of course, when it's time to release it.)

Make a copy of K:\Qt\2010.02.1\qt
and name it K:\Qt\2010.02.1\qt_static.

Our static configuration takes extra space, but who cares?

Now copy K:\Qt\2010.02.1\bin\qtenv.bat and put it in
K:\Qt\2010.02.1\qt_static as
configure_static.cmd.
Modify it to match the below shell script:

@echo off
set INCLUDE=
set LIB=
set QTDIR=%CD%
set PATH=%CD%\bin
set PATH=%PATH%;%CD%\..\bin;%CD%\..\mingw\bin
set PATH=%PATH%;%SystemRoot%\System32
set QMAKESPEC=win32-g++

configure -release -static -platform win32-g++ -nomake examples -nomake demos -no-exceptions -no-rtti -no-qt3support -no-scripttools -no-openssl -no-opengl -no-webkit -no-phonon -no-style-motif -no-style-cde -no-style-cleanlooks -no-style-plastique -qt-libjpeg -qt-zlib -qt-libpng

echo run "mingw32-make sub-src" to build core Qt libraries only.


Before executing it we need to modify some configuration parameters.
Open K:\Qt\2010.02.1\qt_static\mkspecs\win32-g++\qmake.conf (text file) and edit
QMAKE_CFLAGS_RELEASE = ... to
QMAKE_CFLAGS_RELEASE = -Os -momit-leaf-frame-pointer

Now, open the command line console, jump in qt_static folder and
run configure_static.cmd.

As soon as configure is finished, run mingw32-make sub-src
to build everything except examples and demos. A plain mingw32-make
will build everything, but that would be a waste of our time.

Notes:
References: