Many programming languages come with some way to run an interactive shell, or REPL (read-eval-print loop). This makes it extremely easy to test little bits of code and understand exactly what they do, and is invaluable when learning a new language or library. For example:
What’s the result of (unsigned int)atoi("4294967295") in C?
Even if you know the answer, how quickly can you prove it? How concisely can you communicate the proof via IM or email? What if it’s a poorly documented third-party library function, and not a standard one?
For quick tasks, you can just use gdb which is probably already present on any system that has gcc. Just fire up gdb on any binary, set a breakpoint on main, and run. When it stops you will be able to call functions and examine their results, and many other common REPL tasks. The binary doesn’t matter much, but you should prefer ones with debugging symbols, and if you want to call functions in a particular library, you should use a binary that is linked to that library.
~% gdb ./test (gdb) break main Breakpoint 1 at 0x8048452 (gdb) run Starting program: /home/pcl/sandbox/test Breakpoint 1, 0x08048452 in main () (gdb) set $a = malloc(1234) (gdb) call sprintf($a, "Hello %d", 12345*12345*12345) $1 = 15 (gdb) print (char*)$a $2 = 0x96c6008 "Hello 170287977" (gdb) print (unsigned int)atoi("-1") $3 = 4294967295 (gdb) print (unsigned int)atoi("4294967295") $4 = 2147483647
gdb lets you use arbitrarily-named, untyped convenience variables, as you can see in the example. The only practical difference between print $var = expr, call $var = expr, and set $var = expr seems to be that set does not additionally assign the result to a history variable. Obviously you also have the full debugging facilities of gdb available as well.
It is also possible to do this on stripped binaries with no ‘main’ function, but there are many disadvantages:
~% gdb `which echo` (gdb) inf files Entry point: 0x8048be0 0x08048154 - 0x08048167 is .interp (gdb) break *0x8048be0 Breakpoint 1 at 0x8048be0
For a fully featured REPL for C, check out c-repl.
I have this thing with games.
For many simple games, especially word games, there is a pretty straightforward strategy to follow to play a “perfect” game. Scrabble is a particularly good example. The simplest strategy is to play the best word you can, which is easily quantifiable by points. Refinements are obvious: try to save high scoring letters for bonus squares, try to make the board worse for your opponent.
Once you’ve figured the basics out, the most effective way to improve your game is to expand your vocabulary. At first, this seems like a pretty “human” endeavor. However, anyone who’s played Scrabble online or competitively is probably familiar with the nonsense Scrabble words you have to memorize to play effectively. Especially important are the ones that help you use Q, X, and Z, and 2 letter words that let you attach to another word: qi, za, qats, mbaqanga. Your spell-checker doesn’t have those words, and your dictionary probably doesn’t either. You will never use them in a sentence, and you probably won’t ever encounter anyone else using them either – unless you’re playing or talking about Scrabble.
Memorizing and searching through lists of arbitrary, otherwise meaningless items isn’t something humans are very good at. Performing precise calculations isn’t something humans are very good at either. They are, however, tasks that computers are particularly good at.
This drives me crazy.
I’ve been programming for most of my life, so for many games, coding something that can play is more interesting than actually playing myself. I’ve written bots for Scrabble, Boggle, Sudoku, Poker, and all manner of word/card/number games – many for money.
Recently, a friend introduced me to a word game on Second Life called Lexis. Lexis is basically 10 rounds of single-word Scrabble. You get 7 letters, and 7 spots to place them in, with the familiar bonus tiles: double word, triple word, double letter, triple letter. Your word must start in the left-most spot, so there is no strategy in how you place the word. The only thing to do is choose the highest-scoring word, taking into account the bonus squares, and input it as fast as possible.
Definitely a game for computers.
With a cash prize.
On one machine, the jackpot was over L$10,000 – which is about USD$35.