Games can be characterized as having "perfect" or "limited" knowledge. Also, they can be "deterministic" or "random".
Another important aspect of a game is what sort of "models" one must build for your opponents (and what is the cooperation model).
Chess is a deterministic game of perfect knowledge. So are: tic-tac-toe, checkers, and go. These games are of limited interest to me, because they are effectively searches of a state space. This limits the opponent model to estimating how well they can search the state space. The simplest being, "assume they can search the space as well as I can". This makes the game no different from playing oneself.
Most games include a random element (usually dice, cards, or a spinner). The simplest games are entirely random (they could be reduced to a coin toss to determine the winner). Examples of these are Candyland and Chutes and Ladders, which are really just tools for teaching game mechanics to children.
The only example that comes to mind of a deterministic game of limited knowledge is Stratego.
Also worth mention is Poker, which is often entirely random (stud vs. draw) and may have zero public information (a counter example is Texas Hold'em). Here the outcome of a player model is boolean (bluffing or not bluffing), but coming to that decision requires great skill.
A complex game will include all of these elements: combinations of public and private information, randomness and certainty, complex models of player behavior (driven by a wide choice of possible moves at any point) and player cooperation.
A good game can be built from a simpler set, but this space tends to be better explored (will you make a chess analogue?)
Wednesday, June 29, 2011
Monday, June 20, 2011
New Space Opera
"The New Space Opera" (ed. Gardner Dozois and Jonathan Strahan) - There were a lot of good stories in here. It's good to see there is still some space opera being written today.
Sunday, June 19, 2011
Icons
Getting close!

I've been putting off doing the math for the icons :) Lots of radical threes.
Here we can see the three main icons - * for a city, ! for enemy units, @ for my units. ALH also has icons for ships, taxing, production. It also differentiates between my units on guard vs. not on guard. Not sure how important that is (although I need ships)...
I also still need to add roads and buildings.

I've been putting off doing the math for the icons :) Lots of radical threes.
Here we can see the three main icons - * for a city, ! for enemy units, @ for my units. ALH also has icons for ships, taxing, production. It also differentiates between my units on guard vs. not on guard. Not sure how important that is (although I need ships)...
I also still need to add roads and buildings.
Wednesday, June 08, 2011
Show Production
My goal is to get this thing to the point where I can do my turns. I added exporting orders yesterday, now I can display the region production.

I'm using a wrapping label, which seems less than ideal. But I wasn't sure what else would look good...
Now I need to show whats for sale (and maybe what they'll buy, but that is less useful). I also need to show unit skills somewhere.

I'm using a wrapping label, which seems less than ideal. But I wasn't sure what else would look good...
Now I need to show whats for sale (and maybe what they'll buy, but that is less useful). I also need to show unit skills somewhere.
Monday, June 06, 2011
Z Problem
Programming is all about assumptions. You have to make certain assumptions about what your software is going to encounter, and how different modules will work together. To do otherwise would require total knowledge, and the development of a system that could handle anything (which would make it smarter than any human, so you'd be developing strong AI).
As long as your assumptions hold, your software will work well. And if new features fit in with those assumptions, they will be easier to add. If they violate the assumptions, you're in for a world of hurt.
When I started the True Atlanteans client, I knew it was possible to have a z coordinate for hexes. But I didn't have any test cases, and I figured it was a long way off. Well, I just got some test cases, so I guess I have come a long way!

Once again, Tcl and Sqlite made things pretty easy. I rebuilt the tables with a z coordinate and added a couple of entries to the right click menu (yea, I have a right click menu, unlike ALH).
I also fixed the one man unit bug in the old style parser. Rereading the last blog entry made me realize that items have [ABBR], while flags do not.
As long as your assumptions hold, your software will work well. And if new features fit in with those assumptions, they will be easier to add. If they violate the assumptions, you're in for a world of hurt.
When I started the True Atlanteans client, I knew it was possible to have a z coordinate for hexes. But I didn't have any test cases, and I figured it was a long way off. Well, I just got some test cases, so I guess I have come a long way!

Once again, Tcl and Sqlite made things pretty easy. I rebuilt the tables with a z coordinate and added a couple of entries to the right click menu (yea, I have a right click menu, unlike ALH).
I also fixed the one man unit bug in the old style parser. Rereading the last blog entry made me realize that items have [ABBR], while flags do not.
Sunday, June 05, 2011
Items Up!
I must say, working with Tcl and Sqlite has been a real pleasure. Adding orders required changes in about 3 places, most being one or two lines of code: import the data from the TON file, pull the data during unit update, build the GUI items.
The items changes were about the same. My original thinking was that I would need a separate table for items, keyed by the unit id. But Sqlite lets me toss a whole Tcl list into a cell, so I just went with that...

The item box is above the old order box. I figured it would scroll pretty often, so I stuck a scrollbar on there right away (orders might need a scrollbar).
This example shows the frustration inherent with trying to parse the old file format. Units with one man don't get that man in the items (Fast Couriers are one man units in my empire).
Why?
Here is the entry for Fast Courier 416:
The star ('*') indicates this is a full data report ('-' is limited data, '+' is buildings). Then comes the unit and faction names. After that are the unit flags, then items.
Everything is comma separated, with big groups period separated (items, weight, capacity, skills).
But there is no way to tell when flags end and when items begin.
My parser is looking for a number (no flags have numbers, and any item count above 1 will have a number). I suspect ALH understands all the men types, and is checking that... or it understands all the flag names and promotes mismatches. I guess I could tell by making a new flag and seeing if ALH promotes it to an item with count 1 :)
The items changes were about the same. My original thinking was that I would need a separate table for items, keyed by the unit id. But Sqlite lets me toss a whole Tcl list into a cell, so I just went with that...

The item box is above the old order box. I figured it would scroll pretty often, so I stuck a scrollbar on there right away (orders might need a scrollbar).
This example shows the frustration inherent with trying to parse the old file format. Units with one man don't get that man in the items (Fast Couriers are one man units in my empire).
Why?
Here is the entry for Fast Courier 416:
* Courier - Fast (416), Last Outleans (6), avoiding, behind, revealing
faction, holding, receiving no aid, nomad [NOMA], 14841 silver
[SILV], 20 horses [HORS], 5 herbs [HERB], 2 mink [MINK], 4 velvet
[VELV], ivory [IVOR], mithril [MITH], 2 chocolate [CHOC], pearls
[PEAR], 2 spices [SPIC], 2 roses [ROSE], 2 caviar [CAVI], 2 cashmere
[CASH], iron [IRON], silk [SILK], pick [PICK]. Weight: 1089.
Capacity: 0/1400/1415/0. Skills: combat [COMB] 1 (30).
The star ('*') indicates this is a full data report ('-' is limited data, '+' is buildings). Then comes the unit and faction names. After that are the unit flags, then items.
Everything is comma separated, with big groups period separated (items, weight, capacity, skills).
But there is no way to tell when flags end and when items begin.
My parser is looking for a number (no flags have numbers, and any item count above 1 will have a number). I suspect ALH understands all the men types, and is checking that... or it understands all the flag names and promotes mismatches. I guess I could tell by making a new flag and seeing if ALH promotes it to an item with count 1 :)
Thursday, June 02, 2011
Orders are in!
Wednesday, May 25, 2011
git avert disaster
Let me start by saying I hate hg. I should like it, since it is fundamentally the same as git. I want to like it, but it just is unlikeable.
So, here I am in some disconnected head state, with all my patches gone from the rebase. What to do?
I forgot what I did, but I got most of my patches applied. Except one fell on the floor, and didn't show up in the history anymore (well, the commit was there with the log message, but the patch was empty).
Fortunately, there is a file in .git called "ORIG_HEAD" or something similar. Cat it, and "git checkout". Cp the bad files off to a separate space and "git checkout" back. Diff and patch, commit. All fixed!
Yea git!
- It is too complicated. In git there are commits (patches, content) and heads (names). Mercurial has versions, patches (in mq), branches, tags, bookmarks. Maybe more.
- It is disjointed. In git, everything is integrated. In hg, everything is an extension. The extensions work fine, one at a time. But bringing multiple extensions together doesn't always work well. Also, the tab completion only supports some things.
- It keeps messing up. This is the really scary part. I haven't lost anything, but twice now all my subrepos have gone into a "disconnected head" state (once after a crash, but once all by itself). I also sometimes get weird "unknown version" errors. It generally just requires "hg onsub 'hg up'", but sometimes greater voodoo is required.
- Install Cygwin git on Windows
- Intall Linux dual boot, boot in Linux, install git
- Mount the NTFS under Linux (hmm, maybe not a good idea here!)
- Use Linux git to manipulate the Cygwin repo (playing with fire!)
- Rebase the repo
- Boom
So, here I am in some disconnected head state, with all my patches gone from the rebase. What to do?
I forgot what I did, but I got most of my patches applied. Except one fell on the floor, and didn't show up in the history anymore (well, the commit was there with the log message, but the patch was empty).
Fortunately, there is a file in .git called "ORIG_HEAD" or something similar. Cat it, and "git checkout". Cp the bad files off to a separate space and "git checkout" back. Diff and patch, commit. All fixed!
Yea git!
Sunday, May 22, 2011
Stuff I've read lately
"The Oxford Book of Science Fiction" (ed. Tom Shippey) - This was really excellent. It covers about 100 years of SF, and most of the stories I hadn't read before. Really unusual.
Thursday, May 19, 2011
String Madness
I read earlier today that Denis Ritchie (or Brian Kernigan, I get them mixed up) hates C++.
Now, why would anyone hate C++?
Oh wait, I had to do some case insensitive string compares today in C++. Let's see how to do it:
Muahahahahahaa! That's evil (Note: I handled all the freaky <> using Tcl, yea Tcl!). In case you're wondering:
Solution 4, fall back to C. Thanks, that's great. Also, note it is different on different platforms, yea C. It also doesn't work on Unicode.
In Tcl?
Works on most Unicode, but, hey Unicode is broken what do you want?
Now, why would anyone hate C++?
Oh wait, I had to do some case insensitive string compares today in C++. Let's see how to do it:
- Solution 1, download hundreds of megabytes of Boost - meh
- Comment #2, Unicode is broken, yea Unicode!
- Solution three:
struct ci_char_traits : public char_traits<char> {
static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }
static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); }
static bool lt(char c1, char c2) { return toupper(c1) < toupper(c2); }
static int compare(const char* s1, const char* s2, size_t n) {
while( n-- != 0 ) {
if( toupper(*s1) < toupper(*s2) ) return -1;
if( toupper(*s1) > toupper(*s2) ) return 1;
++s1; ++s2;
}
return 0;
}
static const char* find(const char* s, int n, char a) {
while( n-- > 0 && toupper(*s) != toupper(a) ) {
++s;
}
return s;
}
};
typedef std::basic_string<char, ci_char_traits> ci_string;
Muahahahahahaa! That's evil (Note: I handled all the freaky <> using Tcl, yea Tcl!). In case you're wondering:
string map "< {<} > {>}" $code
Solution 4, fall back to C. Thanks, that's great. Also, note it is different on different platforms, yea C. It also doesn't work on Unicode.
In Tcl?
string compare -nocase $str1 $str2
Works on most Unicode, but, hey Unicode is broken what do you want?
Sunday, May 15, 2011
True Atlanteans
Lots of progress, haven't had time for updates. I am building a client for Atlantis, similar to Atlantis Little Helper (see screenshot).
Here is what I have so far:

Obviously, not as much functionality right now, but it is improving quickly. The main advantages will be that I can understand this code (currently less than 500 lines of Tcl).
Also, the code uses an internal database to store the turn information, so should be less vulnerable to disruptions (and more easily support multiple games).
This will be the main visualization tool for any changes we make to Atlantis (currently, I have already hacked in the new turn format).
Here is what I have so far:

Obviously, not as much functionality right now, but it is improving quickly. The main advantages will be that I can understand this code (currently less than 500 lines of Tcl).
Also, the code uses an internal database to store the turn information, so should be less vulnerable to disruptions (and more easily support multiple games).
This will be the main visualization tool for any changes we make to Atlantis (currently, I have already hacked in the new turn format).
Thursday, May 05, 2011
Tcl Object Notation
In the beginning, everything was a plain text file or a binary file. Binary files were easy for computers (just copy the bytes from disk into memory) and hard for people. Text files were easy for people and hard for computers.
On top of this, things were always changing. So the binary files from Word 1.0 didn't want to be read into Word 2.0 (well, 2.0 would upgrade them - but eventually, support could disappear). Text files have a way of expanding into their own Turing-complete language.
Then some mega-genius said, "Hey, let's make a text format that easy for computers and people, and backwards/forwards compatible! We'll call it XML."
And so we got this:
That's the first 771 bytes of the NewStars master file (which is 3530 bytes in full). That's turn 6 for a tiny universe. I generated a huge turn once, it was many megabytes... Every AJAX request is generating and shipping around stuff like this. If you wonder why servers can't handle many clients, why the Internet is so slow (even though we have a lot more bandwidth than the old 56k modems), and clients are so slow - XML is a big part of it.
Then another (smarter) genius said, "All these angle brackets and matching tags are just a pain. Why can't we have a simpler format?" That gave us JSON (JavaScript Object Notation, and AJAJ). Here is the JSON file from my Space Battle project:
A lot more concise. But, why do I need all the quotes and colons? Why are some things in square brackets, while others are in curlies? We can do better:
This is "Tcl Object Notation" (TON). Just as JSON yields a JavaScript dictionary, this is a Tcl dictionary. Since everything is a string, no quotes needed. No colons (dictionaries are lists with "key" "value" pairs). You just need {} for things which might have spaces (or sub-dictionaries).
This will be the turn file format for the True Atlanteans, Atlantis PBEM GUI Client.
On top of this, things were always changing. So the binary files from Word 1.0 didn't want to be read into Word 2.0 (well, 2.0 would upgrade them - but eventually, support could disappear). Text files have a way of expanding into their own Turing-complete language.
Then some mega-genius said, "Hey, let's make a text format that easy for computers and people, and backwards/forwards compatible! We'll call it XML."
And so we got this:
<?xml version="1.0"?>
<NSTARS_UNIV DIMENSIONS="2" X="400" Y="400">
<UNIV_HDR>
<STAR_COUNT>2</STAR_COUNT>
</UNIV_HDR>
<GAME_YEAR>2406</GAME_YEAR>
<TECH_COSTS>50 80 130 210 340 550 890 1440 2330 3770 6100 9870 13850 18040
22440 27050 31870 36900 42140 47590 53250 59120 65200 71490 77990 84700</TECH_C
OSTS>
<COMPONENTFILENAME>newStarsComponents.xml</COMPONENTFILENAME>
<HULLFILENAME>newStarsHulls.xml</HULLFILENAME>
<PLAYERFILEBASENAME>tiny_sparse</PLAYERFILEBASENAME>
<MASTER_COPY>1</MASTER_COPY>
<NUMBER_OF_PLAYERS>2</NUMBER_OF_PLAYERS>
<PLAYERDATA>
<RACELIST>
<RACE>
<SINGULARNAME>Ugly Duckling</SINGULARNAME>
<PLURALNAME>Baby Swans</PLURALNAME>
That's the first 771 bytes of the NewStars master file (which is 3530 bytes in full). That's turn 6 for a tiny universe. I generated a huge turn once, it was many megabytes... Every AJAX request is generating and shipping around stuff like this. If you wonder why servers can't handle many clients, why the Internet is so slow (even though we have a lot more bandwidth than the old 56k modems), and clients are so slow - XML is a big part of it.
Then another (smarter) genius said, "All these angle brackets and matching tags are just a pain. Why can't we have a simpler format?" That gave us JSON (JavaScript Object Notation, and AJAJ). Here is the JSON file from my Space Battle project:
{
"force1" : {
"name" : "Imperials",
"ships" : [
"idest"
]
},
"force2" : {
"name" : "Bugs",
"ships" : [
"bship"
]
}
}
A lot more concise. But, why do I need all the quotes and colons? Why are some things in square brackets, while others are in curlies? We can do better:
Name {Tester (3)}
FactionType { (War 1, Trade 1, Magic 1)}
Month March
Year 1
VerString {4.1.0}
Rulesetname {Ceran}
Rulesetversion {2.0.4 (beta)}
Newssheet 1
Password {none}
TurnCountdown -1
Quit 0
TaxRegion 0
MaxTax 10
TradeRegion 0
MaxTrade 10
NumMage 1
MaxMage 2
This is "Tcl Object Notation" (TON). Just as JSON yields a JavaScript dictionary, this is a Tcl dictionary. Since everything is a string, no quotes needed. No colons (dictionaries are lists with "key" "value" pairs). You just need {} for things which might have spaces (or sub-dictionaries).
This will be the turn file format for the True Atlanteans, Atlantis PBEM GUI Client.
Wednesday, April 20, 2011
Peak Civilization
(a recent article at CNN has got me all depressed)
A few years ago the drumbeat of "peak oil" picked up. Now, it seems to be mostly taken as a given. With the recent Japanese nuclear disaster (among other things), I can't help but think we have reached "peak civilization".
Early science fiction (1900, up to the 60's, even parts of the 70's and 80's) was decidedly optimistic (although not entirely). Mankind was seen as making use of greater and greater stores of energy, and going far. Stories assumed galactic civilization (some took place after many cycles of rise and fall of galactic empires).
At some point, something changed. Perhaps it was the nuclear accidents of the 70's and 80's, or the failure of fusion power. The failure of the space program (which we now see the culmination of, in the last shuttle flights - which will end the American manned space program). Science had promised us the stars, and failed to deliver.
Now, the spectre of global warming is pushing back against greater carbon based energy production. The Fukushima disaster will likely hinder, if not stop nuclear production. Green sources are notoriously inefficient, in terms of land use and construction overhead - they might replace our current production, but growth will be limited.
Science fiction has picked up on this ennui (I don't think it has caused it). Stories of galactic empire are few and far between (John Scalzi is the only current writer I know). Most stories tell of introspective and decadent remnants of humanity, living in dirt (at least, metaphysically, if not physically).
Much of our economy is based on an assumption of growth. It's unclear how we can adapt (we see this in the repeated "bubble" growth and pop cycles). Even population growth is leveling off.
Asimov wrote about computers stretching underneath the whole world (plantary AC). Now, we strive to make computers smaller and less powerful.
It seems we are destined to simply fizzle out. Staring at our belly buttons until the lights go out.
A few years ago the drumbeat of "peak oil" picked up. Now, it seems to be mostly taken as a given. With the recent Japanese nuclear disaster (among other things), I can't help but think we have reached "peak civilization".
Early science fiction (1900, up to the 60's, even parts of the 70's and 80's) was decidedly optimistic (although not entirely). Mankind was seen as making use of greater and greater stores of energy, and going far. Stories assumed galactic civilization (some took place after many cycles of rise and fall of galactic empires).
At some point, something changed. Perhaps it was the nuclear accidents of the 70's and 80's, or the failure of fusion power. The failure of the space program (which we now see the culmination of, in the last shuttle flights - which will end the American manned space program). Science had promised us the stars, and failed to deliver.
Now, the spectre of global warming is pushing back against greater carbon based energy production. The Fukushima disaster will likely hinder, if not stop nuclear production. Green sources are notoriously inefficient, in terms of land use and construction overhead - they might replace our current production, but growth will be limited.
Science fiction has picked up on this ennui (I don't think it has caused it). Stories of galactic empire are few and far between (John Scalzi is the only current writer I know). Most stories tell of introspective and decadent remnants of humanity, living in dirt (at least, metaphysically, if not physically).
Much of our economy is based on an assumption of growth. It's unclear how we can adapt (we see this in the repeated "bubble" growth and pop cycles). Even population growth is leveling off.
Asimov wrote about computers stretching underneath the whole world (plantary AC). Now, we strive to make computers smaller and less powerful.
It seems we are destined to simply fizzle out. Staring at our belly buttons until the lights go out.
Sunday, April 03, 2011
Edge of Battle
"Edge of Battle" (Dale Brown)(audio) - This one was bizarre. I don't know if his editor came to him and said "You're scenarios are too believable, it's scaring people". Here we have a group of Mexicans who believe the western US belongs to them. Then they engineer border skirmishes and steal nuclear weapons (not sure what they want the nukes for, they get blown up (reeeaal goood) before we can find out).
Why? To force the US to implement a guest worker program.
The book turns all cheery 1984 at the end too; with the Mexican and American presidents gulping down nano-tracking pills and smiling for the camera (only people with something to hide avoid swallowing nano-tracking pills!).
Why? To force the US to implement a guest worker program.
The book turns all cheery 1984 at the end too; with the Mexican and American presidents gulping down nano-tracking pills and smiling for the camera (only people with something to hide avoid swallowing nano-tracking pills!).
Wednesday, March 30, 2011
Why Not Linux
(This is about why NedOS will not be a Linux clone)
There are three main operating systems today: Windows, Linux, and MacOS.
Windows is just terrible in every way, and getting worse. It used to be that Windows had the best support for hardware. I believe Linux is better now and can only get better, and Windows will get worse. This is because Microsoft has taken to enjoying changing their driver model periodically, and that breaks old stuff. I do most development on Windows under Cygwin, and I would very much like to stop using Windows entirely.
MacOS is a non-starter. I'm not going to give Apple more money (long story). Also, MacOS is basically BSD (a Unix derivative), plus some stuff.
That leaves Linux. Linux is really very good. But it is a Unix derivative. Some say Unix is bad because it is old. Being old is not necessarily bad, but you must re-examine the assumptions, circumstances, and goals that went into the old design. Where there are changes, it may necessitate a new design.
#2 - Multi-user. This is a source of some complexity that I will be able to avoid. NedOS will be largely single user, with the possibility of some user specific configuration (a family likely has multiple computers, but different people may be on different boxes at any given time).
#3 - Software development. This will be the biggest change. All software functionality will be set at boot time. This should make things simpler, and more secure. I am considering some level of user scripting, but I'm not sure about that.
#4 - Multi-platform. This is a sore spot. I would love to run on all the hardware that Linux supports. But this is a source of complexity (and a huge effort sink). I will be forced to stick to Bochs (which should transition to Qemu for speed). I might be able to run on some real hardware at some point. But consider that my developing a 64 bit kernel means only 64 bit hardware support. 32 bit would double most of my effort.
There are three main operating systems today: Windows, Linux, and MacOS.
Windows is just terrible in every way, and getting worse. It used to be that Windows had the best support for hardware. I believe Linux is better now and can only get better, and Windows will get worse. This is because Microsoft has taken to enjoying changing their driver model periodically, and that breaks old stuff. I do most development on Windows under Cygwin, and I would very much like to stop using Windows entirely.
MacOS is a non-starter. I'm not going to give Apple more money (long story). Also, MacOS is basically BSD (a Unix derivative), plus some stuff.
That leaves Linux. Linux is really very good. But it is a Unix derivative. Some say Unix is bad because it is old. Being old is not necessarily bad, but you must re-examine the assumptions, circumstances, and goals that went into the old design. Where there are changes, it may necessitate a new design.
- Unix was designed as a simplified alternative to Multics (hence the pun in the name). That no one is making Multics clones today tells you this was probably a good move. That Unix is considered complex hints at how complex Multics must of been (I have no idea)
- Unix was meant to be run on multi-user computers. You would have one computer for possibly a dozen people to use at the same time. There might be dozens of accounts, some of whom are total strangers (paid accounts).
- Unix was created for hackers, by hackers. As much as possible, it is intended that users should be able to write their own programs, and those programs should be able to access only the resources available to that user - and no more. Thus we see all the jockeying for "root shells" and counter security practices to prevent that.
- Unix was meant to run on different types of machines. Linux has done really well here. You can run Linux on a "wall wart" (computer in a power plug), laptop, or supercomputer. In every case, you get the most out of your computer.
#2 - Multi-user. This is a source of some complexity that I will be able to avoid. NedOS will be largely single user, with the possibility of some user specific configuration (a family likely has multiple computers, but different people may be on different boxes at any given time).
#3 - Software development. This will be the biggest change. All software functionality will be set at boot time. This should make things simpler, and more secure. I am considering some level of user scripting, but I'm not sure about that.
#4 - Multi-platform. This is a sore spot. I would love to run on all the hardware that Linux supports. But this is a source of complexity (and a huge effort sink). I will be forced to stick to Bochs (which should transition to Qemu for speed). I might be able to run on some real hardware at some point. But consider that my developing a 64 bit kernel means only 64 bit hardware support. 32 bit would double most of my effort.
Monday, March 28, 2011
It's a Cookbook!
A COOK BOOK!
(apologies to the Twilight Zone)
I have completed my read through of "Tcl/Tk 8 Programming Cookbook". It reads very much more like a cookbook than a novel or textbook.
I see three possible consumer groups:
However, groups 2 and 3 should benefit.
Beginners will need to read the whole book to cover everything they need. However, the "cook book" style allows you to jump to any point and try something out. That is important for a beginner, to keep the interest up ("is there something new and interesting here that is worth my learning it").
You can jump right into GUI development. That is what got me hooked on Tcl/Tk.
For people less interested in learning Tcl, but needing to solve a particular problem - the table of contents should allow you to jump right to it. No need to sift through man pages of sometimes historically named commands.
This book is up to date, preferring dictionaries (new) over arrays (old). Most of the other Tcl books are from before dictionaries. It also mentions using the new themed widgets (ttk).
(apologies to the Twilight Zone)
I have completed my read through of "Tcl/Tk 8 Programming Cookbook". It reads very much more like a cookbook than a novel or textbook.
I see three possible consumer groups:
- People who are experts at finding information from man pages (like me, and 1% of the rest of the world)
- People who don't like reading man pages, and are interested in learning Tcl.
- People who have "that Tcl app" at work, that they need to maintain once every six months.
However, groups 2 and 3 should benefit.
Beginners will need to read the whole book to cover everything they need. However, the "cook book" style allows you to jump to any point and try something out. That is important for a beginner, to keep the interest up ("is there something new and interesting here that is worth my learning it").
You can jump right into GUI development. That is what got me hooked on Tcl/Tk.
For people less interested in learning Tcl, but needing to solve a particular problem - the table of contents should allow you to jump right to it. No need to sift through man pages of sometimes historically named commands.
This book is up to date, preferring dictionaries (new) over arrays (old). Most of the other Tcl books are from before dictionaries. It also mentions using the new themed widgets (ttk).
Saturday, March 26, 2011
Tcl and Greek
While some may say that Tcl looks like Greek to them, I have Tcl doing my Greek homework!

This is a window with just an single line text entry. It is built with the following code:

My English/Greek transliteration uses the "_" character as an escape (to handle the two letter English versions, and s/s at the end). The revGreek function is a simple state machine to check for _, and build the escaped sequence. Everything is passed through a dictionary which maps English sequences to Greek letters.
Here is the Greek to English map:
set greekDict {α a β b γ g δ d ε e ζ z η _ae θ th ι i κ k λ l μ m ν n ξ x ο o π p ρ r σ s ς _s τ t υ u φ _ph χ _ch ψ _ps ω _oe}
Greek can be converted to English with a simple function:
This is because each Greek letter is all by itself.
Building the English to Greek map is easy:
Where the Greek to English map is a simple list (where the first subelement is one Greek letter, and the second element is the English transliteration), the use of multiple English characters requires a full map (or "dict" in Tcl).

This is a window with just an single line text entry. It is built with the following code:
When I hit enter, I get:
toplevel .t
pack [entry .t.e]
bind .t.e <return> {
set s [.t.e get]
.t.e delete 0 end
.t.e insert 0 [revGreek $s]
}

My English/Greek transliteration uses the "_" character as an escape (to handle the two letter English versions, and s/s at the end). The revGreek function is a simple state machine to check for _, and build the escaped sequence. Everything is passed through a dictionary which maps English sequences to Greek letters.
Here is the Greek to English map:
set greekDict {α a β b γ g δ d ε e ζ z η _ae θ th ι i κ k λ l μ m ν n ξ x ο o π p ρ r σ s ς _s τ t υ u φ _ph χ _ch ψ _ps ω _oe}
Greek can be converted to English with a simple function:
string map $greekDict $s
This is because each Greek letter is all by itself.
Building the English to Greek map is easy:
foreach {g e} $greekDict {
dict lappend revGreekDict $e $g
}
Where the Greek to English map is a simple list (where the first subelement is one Greek letter, and the second element is the English transliteration), the use of multiple English characters requires a full map (or "dict" in Tcl).
Sunday, March 20, 2011
Strike Force
"Strike Force" (Dale Brown)(audio) - Brown must have a lot of fun writing these books. The protagonist is an American general in charge of the "Air Battle Force" (basically guys with rudimentary orbital dropships and power armor). He is so aggressive as to make Douglas Macarthur look like a peacenik.
In order to make this guy look sensible and righteous, the evil guys are almost comically evil (although, they are in Iran, so it's not entirely unbelievable). Many explosions ensue (including a ground to orbit laser attack from the Russians! pew! pew!).
In order to make this guy look sensible and righteous, the evil guys are almost comically evil (although, they are in Iran, so it's not entirely unbelievable). Many explosions ensue (including a ground to orbit laser attack from the Russians! pew! pew!).
Tuesday, March 15, 2011
Book Review Coming
Saturday, March 12, 2011
Houston, we have a keyboard
Nice!

I had a feeling once I got past the interrupt barrier things would move a lot more smoothly.
I quickly got the keyboard interrupt working (it puts the scancodes into a queue and returns as quickly as possible).
Then, I changed the final idle loop into a loop to empty this queue. Right now, it is printing the scan codes - you can see the keyboard scancodes (in hex) for "Shift, h, i, space, k, e, y, b, o, a, r, d". I am ignoring all break codes, so you don't see the Shift key released.
It was a real pain getting the screen shot for this one. I couldn't hit print screen in Bochs, no telling what that funky scan code would do to my handler :) I had to make a tiny notepad window active (you can see it peeking over the left edge), and do a full screen capture.

I had a feeling once I got past the interrupt barrier things would move a lot more smoothly.
I quickly got the keyboard interrupt working (it puts the scancodes into a queue and returns as quickly as possible).
Then, I changed the final idle loop into a loop to empty this queue. Right now, it is printing the scan codes - you can see the keyboard scancodes (in hex) for "Shift, h, i, space, k, e, y, b, o, a, r, d". I am ignoring all break codes, so you don't see the Shift key released.
It was a real pain getting the screen shot for this one. I couldn't hit print screen in Bochs, no telling what that funky scan code would do to my handler :) I had to make a tiny notepad window active (you can see it peeking over the left edge), and do a full screen capture.
Subscribe to:
Posts (Atom)