Thursday, November 30, 2006
This is not at all bad, because last time I sold most of those 30 due to a row that AGA - The American Go Association - started with a malicious "review" of my software, that spurned about fifteen people (mostly Americans) to purchase it out of sheer disgust with the article. All in a couple of days, so that I ran out of bubble envelopes and stamps. The AGA folks that run their website and newsletter have a financial stake in competing Go software, hence the shameless "review".
I go into detail because I noticed that quite a number of μISV regulars from Joel Spolsky's site occasionaly visit here because I'm the archetypal μISV: A one-man shop, starting from scratch, doing everything himself and able to make a living from it if he would live in a cheaper country.. And there are few things more interesting for the small independent software vendor than comparing sales figures.
My competitors will see these figures too, but I consider it part of the psychological warfare. The enemy plays a much dirtier game than handing over their trade secrets like I've done regularly. They make up lies and put them on their sites. PsyOps message: Don't forget that I don't play Go above beginner level and my software is, in terms of Go software sales in general, selling like hot cakes. 2007 is scheduled for major R&D, which includes regular Go lessons from a teacher and play on a Go server, so I will get stronger at Go and learn all principles needed for the next step: A full-fledged Go playing program. You ain't seen nuthin' yet!
Go software in the West is a niche, and for those who didn't know yet - my software is in the unique position of being boycotted by most major Western Go websites and retailers due to the disproportionate power the "old boy network" has, an established order of - mostly millionaires - who monopolized the world's Go games under the banner of "ethical game ownership". Of course this is totally bogus - all they do is fight hand and nail to protect their business interests, and anything goes.
The remarkable collusion in this little Western Go world is something to think about, to contemplate. Will it be the same in South-East Asia? That is my main (potential) market.
So far, I think not much can go wrong when I will introduce my software in SE Asia. For the most part, those who have been vilifying/attacking my software here due to the threat it poses to their bottom line are either unknown or despised there.
Of course there will be repercussions to the actions of the GoGoD/MasterGo/SmartGo kartel. If I ever manage to write the world's strongest Go program (and I really think I will be able to, and in a reasonable time as well), then one of my criteria to any dealers in SE Asia will be that they do not carry the aforementioned products. This would only be fair, seen how those three effectively interfered with me advertizing, getting retailed and sponsoring Go tournaments.
Revenge is sweet - patience is a virtue, who laughs last laughs best and that what not kills me, makes me stronger.
Tuesday, November 28, 2006
The diagram in his example was a little work of art: Many font sizes, alignments and even font colors. In spite of the season, I do not want to encourage "Christmas tree kifu's" but the user should be able to specify alignment, font attributes and color for various parts of the published material and included kifu's, so I cooked up this monster:
I discovered more bugs in the PDF output module I purchased the sources to: Italic doesn't work properly in RTF, the last character is cut off because the bounding box is too narrow. In PDF, italics don't work at all. Thank heaven I have the source at this advanced stage!
Monday, November 27, 2006
My solution is incremental (I can do delta-updates to the territory/influence map) and does not require multiple "passes". So it's very fast.
I have just added it to the update.exe and this is how it looks:
It's most useful at the Fuseki/Joseki stage, because life & death is not yet taken into account.
Tuesday, November 21, 2006
I notified them of the bugs and suggested they were trivial to fix and they mailed back within 24 hours with their acknowledgement! They would have a fix ready the next day or so, which means I'm now ordering their software for embedding into Moyo Go, as soon as as I have their confirmation that redistribution as an embedded app is OK.
Their solution also properly supports Excel and Powerpoint and even XML for maximum flexibility, so this would mean that Moyo Go will be able to make powerpoint presentations and Excel spreadsheets and produce Word documents that are compatible with OpenOffice. Thirteen major formats is a good start ;-)
So it will be DOC, EMF, EPS, HTML, PDF, PNG, PPT, PS, RTF, SVG, TIFF, XLS and XML. And not half-assed, shitty-rendered, nasty-looking, often-crashing either, but stable, fast, high-quality, exactly-what-you-would-expect output, tried and tested and every single output format looking identical to the other, including page margins, CJK fonts and images. This is another reason why it's taking so long. And - I want to bet you a free copy that AGA will not publish an independent review of this rather spectacular publishing module, or, if they do, they'll crush it into the ground :-)
And yes, the HTML publishing will FTP your games straight to your website!
Friday, November 17, 2006
..or was it this game:
GoBase does not have this game in its repository. It makes you wonder where those guys get the guts, telling me I am stealing "their" games, while in the end it is I who have, with the help of many others, collected and normalized a pro database that has more than 12,000 games than GoBase or GoGoD or SmartGo or MasterGo or anyone else except perhaps the Nihon Kiin, but they haven't romanized their collection and besides, their collection is zealously guarded.
So Gobase has zilch, zippo, and I have two versions of it. Makes you wonder how serious those game monopoly dudes are, it's a game from 1935 for crying out loud!
Could anyone shine a light on which game has been entered incorrectly so I can remove the erroneous duplicate? The second one looks suspicous to me..
(Thanks to Bob Felice for pointing this out)
I added pre-defined page sizes and a button to swap page width and -height. I also added a setting for the line spacing, and an alternate option for specifying font size: Characters/line in addition to lines/page. There also is now a progress line, showing which page or figure are being worked on.
Many small bugs in the GUI have been fixed and now it's slowly time to work on the diagram-generation. 90% of the GUI and 99% of the rendering engine is done (at least for "column-wide" diagrams, which are the simplest layout option in terms of rendering). What remains is implementing a plethora of diagramming options according to a functional spec I received from someone who puts serious demands on Go publishing.
My girlfriend comes to live with me permanently tomorrow and I haven't slept much, but I intend to finish the first version before December. It may look intimidating, but the publishing module will be incredibly simple to use. Basically nothing can go wrong and everything is so straightforward that reading the Help will not be neccessary, but there will be a comprehensive tutorial, just in case.
It is a great feeling that my users will get this as a free update. I really feel I'll be giving everyone a nice Christmas present, and repay the investment of the "early adopters" who had faith in me from the very beginning. Updates will always be free but the price might go up in early 2007 because having the best publishing module in existence makes the software more valuable. I am not there yet, but the biggest hurdles have been taken. This kind of stuff takes months to do right.
Thursday, November 16, 2006
Encapsulated Postscript: Hard Things Done Immediately, Miracles Take A Little Longer, But Easy Stuff Takes Forever
I threw in ordinary Postscript as a bonus and everything works very well. EPS support took half a day to accomplish. Not because of the complexity involved but because it took me several hours to figure out how to invoke a specific command line option from within Moyo Go. I do that all the time already, but this time it did not want to work. The solution was mundane but somehow I needed about a hundred trials-and errors to get it working.
Tuesday, November 14, 2006
A lot still has to be done, but the last bugs are out of the purchased report generator. I managed to generate correct output (more than 100 pages) without crashing for Kogo's Joseki Dictionary, but as I said - this is just the beginning.
I hope to have something to show on the first day of December.
Saturday, November 11, 2006
A good thing to know for aspiring programmers are a few coding style rules. I call them "the three fucks", and they are:
- What the fuck
- Why the fuck
- How the fuck
Almost no bad programmer practices the three fucks, and all good programmers practice them. (For those bad at logic: This does not imply that practicing those three rules by themselves make a good programmer!)
It should be perfectly clear, two decades after code has been written, well after the original coder has been hit by a truck, for a non-domain expert to understand what the code is doing. With all comments stripped from the source.
The only thing to achieve this is meaningful method- and variable names. "I have heard this all before" you say and "I do give my identifiers meaningful names". No you don't. I dare you, prove to me that you do. Prove it to yourself at least. Most likely, you can't. Long names are not the same as descriptive names. Especially not for someone who has to maintain your code.
Every time you give a function a name, you have to think of something that explains exactly, in detail, what that function will be doing. That is a talent most often associated with folks that write headlines for newspaper articles. This talent is so rare that most good journalists don't even possess it. It's left to the pro's. What makes you think you can do it? I am sure you can't if you haven't done several years of hard effort and especially refactoring.
When maintaining legacy code, I often come across names like: "PrepareDatesForBubbleDiagram". I am sure the Original Programmer thought he'd done a good job in providing a descriptive function name, but in fact this name isn't worth the bytes it occupies. It says nothing about what the function does. That the function "prepares" dates can be learned at a glance, but WHAT does it do to those dates? Complicated stuff, that's for sure.
In Delphi and other languages, "DateTimes" are floating point numbers, with the part behind the decimal point being a fraction of a day. You can imagine that juggling around with fractions, doing all kinds of arithmetical operation on those numbers easily results in something that can't be easily understood merely by looking at the code. 791023.47104 simply does not look like August 12, 2005, 13:45, and adding some of those numbers and then rounding the result to two decimals is NOT going to tell the casual observer what's going on.
"PrepareDatesForBubbleDiagram" could, with the same clarity have been called: "DoSomethingSecretWithTheDatesForBubbleDiagram". Most code is full of those "descriptive" names.. Of course the right way to name such a function would be "NormalizeDatesToExcludeWeekends" or "ModifyDatesToFiveMinuteResolution". But that takes a bit more thinking and we are not prepared to do it, hyped-up on caffeine as we are or preferring to browse for funny video's on the net. To provide more clarity as to what the function does, also name variables that are not used as simple counters properly. Meaning that from their name should be exactly clear what they do. If that means a variable name takes 20 characters, so be it. Camel-capping is your friend.
"Why" is almost as important as "what"
If I don't know why something is done, I might just as well rip it out completely, see what happens and rewrite the whole thing, making it ten times faster in half as many lines. That's what I usually do when something doesn't work and I have no clue why because the OP abandoned the project.
Let's take "NormalizeDatesToExcludeWeekends" as an example. DateTimes are removed when they fall in a weekend, that I can deduce from the source and the name. But WHY?
Is it because an associated component can't handle them, or because the customer does not want to see weekends, or because the data on weekends is unreliable, or because weekends are not working days and 30% of space can be saved?
When people are working on your old code, it's often because it is buggy, or it's too slow, or features need to be added to it. It would help if it were clear what the code is is supposed to do in the first place. This is why comments have been invented. Some say "It's easy to abuse/overuse comments" but that's just as abusing/overusing money. There is no such thing as "too much money", only money ill-spent and ill-invested. The same goes for comments. There is not such thing as "too many" comments, only unclear, superfluous or misplaced comments. Comments are much less used for the "what" part as for the "why" part. "what" is taken care of by the code itself, the identifier names. "why" is of secondary importance and due to the verbosity involved, comments are better suitable for conveying "why". "Why" should cover the following:
A) Why the code does what it does
B) Why it is coded the way it is coded (including improvement suggestions)
B is most often ignored, even in the rare event of observing A.
With B, it becomes much easier to make refactoring decisions and discover bugs that pertain to algorithm and architecture.
The deepest level of detail is the "how" of the code.
To be able to modify/bugfix code instead of replacing it completely, we need to know how it achieves a purpose, or, more accurately, how the author intended the code to work.
"How" is also covered by comments, and we again need to know two aspects:
A) How the algorithm is supposed to work (a description)
B) How the algorithm is implemented with sufficient detail for a non-domain expert to maintain its code.
An example of how the three fucks are covered in a piece of code:
This code is also an example of "coding hygiene". Assignments and declarations are logically grouped and column-aligned and logical groups of statements are separated by newlines.
Type declarations come in order of "complexity", pointers below their simple type.
Enforcing a 80-column width is counter-productive with today's hi-res screens. We don't live in the 80-column punch card era any more.
Using braces in expressions, even though operator precedence does not require it, makes clear what is intended, very important when bugs have to be fixed later on.
You can put statements on the same line to show they are related but remember that the debugger won't be able to step through the source line by line in that case.
The goal must always be writing the clearest code possible, not to save keystrokes. Most of your time should be spent designing a solution - on paper - anyway. Clean code saves time debugging but - most importantly - it saves a massive amount of time refactoring when it has become "legacy".
Wednesday, November 08, 2006
And I live here:
Last winter, I walked from my job back to my old rental bedsit downtown and I collapsed in Slottsparken and sat in a slump in the mud for 20 minutes. Sad, because I used to be very sportive and used to do a quarter marathon occasionally on Sunday mornings, do 3 km power-swims in the Gulf of Aquaba, lift weights, be a divemaster etc. I am a total wreck now. The nearest shop is 2.5 km. I try to get as much excercise as I can muster though. I had to sell my bicycles (I have done several trips of a few thousand clicks, every day 120 - 140 km, on hybrid bikes with luggage. One of the coolest ones was Czechia - Egypt - Sweden, which took several months). I have written an unpublished book about my travels. The manuscript is lost.
Turns out I did not have to worry about dinner - I sold 9 copies so far. This November is poised to be just as good as it was last year!
I am always so short on cash that I pay my rent much earlier than I should because I am always worried I won't have the money to pay it when it's due. Go programming certainly isn't a way to get rich (except perhaps when you licence a strong engine to Japan, something I hope to do, one day. I have unconventional ideas on how to use automatic learning to get a very strong positional evaluator.
Monday, November 06, 2006
There is no Go software that I know of that can generate small PDF's that can have any language combinations mixed into them, but before I can do that, I need to licence the Cyberbit font. So I just sent them an email. As I understand it, they want an "access fee" and royalties. It used to be a free download with the Netscape browser. A very esthetically pleasing font!
I read on GoDiscussions.com about a popular SGF printing application (I forgot the name), and someone said that making PDF's was so complicated that he gave up. Perhaps due to the complexity of generating small PDF's with mixed-language text.
Saturday, November 04, 2006
RTF, PNG, PDF, EMF, HTML and TIFF are the formats that made it into the final selection. Anything else is superfluous.
I could concentrate well today. I had to rewrite some rendering code in that report generator library I bought, again, to make everything look exactly the same and to get the same rendering features across all output formats.
I also made an elegant way to make sections bold. There still is very much to do, I hope to get it done by the end of this year.
Thursday, November 02, 2006
I hate point sizes as well. They say nothing about the actual font size when used in the context of outputting to a PNG image versus a printer. Sure, a point size is a "size", but bitmaps size differently, depending on the screen resolution so it's pointless
What we want is something like characters per page line, or lines per page height. And the publishing process calculates the appropriate font size, so that no matter where you output to, the result always has the same text in the same size, even though wildly different resolutions are used.
Wednesday, November 01, 2006
Recently I purchased the sourcecode to a library that lets me export to RTF, HTML, PDF etc.
If you want ot put CJK languages in a PDF, and the reader does not have a CJK unicode font, it does not display properly, therefore there is such a thing as "font subset embedding", because embedding the entire font would result in a filesize of more than 10 MB.
The library I bought supports that. Except with "composite glyphs". And unfortunately it's Korean that uses those. So I can't produce - for me - acceptable PDF output that contains Korean.
But I have the source, so poor naive me, I tried to implement it myself in that source (which I paid 349 USD for).
I spent the past three days struggling with it. I finally discovered that it will take me a week to do it, so I'll let it be for the moment.
The vendor bounces my emails as SPAM, and ShareIt! told me their emails to them also bounce..
I should have known better than to buy stuff from India. They have no support forum either. Then again, they were the only ones that had met my requirements.
It's not that Indians are inherently worse at software development. The issue here is that 25 years ago, most were unable to own personal computers. And owning a PC as a kid is usually prerequisite for becoming really, really good, just as with Go. You have to start young. 25 years ago, I had a computer. And with 16, I was late, very late. Extreme focus and dedication (and I had my own guru-level hacker to teach me about pointers and multi-dimensional arrays) the following decade got me through. My brother, I got him a computer when he was twelve. Before he was allowed to do his driving test, he employed two or three people in his turn-key IT company that produced their own POS solution. He wrote a barcode-reader driver from scratch before he had his first girlfriend.
Update: It's solved! The BitStream Cyberbit font properly embeds subsets, for my purposes. I have applied for a license.