A fabulous thing about Winboard

Discussion of anything and everything relating to chess playing software and machines.

Moderators: hgm, Rebel, chrisw

Dann Corbit
Posts: 12538
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

A fabulous thing about Winboard

Post by Dann Corbit »

It can read junk like this:

Code: Select all

[Event "?"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "?"]
[Black "?"]
[Result "1-0"]
[Setup "1"]
[Fen "r1b5/1pKp4/pP1P1p1p/P4p1B/3pn2p/1P1k4/1P6/5N1N w - - 0 1"]

1.Bh5-d1 h6-h5 2.Kc7-d8 Ra8-b8 3.Kd8-e7 Rb8-a8 4.Ke7-f8 Ra8-b8
5.Kf8-g7 Rb8-a8 6.Kg7-g8 Ra8-b8 7.Kg8-f8 Rb8-a8 8.Kf8-e7 Ra8-b8
9.Ke7-d8 Rb8-a8 10.Kd8-c7 f5-f4 11.Kc7-d8 Ra8-b8 12.Kd8-e7 Rb8-a8
13.Ke7-f8 Ra8-b8 14.Kf8-g7 Rb8-a8 15.Kg7-g8 Ra8-b8 16.Kg8-f8 Rb8-a8
17.Kf8-e7 Ra8-b8 18.Ke7-d8 Rb8-a8 19.Kd8-c7 f6-f5 20.Kc7-d8 Ra8-b8 
21.Kd8-e7 Rb8-a8 22.Ke7-f8 Ra8-b8 23.Kf8-g7 Rb8-a8 24.Kg7-h6 Ra8-b8
25.Kh6-g6 Rb8-a8 26.Kg6-g7 Ra8-b8 27.Kg7-f8 Rb8-a8 28.Kf8-e8 Ra8-b8
29.Ke8-d8 Rb8-a8 30.Kd8-c7 f4-f3 31.Kc7-d8 Ra8-b8 32.Kd8-e7 Rb8-a8
33.Ke7-f8 Ra8-b8 34.Kf8-g7 Rb8-a8 35.Kg7-h6 Ra8-b8 36.Kh6-g6 Rb8-a8
37.Kg6-g7 Ra8-b8 38.Kg7-f8 Rb8-a8 39.Kf8-e7 Ra8-b8 40.Ke7-d8 Rb8-a8 
41.Kd8-c7 f3-f2 42.Kc7-d8 Ra8-b8 43.Kd8-e7 Rb8-a8 44.Ke7-f8 Ra8-b8
45.Kf8-g7 Rb8-a8 46.Kg7-g6 Ra8-b8 47.Kg6-h6 Rb8-a8 48.Kh6-g7 Ra8-b8
49.Kg7-f8 Rb8-a8 50.Kf8-e7 Ra8-b8 51.Ke7-d8 Rb8-a8 52.Kd8-c7 f5-f4
53.Kc7-d8 Ra8-b8 54.Kd8-e7 Rb8-a8 55.Ke7-f8 Ra8-b8 56.Kf8-g7 Rb8-a8
57.Kg7-h6 Ra8-b8 58.Kh6-g6 Rb8-a8 59.Kg6-g7 Ra8-b8 60.Kg7-f8 Rb8-a8
61.Kf8-e7 Ra8-b8 62.Ke7-d8 Rb8-a8 63.Kd8-c7 f4-f3 64.Kc7-d8 Ra8-b8
65.Kd8-e7 Rb8-a8 66.Ke7-f8 Ra8-b8 67.Kf8-g7 Rb8-a8 68.Kg7-h6 Ra8-b8
69.Kh6-g6 Rb8-a8 70.Kg6-g7 Ra8-b8 71.Kg7-f8 Rb8-a8 72.Kf8-e7 Ra8-b8
73.Ke7-d8 Rb8-a8 74.Kd8-c7 h4-h3 75.Kc7-d8 Ra8-b8 76.Kd8-e7 Rb8-a8
77.Ke7-f8 Ra8-b8 78.Kf8-g7 Rb8-a8 79.Kg7-h6 Ra8-b8 80.Kh6-g6 Rb8-a8
81.Kg6-g7 Ra8-b8 82.Kg7-f8 Rb8-a8 83.Kf8-e7 Ra8-b8 84.Ke7-d8 Rb8-a8
85.Kd8-c7 h3-h2 86.Kc7-d8 Ra8-b8 87.Kd8-e7 Rb8-a8 88.Ke7-f8 Ra8-b8
89.Kf8-g7 Rb8-a8 90.Kg7-h6 Ra8-b8 91.Kh6-g6 Rb8-a8 92.Kg6-g7 Ra8-b8
93.Kg7-f8 Rb8-a8 94.Kf8-e7 Ra8-b8 95.Ke7-d8 Rb8-a8 96.Kd8-c7 h5-h4
97.Kc7-d8 Ra8-b8 98.Kd8-e7 Rb8-a8 99.Ke7-f8 Ra8-b8 100.Kf8-g7 Rb8-a8 
101.Kg7-h6 Ra8-b8 102.Kh6-g6 Rb8-a8 103.Kg6-g7 Ra8-b8 104.Kg7-f8
Rb8-a8 105.Kf8-e7 Ra8-b8 106.Ke7-d8 Rb8-a8 107.Kd8-c7 h4-h3 108.Kc7-d8
Ra8-b8 109.Kd8-e7 Rb8-a8 110.Ke7-f8 Ra8-b8 111.Kf8-g7 Rb8-a8 112.Kg7-h6
Ra8-b8 113.Kh6-g6 Rb8-a8 114.Kg6-g7 Ra8-b8 115.Kg7-f8 Rb8-a8 116.Kf8-e7 
Ra8-b8 117.Ke7-d8 Rb8-a8 118.Kd8-c7 Ra8-a7 119.Kc7-b8 Ra7-a8+ 120.Kb8xa8 
Ne4-d2 121.Nh1xf2# 1-0
And turn it into this:

Code: Select all

[Event "?"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "?"]
[Black "?"]
[Result "1-0"]
[FEN "r1b5/1pKp4/pP1P1p1p/P4p1B/3pn2p/1P1k4/1P6/5N1N w - - 0 1"]
[SetUp "1"]

1. Bd1 h5 2. Kd8 Rb8 3. Ke7 Ra8 4. Kf8 Rb8 5. Kg7 Ra8 6. Kg8 Rb8 7. Kf8 Ra8
8. Ke7 Rb8 9. Kd8 Ra8 10. Kc7 f4 11. Kd8 Rb8 12. Ke7 Ra8 13. Kf8 Rb8 14.
Kg7 Ra8 15. Kg8 Rb8 16. Kf8 Ra8 17. Ke7 Rb8 18. Kd8 Ra8 19. Kc7 f5 20. Kd8
Rb8 21. Ke7 Ra8 22. Kf8 Rb8 23. Kg7 Ra8 24. Kh6 Rb8 25. Kg6 Ra8 26. Kg7 Rb8
27. Kf8 Ra8 28. Ke8 Rb8 29. Kd8 Ra8 30. Kc7 f3 31. Kd8 Rb8 32. Ke7 Ra8 33.
Kf8 Rb8 34. Kg7 Ra8 35. Kh6 Rb8 36. Kg6 Ra8 37. Kg7 Rb8 38. Kf8 Ra8 39. Ke7
Rb8 40. Kd8 Ra8 41. Kc7 f2 42. Kd8 Rb8 43. Ke7 Ra8 44. Kf8 Rb8 45. Kg7 Ra8
46. Kg6 Rb8 47. Kh6 Ra8 48. Kg7 Rb8 49. Kf8 Ra8 50. Ke7 Rb8 51. Kd8 Ra8 52.
Kc7 f4 53. Kd8 Rb8 54. Ke7 Ra8 55. Kf8 Rb8 56. Kg7 Ra8 57. Kh6 Rb8 58. Kg6
Ra8 59. Kg7 Rb8 60. Kf8 Ra8 61. Ke7 Rb8 62. Kd8 Ra8 63. Kc7 f3 64. Kd8 Rb8
65. Ke7 Ra8 66. Kf8 Rb8 67. Kg7 Ra8 68. Kh6 Rb8 69. Kg6 Ra8 70. Kg7 Rb8 71.
Kf8 Ra8 72. Ke7 Rb8 73. Kd8 Ra8 74. Kc7 h3 75. Kd8 Rb8 76. Ke7 Ra8 77. Kf8
Rb8 78. Kg7 Ra8 79. Kh6 Rb8 80. Kg6 Ra8 81. Kg7 Rb8 82. Kf8 Ra8 83. Ke7 Rb8
84. Kd8 Ra8 85. Kc7 h2 86. Kd8 Rb8 87. Ke7 Ra8 88. Kf8 Rb8 89. Kg7 Ra8 90.
Kh6 Rb8 91. Kg6 Ra8 92. Kg7 Rb8 93. Kf8 Ra8 94. Ke7 Rb8 95. Kd8 Ra8 96. Kc7
h4 97. Kd8 Rb8 98. Ke7 Ra8 99. Kf8 Rb8 100. Kg7 Ra8 101. Kh6 Rb8 102. Kg6
Ra8 103. Kg7 Rb8 104. Kf8 Ra8 105. Ke7 Rb8 106. Kd8 Ra8 107. Kc7 h3 108.
Kd8 Rb8 109. Ke7 Ra8 110. Kf8 Rb8 111. Kg7 Ra8 112. Kh6 Rb8 113. Kg6 Ra8
114. Kg7 Rb8 115. Kf8 Ra8 116. Ke7 Rb8 117. Kd8 Ra8 118. Kc7 Ra7 119. Kb8
Ra8+ 120. Kxa8 Nd2 121. Nxf2#
1-0
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.
adams161
Posts: 626
Joined: Sun May 13, 2007 9:55 pm
Location: Bay Area, CA USA
Full name: Mike Adams

Re: A fabulous thing about Winboard

Post by adams161 »

Sometimes old code bases get out dated or hard to maintain. Winboard is lucky that from what i know of the authors, it's probably well written, and it's been maintained both past and present. The more time an author has over the years to update certain types of code, for example the PGN parsing, engine management, the more time to start handling more cases. And it can reach a point that almost anything you can throw at the code or program, it can run. Which is nice :)
Dann Corbit
Posts: 12538
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: A fabulous thing about Winboard

Post by Dann Corbit »

adams161 wrote: Fri May 10, 2019 7:27 am Sometimes old code bases get out dated or hard to maintain. Winboard is lucky that from what i know of the authors, it's probably well written, and it's been maintained both past and present. The more time an author has over the years to update certain types of code, for example the PGN parsing, engine management, the more time to start handling more cases. And it can reach a point that almost anything you can throw at the code or program, it can run. Which is nice :)
Tim Mann was the first guy, and he did a fabulous job with it, especially in making it work well in different environments.
Now hgm has picked up the baton, and he has done just as well as Tim did.

The sample I provided was just one instance of turning hamburger into sirloin.
Bad castles like 0-0-0 are handled with aplomb, along with other common boo-boos.
Instead of assuming that the engines/people will provide perfect data, they decided to fix the obvious goofs and not even pout about it.
That's beautiful software engineering.

Lots of programs would just crash on bad input. That's lazy.
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.
adams161
Posts: 626
Joined: Sun May 13, 2007 9:55 pm
Location: Bay Area, CA USA
Full name: Mike Adams

Re: A fabulous thing about Winboard

Post by adams161 »

Dann Corbit wrote: Fri May 10, 2019 8:49 pm Lots of programs would just crash on bad input. That's lazy.
Having written PGN parsing code the process i went through was something like i have 2-3 weeks to write the PGN code or some time and tried to test it on common file types i expect to be loaded. This included PGN from Chessbase, Internet chess clubs and some files of pgn i downloaded off the web like a fischer game collection. The code has gotten more robust as i've found more files i could not handle that people sent me or I found. I don't think its lazy to set a scope and do your best. Now ideally i like to see the code not crash on PGN it cant parse but have tried to write my code to simply fail safely and stop parsing if it gets confused. But some things have crashed it. Not nearly as common as just failing but it can happen as it gets complex.

I think with winboard it's the combination of having much more time and more users sending in files over time saying hey you can't read this and the winboard author, whoever it is at the time takes a look and says how can i expand the code to handle that. This also requires an author willing to put in time over the years vs an author who maybe is done with the app or a feature in the app mostly and reluctant to touch it if it's working for most of their customers.

Working in professional app development i know its common to start out with just get it working. Over time if the program is successful often work moves more to edge cases and hardening it and reducing crash rates etc.
Dann Corbit
Posts: 12538
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: A fabulous thing about Winboard

Post by Dann Corbit »

In C++ all you have to do is:

Code: Select all

try {
    something_that_might_crash();
 }
 catch (...)  { 
   // friendly, diagnostic error message goes here.  You can get a lot more clever if you know what the likely exceptions are.
 }
My friend Les Fernandez wrote a parser that takes chess contest games and turns them into fully decorated EPD records.
They have the score, the time, the depth, etc. collected from the PGN.
It's fabulous.
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.
adams161
Posts: 626
Joined: Sun May 13, 2007 9:55 pm
Location: Bay Area, CA USA
Full name: Mike Adams

Re: A fabulous thing about Winboard

Post by adams161 »

Dann Corbit wrote: Sat May 11, 2019 12:47 am In C++ all you have to do is:

Code: Select all

try {
    something_that_might_crash();
 }
 catch (...)  { 
   // friendly, diagnostic error message goes here.  You can get a lot more clever if you know what the likely exceptions are.
 }
There are two schools of thoughts on try catches and to be honest i've joined the latter school lately. In my java lantern i used a lot of try catches around code that might crash but long term it was harder to find the bugs. The other school of thought is write code so it doesn't crash and if it does, let it, and fix it. In my two most recent android apps i used just about no try catches unless i had to like the statement needed to be used with one. I do get crash reports and i fixed the crashes that came in early. Now i trust the code more. If it was in a try catch what might happen instead is bad user experience of some part of the programs state failing that i'd never know about unless they told me and it be doubly hard to figure out why vs line 1131 of gamestate.java failed.

Now some go even further in this direction. I had a friend tell me never null check anything as you wont find the bug as easily as a crash. I think null checks can be wise often. On the other hand if you don't intend to work on it till it stops crashing maybe its better to use try catch more and at least your app wont crash so often if thats the best you're going to give them.

Edit: also another thing is in java i can try catch most anything, in C++ i'm not sure all primitive crashes will be caught. It's not a managed language and unless you're dealing with objects like STL smart enough to throw exceptions i think certain things like divide by zero or something are just going to crash even in a try catch.

Mike
Dann Corbit
Posts: 12538
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: A fabulous thing about Winboard

Post by Dann Corbit »

You can never foresee every possible failure.
Tried to write to file? Disk got full or permissions were wrong or file was locked or...
Now, you might make a case branch for everything in errno.h, but things are added or subtracted when you move to a different operating system.
E.g. Linux has more signals than Windows.

On the other hand, it is better to handle problems directly instead of just using try/catch.
But try/catch is easy, that's all.
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.
adams161
Posts: 626
Joined: Sun May 13, 2007 9:55 pm
Location: Bay Area, CA USA
Full name: Mike Adams

Re: A fabulous thing about Winboard

Post by adams161 »

On the original point of "Who the hell can read that PGN", or what program can, I can tell you mine cant. I don't even know if it's in the PGN spec as i never read the PGN spec. My code which is now in 4 of my apps, OpeningTree on iOS and Android and Pulsar Chess on iOS and Android, was written for internal use originally to be used by the book builder program.

I'd be curious how the Winboard/Xboard PGN parsing code evolved. Did they start withe the spec and just spend time till it was pretty covered? Was it a bit more like me and they got PGN games working generally and then patched it over time as files were found it couldn't read.

In any event i'd say it had to happen over time. It's one of the advantages Winboard/Xboard and a few other major chess apps have that they are worked on over more than a few years.

My focus has been more mobile last 7 years or so and i've noticed many mobile chess apps don't have long development histories or sporadic histories. Still agreed don't write code that is not thought out how to avoid crashes or fail safe. Stop parsing when confused was what i did with my code. As it parses each move it returns true or false, if it cant parse the next move it returns false and stops on that game. Solid work by Winboard/Xboard it can read that none the less. Be interested if anyone knew more how it got there, attrition over time or more purists, started with the spec.
JohnWoe
Posts: 491
Joined: Sat Mar 02, 2013 11:31 pm

Re: A fabulous thing about Winboard

Post by JohnWoe »

Yes, I find winboard very clean and easy to work with.
I have watched Sapeli playing 1000s of games on xboard and analyzing them.

Sapeli sends moves in long notation but Xboard converts them to short notation.
Here b5a5 -> Rxa5.
Image
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: A fabulous thing about Winboard

Post by hgm »

adams161 wrote: Sat May 11, 2019 8:57 amI'd be curious how the Winboard/Xboard PGN parsing code evolved. Did they start withe the spec and just spend time till it was pretty covered? Was it a bit more like me and they got PGN games working generally and then patched it over time as files were found it couldn't read.
WinBoard/XBoard originally did not store games as PGN, but in some older GNUchess format. So the original parser was for that. Later code was added for recognizing PGN tags, and other PGN-specific elements (mostly for the purpose of ignoring them). I suppose support for the ignored things grew slowly, e.g. the ability to store comments with the moves, and edit those. Originally stuff in brackets and parentheses were then also treated as comment. I added code to implement variations and recognize the stuff in parentheses as such myself.

The parser has always been such that it simply ignores anything it doesn't understand silently. The original parser was machine-generated from a description syntax, and it could always fall back on the syntactical unit 'stray character', with empty semantics. I completely rewrote the parser at some point, because the formal syntax description could not handle variant-dependent stuff.

The aim has always been to recognize anything that remotely looks like a collection of moves as a chess game. This makes it for instance possible to copy-paste a table with moves from a HTML page into WinBoard. The HTML tags, and possible columns with other information, are simply ignored. The handling of non-PGN-compliant stuff sometimes leads to undesired behavior; e.g. when a HTML table that, next to columns with moves, als contained columns for time in hr:min:sec format, the number of min or sec was sometimes 00, which is also recognized as a non-compliant notation for K-side castling.So it slipped in extra castlings, which of course produced illegal moves. To make the parser resistant to that I had it recognize strings of 0 adjacent to : as garbage, rather than castling.

The current move parser doesn't only recognize coordinate notation and SAN, but also PSN-style moves (e.g. K5a-5b), or even traditional Japanese kifu notation for Shogi (where it recognizes the kanji both in UTF-8 and Shift-JIS encoding).