[Tutor] Long post: Request comments on starting code and test code on chess rating project.

boB Stepp robertvstepp at gmail.com
Sun Aug 13 16:15:10 EDT 2017


Based upon the feedback thus far (Many thanks!) I think that perhaps I
should expand on my design thoughts as I have already stubbed my big
toe at the very start!

On Sun, Aug 13, 2017 at 12:22 AM, boB Stepp <robertvstepp at gmail.com> wrote:

> The intent of this project is more than just calculate chess ratings.

CALCULATION OF RATINGS

My calculation of a new chess rating is a simpler process than what is
used for FIDE Elo ratings or USCF Elo ratings for over-the-board play.
Instead, I am adapting the USCF (United States Chess Federation)
correspondence chess rating formula for use with my students.  These
students usually come to me often not even knowing the moves and rules
of the game.  They have no previous tournament chess experience and in
general are quite weak players even if they sometimes believe
otherwise. ~(:>))  A link to the USCF's explanation of this rating
system is:  http://www.uschess.org/content/view/7520/393/

It is not very well-written in my opinion.  But anyway ... The basic formula is:

new_rating = old_rating + K_MULTIPLIER * (opponent_rating -
old_rating) + K_ADDER * (your_result - opponent_result)

If you win your_result = 1; lose = 0; draw = 0.5.  Note that the
opponent's result would be, respectively, 0, 1 and 0.5, corresponding
to these values of your_result.

I am not using the article's section on unrated players.  This is of
little use to me as I usually start off without anyone who has ever
had a chess rating.  So there is no existing rating pool to
meaningfully compare my unrated players against.  So I start out each
unrated player with a rating of 1000.  For most of my students who
already know and play chess, this turns out to be a slightly generous
estimate of their rating if I were to compare them to the USCF
over-the-board rating population.

Another change from the article I am making is that if there is more
than a 350 rating point difference between players, then the game is
rated as if it is a 350 point difference.  I have changed this to 400
points as I feel that the higher rated player should _not_ gain any
rating points for beating the lower rated player.  In practice I am
the only person 400+ points greater than anyone.  To date I have a
100% win rate against my students, so I would rather they not obsess
about losing rating points against their peers if I have to fill in
for a game due to an odd number of players showing up.

There are several conditionals that have to be applied to calculate
the rating even in this simplified system.  K_MULTIPLIER and K_ADDER
are dependent on whether the player's old_rating falls into one of
these rating ranges:  1)  0 - 2099; 2) 2100 - 2399; 3) >= 2400.
Additionally, if the initial new_rating calculation causes new_rating
to fall into a different K-factor rating range, then the new rating
must be proportionately adjusted for the number of points that fall
into the new K-factor rating range, using a ratio of the new and old
K-factors.

So based on what Steve said, the rating calculation makes more sense
to be done with functions.  One of the things I wish to do with the
completed program, is to enter all of my old game data spanning ~ 5
years, and have the program re-rate everything from scratch.  So I do
not see how it would be helpful to create a new RatingCalculator
instance for each game.

PERSISTENT STORAGE OF GAME DATA AND PLAYER DATA

I've decided not to use an actual database as I will never have so
much data that it cannot be fully loaded into RAM for even quite
modest PCs.  The approach I am thinking of taking is using a
dictionary of dictionaries to store the game data and player data.
Something like:

players = {0: {'last name': 'Smith', 'first name': 'John', ... },
           1: {'last name': 'Doe', 'first name': 'Doe', ... },
           ... ,
           n: {...}}

and similarly for games.  I would use the csv library's dictread and
dictwrite methods to load into memory and on program exit write back
to disk these two dictionaries, which are meant to mimic two database
tables.

REPORT GENERATION

There are a variety of reports that I would like to be able to print
to screen or paper.  Things such as a "Top x List" of rated players,
full rating list sorted from highest rating to lowest, rating lists
for the current school year only or a particular past school year, and
so.  I could see wanting to sort such lists by various criteria
depending on the type of report I would like to generate.  Currently
this section of the program is a big gray area for me, but I see no
reason why my two dictionaries cannot be manipulated to pull the
desired results for each imagined type of report.

USER INTERFACE

Until all of the above is worked out, I will use a CLI, perhaps even
play around with the curses library, which I have been meaning to do.
Once I get an overall result that I am happy with, I will develop a
GUI in tkinter.  My intent is to go as Alan suggests and keep the UI
well-decoupled from the rest of the program, no matter if it is CLI or
GUI.

PLANNING ALL OF THIS OUT -- HOW MUCH DETAIL?

I generally start as above by dividing things up into broad areas of
functionality and then picking the seeming easiest to start work on,
which is why I began with the RatingCalculator (Which will shortly
become the calculate_ratings module instead of a class.).  It seemed
to be a rather straightforward translation of a formula with various
conditions into code, returning the newly calculated ratings (One per
player in a game.).  All ratings must be positive integers; floats
must be rounded to nearest positive integer. It is theoretically
conceivable that someone could eventulally acquire a rating of zero,
but in practice that should be impossible and if that result turns up
I would be suspicious of bugs in the program.  Likewise I am planning
to use 3000 as an upper limit.  Current super-strong chess programs
can exceed this lofty height, and the very best humans in the world
might get in spitting distance of this limit, but grade school
students that have minimal experience with chess?  I am using these
bounds as sanity checks for the program for unforeseen issues.  Note
that in the starting code I posted, I had yet to reach the steps where
I would make use of these two bounds.

So how detailed should I plan out each broad section of the program
before writing any code?  Alan seems to be suggesting getting a firm
handle on initially imagined objects and their methods before any code
writing.

I hope this describes better what I am striving to accomplish.

Thanks!

boB


More information about the Tutor mailing list