I have not seen any sort of 'rules of thumb' for coming up with version numbers. So here is mine.
The Version (or Major Version) Number; This increments only when the User experience with the program will change in a new and major way or when the program design changes in a manner that the entire program has to be re-engineered from soup to nuts.
Simply extending the program's functionality, e.g. additional file types, would not make the cut. The extention would have to involve new capabilities for the user, not just additional capabilities much like ones that user had before.
For instance, adding a move hint capability would justify a change in version as this would involve multiple changes in multiple areas in the program to implement.
N.B. Zero in this position, by convention, is reserved for works in progress, alpha and beta programs.
The Mark (or Minor Version) Number; This increments when the user's experience is modified or when a major portion of the program needs changing, like when a class withing the program needs refactoring.
For instance, instead of just showing the best move, the program could indicate which moves are better than others. The only major changes are done in a very small set of classes, usually one, and minimal changes (if any) are needed elsewhere.
The Revision Number; Capabilities and user experience remains the same but how they are implemented changes. Usually the changes involve one, maybe two, functions.
The Build Number; Increments per build cycle. Setting this to zero would basically depend on the developer.
Sometimes Build number and Revision numbers are swapped.