Sunday, March 15. 2009How to Beat SimTowerSimTower -- we've all played it, many of us have loved it, none of us have beat it. Until now. So, here we go: the definitive guide to beating Sim Tower! 0: Get the GameIt's hard to beat a game you can't play, so getting a copy of the game is a good place to start. I got mine at Abandonia. A note here: the game will run under Darwine on Intel-based Macs... Just don't try and save -- that doesn't work. 1: Starting your Tower: hitting two starsAfter the game is installed and started, begin your tower by using the build-a-lobby-in-the-bottom-left-corner-of-the-screen trick to double your money, then build a lobby that is the entire width of the screen. After you have built the mega-lobby, start building offices. Lots of offices. Three floors worth of offices. In addition to offices, build stairs. I build them approximately half a screens width from the right side of the screen, then every screens width after that. It doesn't really matter, though -- all that matters is that you've got three floors of solid offices and stairs going to all of them.
By the time this is done, you should have two stars (300 population). 2: Fast food: three starsGreat -- you've got two stars. Only three more to go. And how will we get there? Fast food. Why fast food? Well, the hardest part of the star requirements is the population, and fast food restaurants have the highest population to space ratio. Also, no one seems to notice if the only thing in your tower is fast food and office space. So, time to start building! Your first order of business is to build two security offices. It doesn't really matter where you put them, all that matters is that you have them -- they are the only requirement for three stars. Stick them under ground, at the beginning of a floor -- where ever. Now that that's out of the way, it's time to start building fast food. Your goal is to build eleven (yes, 11) floors of fast food. To do this, you will also need elevators. Lots of elevators. You will need about six, distributed across the length of your building. I like to build them in pairs:
Additionally, you will need to make sure that the lazy sims working in the offices don't use these elevators. Use the inspector tool to look at each elevator, then click the floor numbers to disable floors 2,3,4. Also, I've found it helpful to have one elevator which goes to odd-numbered floors and another which goes to even-numbered floors. Try that too. Oh, yea, and make sure that all the elevators have eight cars in them. At some point in the process of building this unholy pile of fast food, you'll get a population of 1000 and hit three stars. Cool! On to the next step. 3: Cinemas: A (brief) change from fast food (four stars)Once you've hit three stars you'll get the option to build even more exciting things like restaurants, shops and party halls. But just go ahead and ignore those. The only things you should be concerned with are:
Alright, and once you've done that, just go back to building more fast food. At some point here, you will hit a population of 5,000, the VIP will come and you will get four stars. Good job. And if you get to 14 floors and still don't have four stars, just skip down to the next section anyway. Oh, your building will catch on fire too. Just pay to have it put out. 4: Metro station, express elevators and more fast food (five stars)Ah, four stars. You think you're almost there, don't you? Ha! By now, you should be up to about 14 floors. You will finally get a break from the tedium of building fast food as you get to build a sky lobby and revamp your elevator system. So here's what to do:
And there you have it -- do this up to floor 23 or 24, and eventually you'll hit a population of 10,000 and five stars. Huzza! 5: One last thing...Phew, you're at five stars and you've probably got a population of close to
15,000. Your first order of business is to get your population up and over
15,000 (the requirement for a "Tower" ranking). Keep building fast food until
you've got that Once you're over 15,000 population, you've only got to do one more thing: build a cathedral. To do this, pick two express elevators which are at least the width of a cathedral apart, then extend them up all the way to the 100th floor. Build a small lobby on the 90th floor, place the cathedral on the 100th floor, then build an elevator to connect them. Now you've just got to wait for someone to get married, and your tower will be awarded the rank of "Tower"! (just don't forget to turn off fast mode so you can enjoy the wedding). And that's it! You're done
ResourcesA couple of useful resources: Converting TODOs to Tickets?I work on a lot* of projects which are too small to warrant a full-blown bug tracker (DrProject, Trac, etc), but too big to keep track of bugs/TODOs "just" in code. So I got thinking:
For example, given the code:
Would generate a "TODO" file like this:
And with the liberal use of a 'tags' file, it could even fake editor integration (eg, jumping to tag 'TODO001' would take you to line 45 in foo.c). So, what do you, the Internet, think? Would this tool be more useful than grep? *: read "a few" Tuesday, February 24. 2009ohmygoodnessihatejavascriptUg.
Ok, good and sane so far...
Alright, that's still pretty sane...
Wait... WHAT?! Yes, you have it folks... Javascript can't actually hash objects into dictionaries -- it uses their toString function. Pretty unique and immutable, 'eh?
Ug. Javascript loses. Hard Monday, February 16. 2009Seven ThingsSeven Things You Probably Didn't Know About Me Well, Andrew has finally convinced me to start using Twitter, so I guess the next logical step is to get on with being part on an Internet Meme! So, seven things you may or may not know about me:
And, hhmm... Friends with blogs...
Saturday, February 14. 2009Apple Migration Assistant: Thanks for the fonts!It turns out that Apple's Migration Assistant ALSO breaks fonts! After migrating, Hex Fiend started crashing on launch... And when I downloaded the source and ran it through gdb, I noticed it was crashing because it couldn't load a font. So I downloaded the font again and double-clicked it to install it... But, nope -- Font Book started crashing too! Hurra! Even the font selection dialog (apple-t) was crashing! Hurra for error checking! Anyway, it turns out that the culprit lay in ~/Library/FontCollections -- all my old font collections, which (for whatever reason) make my new laptop very unhappy. After cleaning out those, though, everything seems to be happy... For now... Thursday, February 12. 2009Thanks Apple Migration!The situation: I've just bought a new computer. Sweet. I want to migrate all the "stuff" from my other computer. Cool. They even have a tool for that! But... Crap. If you've already got an account on the new machine, you can't migrate an account with the same name from the old machine (because, hey, who uses the same name on two machines?). Ok, re-install, try again... But... Crap. Can't mount my encrypted backup from the install environment. Ok, create another account with a new name, migrate, trash new account, use old account. And everything is happy. Except... Not quite. Apparently not only does it migrate my home directory, but everything! Yea, all those old, broken, Power-PC only libraries? Yup, here to muck up my new machine Ug. Apple migration assistant, you suck Fix Apple's no-good-very-bad Trackpad AccelerationUg, Apple doesn't quite seem to be able to get it right with their touch pads. Alright, I feel a rant coming on, so I'll get to the point, then rant. Ok, that's it. Now for the rant. If you've ever used an Apple computer, you've doubtless noticed the brain dead mouse acceleration model. And it's even worse when you're using a laptop. I frequently need to two or three times before I can successfully click text. When I was on my (beautiful, lovely, wonderful) 12" PowerBook, I used a great little piece of software called SideTrack to give me side scrolling, right clicking and everything else I wanted. But now that I'm on a very mediocre 13" MacBook, I have to live with crappy Apple drivers, silly two-finger scrolling (which can't do continuous scrolling) and the aforementioned acceleration issues. Oh well... I've got the accelleration stuff (mostly) fixed now... Maybe I'll figure out how to fix the scrolling at some point two... PS: I wonder if Fitt's Law takes acceleration into account? Wednesday, February 11. 2009Testing for Unicode SafetyAfter yesterdays post, Greg suggested I write another on how to test for Unicode safety... And unfortunately I've got some bad news: it's hard. You never know when some developer, somewhere, will unintentionally encode or decode something the wrong way (for example, But there is hope! In my experience, almost all Unicode-related issues follow the same pattern: someone using The first is easy to check for: grep through the code for The second is harder to check for, and requires an understanding of both the code base: all of the points where the code interacts with other parts of the system (filesystem, database, network) must be found and checked. Finally, it isn't a bad idea to throw some Unicode into the test suite. Instead of calling mock users 'user0', 'user1', Call them u'\u03bcs\xeb\u044f' (u"μsëя")*. Keep a central "database" of these sorts of strings, so it's easy for developers who don't normally write in Cyrillic to use Cyrillic characters in their code (I keep my own personal list at http://wolever.net/~wolever/wiki/unicode_audit -- a url I can now type from memory). One word of caution, though: you're asking for world of pain if you actually think you can commit UTF-8 encoded text -- any number of things will break (subversion may helpfully fail, your editor may helpfully re-encode the file, your unenlightened developers will complain about funny question marks in their code, etc...). Instead, have a central file which defines these "canned test strings" using escaped Python strings (ie, u'\u03bc...') then import that into your test suite:
Or tar up all the offensive files, then write a script to un-tar them when they are needed**. So, to sum it up:
Then maybe, if you're lucky, all those inconsiderate people who have the audacity to ask for more than 127 characters will be able to use your application *: A good choice both because it's easy for ignorant North Americans like myself to see that's it's correct. **: This is how I tested DrProject's handling of Unicode filenames which are checked into the Subversion repository. Tuesday, February 10. 2009str(...): 'yer probably doin' it wrong.Unicode is an ugly beast... And until people start standardizing on Python 3k*, we're going to have to live with the eccentricities of Python 2's strings. But, fear not! There is (at least some) hope. By changing a few patterns in the way you code, you can alleviate the bulk of Unicode-related problems. First, using the str function. In just about every case, if you're using the str function, you're probably doing it wrong. Let me demonstrate:
Cool, we can hash things then print out the hash:
But, wait... What happens if the thing we're hashing isn't a string (even though it can be represented as a string):
Oh no! Ok, let's fix the code:
Great -- we can hash numbers now:
And, for most people who only speak English, this is a perfect place to stop.
After all, everything is a Well... No. What happens if the input is a
Crap. Where the heck is 'ascii' coming from? Well, it's a long story (which I've covered over at Encoding and Decoding Text
in
Python),
but basically the "Alright...", you're probably thinking, "If the problem is with Ok, let's see what happens.
Yup, that's right -- you just can't win What's happening here? Well, this time, the Confused yet? So how can we save ourselves from all this insanity? Actually, it's not too difficult:
And what about those
So there you have it.
A quick and fairly easy way to avoid many of your encoding-related options If you're still not quite feeling comfortable with all of this, though, take a read over Joel Spolsky's The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) *: My newly installed Debian 4 machine is still running Python 2.4 (released December 2004)... So that wait might be a while. Tuesday, February 3. 2009iconv: making character encoding just a tiny bit less hellishUg, I hate character encodings. But there is a tool that can help to make your life slightly (slightly) less hellish: iconv. It will convert a bag of bytes from any character encoding TO any character encoding:
Where the -f flag is "from encoding" and the -t flag is the "to" encoding. latin1 is also a good candidate for the "from" encoding. Just don't go and re-encode a database dump, then leave it running for a few days, THEN realize you've gotten it wrong... Monday, January 26. 2009Renaming projects in DrProjectAfter going through one DrProject project rename, I thought I might document the process for the next poor soul who needs to do the same. 0: Backup your databaseYou weren't thinking of doing this without a backup, were you?vv
And, while we're here, we might as well stop the server, just to make sure no one mucks with our instance while we're doing the rename:
1: Update the project name in the databaseUnfortunately this is not as simple as a simple "update" because DrProject's database does not have "ON UPDATE CASCADE" set. Fortunately, however, it DOES have "ON DELETE CASCADE" set, so we can just find all of those and add the UPDATE case in there too. First, find all the existing CASCADE statements:
The drp_constraints file should look like this:
Now it's time to make a script that will remove all these constraints, then re-add them with an "ON UPDATE CASCADE". First, check that, when you run the command below, the output matches what I've got:
Then go for it:
(ha! I bet you never knew you could do that with sed!) Great, so it all worked? Save it to a file!
Finally, throw all that inside a transaction, add the "UPDATE TABLE" and we're all done!
Check that the drp_constraint_final file looks correct... Then load it in:
And, with any luck, you shouldn't get any errors and everything will be happy 2: Rename the Subversion repositoryYou will also have to rename the projects subversion repository:
3: Update any links which may point to the old projectStop for a minute and try to think if there are any links which may point to the old project... If there are, they may be worth updating. 4: You're done!Phew! AddendumIt's worth noting that renaming a project is not very easy because the technical difficulties have always outweighed the usefulness: I've been working with DrProject for almost three years now, and this is the first time (in memory) I've had to rename a project. I estimate that it would take a bit less than a working week to properly implement this operation (that would include: hacking around SQLAlchemy's aversion to changing primary keys, figuring out a "sensible" thing to do when links point to a renamed project and then testing everything with both SQLite and Postgres), when Alan (our incredible sysadmin) and I were able to bang this procedure out in less than an hour. It is also worth noting that this procedure was so very "easy" because Postgres ensures referential integrity (ie, it won't let you mess up your data). Had we been using a database like MySQL/MyISAM or SQLite which doesn't do this, life would have been a bit more difficult. PSCheck out DrProject's successor, Basie! 100% re-written in Django, Basie is cooler than ever! Wednesday, August 27. 2008Why I Don't Like gitI've got some code checked out with git-svn, and I'd like to do two things: pull in new revisions and push up my local revisions. Pretty simple, brainless, thing, right? But we're dealing with git, so of course not
# Fortunately I'm smart enough to remember that when you
# want to push changes to SVN, you've obviously got to use:
$ git-svn dcommit
...
$
# Hurra! It worked! (at least I think...)
# Now for the next feat, pulling in more revisions...
$ git svn
...
fetch Download new revisions from SVN
...
# Phew! That looks like exactly what I need... Maybe it's not so tricky after all!
$ git svn fetch
A basie/a3c/admin.py
r13 = 45f5309121a77f33f8bd87009671727c0e2dc4a5 (zuze)
# Sweet! Now I can take a look at what has been changed
$ cat basie/a3c/admin.py
cat: basie/a3c/admin.py: No such file or directory
# Hu? I thought I just fetched it...
# Crap, right! I'm NOT supposed to use fetch, I'm supposed to use 'rebase'
# (not, of course, that I understand why "pulling in new revisions from SVN
# is equivilent to a mung-your-history-rebase... But that's ok, I guess)
$ git svn rebase
...
$ cat basie/a3c/admin.py
cat: basie/a3c/admin.py: No such file or directory
# Blast. That didn't work either.
# Right, that's because 'fetch' updates the git repository but not the
# working tree... Alright, let's try an update
$ git up
git: 'up' is not a git-command. See 'git --help'.
# Crap, right, git is too cool to have 'update'... I think I need reset
$ git reset
docs/cmdline.wiki: needs update
# hhmm... Why is it telling me that the files I edited need update?
# And how on earth do I update them?
# I give up
I guess I'll go back to Bazaar... It may be slow as molasses on a cold day, but at least it is simple enough that mere mortals can use it without resorting to Google. Thursday, May 29. 2008Python Brain-TeaserI'm working on pulling some functionality out of one object and putting it in another, and I came across this interesting problem: class Foo:
me = "foo"
class Bar:
me = "bar"
def get_me(self):
return self.me
Foo.get_me = Bar.get_me
x = Foo()
print x.get_me() What does this print? And, next question, why is that? After lunch I'll post my thoughts Continue reading "Python Brain-Teaser" Saturday, May 17. 2008SSH Connection SharingThis tip was originally posted to the python-dev mailing list, so I can't take one scrap of credit for it. Basically, since OpenSSH4, there has been an option to share connections -- that is, once you've opened one connection to a host, every subsequent connection is tunneled through the same channel, completely removing the overhead of authentication! It's quite simple, just add this to
There can be problems if your machine crashes and that file is left lying around... So adding this to your crontab will fix that:
Next time: tab completion with scp! Tuesday, May 6. 2008SVK + Unicode == :(I was not impressed when I tried to check out a UTF-8 encoded file with SVK, then got the helpful message
I was even less impressed when I searched Google for svk unicode and this blog was the first hit. Fortunately my Google-foo is high today, and I was able to find a page that gives a solution: Making sure that your locale is set to something similar to On Debian, here's how I do it:
And, of course, it may be good to put those two Oh, but wait!
It still doesn't work! It turns out that, for what ever reason, something was upset. Eventually I got it working by deleting the offending directory, then using
Hurra!
(Page 1 of 3, totaling 42 entries)
» next page
|
QuicksearchLinks
CategoriesSyndicate This Blog |
