The Next Home of Chris Chapman's Free Thoughts on Agile, .NET, SharePoint, what-have-you, whatnot. 
# Friday, November 02, 2007

In my last entry, I outlined my ambitions for revisiting the code for my .NET 1.1 WinForms chess board control - specifically the rules engine.  This component is responsible for analyzing each move made on the chess board control against the known rules of the game for:

  • Legality - Is the piece being moved from/to legitimate squares on the board according to the type?  Is the move blocked?
  • Material Captures - Does the move result in material capture?  This includes special capture moves such as en passant, which incidentally has a known bug.
  • Check - Does the move result in either placing the player's or the opponent's king under direct attack?
  • Check-mate - Does the move result in placing the player's or the opponent's king under attack that cannot be evaded?

There are also some additional methods in the engine that should probably be extracted, since they do not directly relate to the class’ core responsibilities, ie. Standard Algebraic Notation and FEN notations for recording moves and bit-board initialization and manipulation routines.

By the way, don't worry if you're not a chess fanatic or chess programming whiz - I certainly wasn't when I tackled the project!  You should still be able to grok what’s going on – let me know if I’m glossing over material. 

Before we get much further, you might want to pull down a copy of the original source code so you can follow along.  Download it hereOpening the solution in Visual Studio, here’s where you’ll find the rules engine artifacts:

Rnchess_vs_solutionexp2

One thing to note here is the green orbs beside each element in the view – these are Subversion source control status flags that are provisioned via the Visual SVN plug-in for Visual Studio.  Since we’re going to be ripping into the code, it is an absolute must that we use some form of code versioning.  Subversion is free (as in beer), and is professional-grade, with features that I feel rival TFS.  It has a small footprint and can be set up easily on a local box, web server or network share.  In sum, it’s a great all-round tool for managing your code – I’ll do a posting on getting started with Subversion for .NET development in the near future for the curious. 

The class file that contains the rules code I’ll be refactoring is contained in ChessRulesEngine.cs, a rollicking roller coaster of code over 1400+ lines deep (excluding comments) with 121 methods, 164 fields and eight types!  Almost all of it necessary – I think.  Well, except for the 24 #regionswhich we all now know are completely evil (right, Bil?).

First thing we do:  Kill All The #regions

I know that I promised to get into my strategies for tackling the high cyclomatic complexity, but before we can get to any refactoring, we need a clean surface.  Looking at this old code, I cringe because it’s a little messy, and I want to make it more in-line with my current habits.

So I began by first removing all the #region statements so that I could see the code I was dealing with without having to mess around with little “+” swizzles and to reveal all the code in its naked glory.  However, I did want to retain some markers about what each block of methods represented, so I did some global S&R to change all “#regions” to “// GROUP:” and “#endregions” to “// — GROUP END —”  I then added GROUP as a task list macro (Tools—>Options—>Environment—>Task List) so that I could easily view and navigate to each section within the IDE:

Rnchess_group_code_highlight

Now, I could easily move around to each code grouping using descriptive markers.  At this point, I committed my changes to the repository to serve as my new baseline.  As an aside, when using any modern CVS, it is generally a good practice to provide a brief message about the changes you’re committing – getting into this habit will make your life a lot easier should you ever have to revert to a specific revision later on:

Rnchess_commit_changes_msg

Next:  In-depth code analysis

In my earlier post I mentioned two motivations that would provide an initial guide to establishing my refactoring plan:  Maintainability and Cyclomatic Complexity.  Each is complimentary in a yin/yang sense – by tackling methods and types with high CC scores, I would be making strides toward improving maintainability, and vice-versa.

Refactor! Pro provided me with a whack of methods with high CC scores.  In general, methods that have a CC of 15 or higher are strong candidates for refactoring.  CC metrics of 20–30+ should be aggressively refactored to split them up.

Now, while the Refactor! Pro metrics provide a good indication of some hotspots, I wanted to mine out some more information about my code to get a better sense of its overall health and to begin constructing a baseline “map” to evaluate my changes against.  I needed to bring in a heavier duty tool.

Enter: NDepend

NDepend is a static (ie. non-runtime) code/assembly analysis tool for measuring an application's design (recall:  all code is by nature, design) against a series of metrics that gauge type/assembly interdependencies, complexity, stability, couplings, abstraction and cohesion - among many others.  Basically, all the things that help define code that not only functions well, but maintains well. 

While initially a bit intimidating, NDepend can be your best friend once you get around the idiosyncrasies, and is invaluable in putting together a comprehensive picture of how an app is structured.  Initially released as a free tool, it is now quasi-commercial at a cost of $400 USD for a single license.  That said, you can use it for free (with some feature crippling) for non-commercial apps – works for me!

Running the analyses

There are some excellent tutorials on the NDepend site for getting started and how to use the tool, so I won’t go into a deep-dive in this post.  Basically, we want to use the VisualNDepend GUI to create a new project from our VS2005 solution (sorry, no 2003 support) and focus on analyzing just the RNVirtualChessboard and RNChessBoardCommonTypes assemblies – we can remove the RNChessBoard assembly as that contains the code for the control GUI:

Ndepend_app_assemblies

At this point, we can now launch the analysis and view the results in the VisualNDepend GUI (click to enlarge):

Ndepend_gui_cc

In the above capture I’ve reset the views in the GUI to focus just on code metrics.  The middle pane with the bubble-blocks is a high-level view of the methods in the assemblies that are organized in relative size to one another according to the current metric, which is set to show cyclomatic complexity.  The scores for CC are in turn provisioned via the CQL queries in the pane just below.

Right.  CQL – That’s pretty cool.  Wait, what?

CQL is an acronym for Content Query Language – in a nutshell, it allows you to run SQL-like queries against the metrics that NDepend has gathered so you can quickly view pertinent results according to adhoc criteria.  OOTB, VisualNDepend has over 60 of these queries that you can run and modify.  This feature alone makes NDepend a tool worth having, IMHO.

Note that we’re seeing only two methods, IsCastleLegit and DoPlayerMove, from the CC query as opposed to the 20–odd that Refactor! Pro was showing.  This is because by default, the CQL query NDepend uses shows the top-10 results for methods with a CC score of 20 or higher.  By editing the query to show methods with CC scores of >= 15, we get ten methods returned:

Ndepend_gui_cc_15

Ndepend_gui_cc_15_methods

As cool as this is, we can glean even more targets through NDepend’s additional code quality queries, but for now I’d like to pursue the top-three in this list starting with DoPlayerMove, as I suspect that from here I will touch a lot of other methods.  By right-clicking on the method in the results pane, I can access a context menu for drilling down into dependencies:

Ndepend_gui_dep_drilldown

From here, I want to know what methods are directly consumed by DoPlayerMove – this query reveals the following shortlist:

Ndepend_doplayermove_methodsusedby

Of these, the first two, UpdateMoveBitBoards and GetPieceTypeBitBoard have CC scores of 14 and 15.  Almost immediately we can start to see the broad brushstrokes for our refactoring plan and we’re more aware of the dependencies that we can run up against.

Strategies for Dealing with Cyclomatic Complexity

Because cyclomatic complexity is a measure of the branching and looping elements that exist within a method or type, it makes sense that the strategies we’ll want to employ for refactoring will be concerned with mitigating the effects.  Briefly, this means that we want to look at:

  • Branching requirements
  • Loop unrolling
  • Switch/Case optimizations
  • Segmenting code into smaller functions

Additionally, we want to be on the lookout for any low-hanging fruit that will improve the readibility of the code, such as introducing constants for any “magic numbers”, renaming methods where appropriate, collapsing redundant code, etc.

Refactoring-Ho!

For the remainder of the posts, we’ll be going through our target methods to begin sorting them out through the application of various refactorings.  As an aide, I’ll be using the Refactor! Pro add-in to make suggestions on the changes we can make to improve the design of the code.  While we should endeavour to recognize refactoring opportunities in our code without tools, they can provide us productivity gains and be instructive at the same time.  However, as with any power tool, we need to employ a little TFD (thought-first development) and try to do as Norm Abrams recommends and measure twice, cut once.

Note:  If you haven’t already a copy, I highly recommend getting Martin Fowler’s book, Refactoring: Improving the Design of Existing Code.  While it is an older text (1st edition in 2000) it is the seminal work that defines the reasons and strategies for revising code through the identification and cataloging of “code smells”.  Additionally, you may want to review Joshua Kerievsky's catalog of Refactoring to Patterns as well as Fowler’s online Refactorings Catalog which has current revisions and additions.

If we look at the DoPlayerMove code, we can readily see a number of “low-fruit” opportunities such as this block, which checks for the movement of either white rook as a pre-condition for determining the legality of a special defensive move called castling:

Rnchess_doplayermove_rooksquare

Refactor! Pro has picked up from my selection that I have the opportunity to employ several refactorings, including Replace with Constant – note that it even observed I already have a defined constant for the value that I can use!  Taking a step back, we can also see that there’s an opportunity to employ the Extract Method refactoring:

Rnchess_doplayermove_rooksquare_extract_method

However, now we’re starting to get ahead of ourselves:  We need to backstop our code with some unit tests so that we can be assured that the changes we’re planning on making don’t break the build or introduce new bugs.  For this, we’ll be using NUnit unit-testing framework v2.4.3 for .NET 2.0 and then adding a new project to our solution for containing our tests, which I’ll be covering in my next post!

In the next installment:  Setting up Unit Tests

Your homework for the next installment is to install and become familiar with NUnit and a complimentary add-in for Visual Studio, TestDriven.NET as I will be covering the fundamentals of each only briefly as they relate to managing and running our tests.  As always, if you have any questions feel free to post them below.

Friday, November 02, 2007 5:07:52 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
.net | better practices | refactoring | rnchessboardcontrol

# Wednesday, October 31, 2007

Four years ago I wrote a bit of code to satisfy an "itch" to see what it would take to create a chess engine in C# / .NET 1.1.  Several thousands of lines of code later, it was done and spent a little time up on MSFT's WinForms Code Hero site.  I didn't set out to have it there, mind you - it sort of came up as I was in that fabled "85%" complete zone, and that caused a huge push on my part to get it done within a week to make deadline.

Jump forward to present day:  I've opened up the "crypt" and peered inside my code for the first time in ages.  Cobwebs and other detritus is strewn about - wow.  I actually wrote code like this??

So begins my journey to review my chess control code.  I have a couple of reasons to use it as a guinea pig:  I know that it has some bugs (there's an infamous one that deals with en passant captures), no unit tests and despite the best of intentions isn't that cohesive internally.  It's also .NET 1.1, so I'd like to buff it up to leverage some 2.0 features and eventually 3.5 features. 

The bulk of the code resides in a single class, RNChessRulesEngine.ChessRulesEngine, which is augmented by five helper classes for managing other features (click to enlarge):

ChessRulesEngine is a real monster:  3000+ lines of code, 100+ methods, 40+ member variables and types, excluding arrays of types.  Not all of this is a cause for concern, however:  Validating chess piece moves is a non-trivial exercise that can get complicated fast when we're dealing with bit manipulations, masks, state checks and the like.  Nonetheless, I know that this engine can be improved, especially with respect to improving its maintainability.  Which makes it an excellent candidate for a case study on refactoring existing code.  So, let's move along into the kitchen and see what we'll be using to whip this beast into shape.

The Power Tools

Scrolling up and down through the code, it quickly becomes apparent that despite having written this app, I've long since lost the conceptual mental map for understanding the mechanics.  Further, I'm not even sure where to begin.  There's a few things I'd like to do off the bat, like improving some algebraic coordinate lookup algorithms with arrays, but that's really nibbling 'round the edges.  To be a Code Viking and do Odin's Bidding, I need some power tools:

Some of these you probably already have in your kit - these are the core tools that I'll be using to tackle my ancient codebase, and I'll be referring to them in my examples as we take a stroll down my digital memory lane.  I mention them all for the benefit of others who may not be as familiar and curious.

The Motivation:  Maintainability and Cyclomatic Complexity

I've mentioned above that I want to improve the chess rules engine to "modernize" it, and part of this necessitates refactoring the unwieldy portions of the code that are... how to put this delicately...  a bloody nightmare because they're so damn complicated.  I know the routines are complex, because I wrote them.  But how can I be sure which methods to tackle first?  How do I know if my intuitions have any basis in fact?

To answer this question, I'll be leveraging a concept known as cyclomatic complexity (CC), which is a metric that measures how many decisions are taken within a method.  Put another way, it is a count of the following expressions in a method or type:

  • if
  • while
  • foreach
  • case
  • default
  • continue
  • goto
  • &&
  • ||
  • catch
  • ternary operator (ie. {expression} ? {if true} : {if false} )

In general, the higher the CC metric, the more complex your code, the more of a nightmare it will be to maintain.

Of the tools I've listed above, three provide the ability to measure CC:  NDepend, Refactor! Pro and Reflector (with the separately downloaded Metrics plugin).  I decided to use Refactor! Pro's metrics feature from within Visual Studio to get a handle on what I was in for.  This is easy to get at from the menu:

Clicking Metrics brings up a modal dialog with a list of methods and their related CC, lines of code and maintainability measures.  I filtered on CC and well, now we see where we have to begin looking to make improvements (all supported by unit tests, of course...)

As I've alluded to above, some complexity can't be avoided in this app - but when we look at the DoPlayerMove, IsCastleLegit, and GetInterceptSquares methods with CC scores of 24, 19 and 19 respectively, this tells us where we can begin our investigation and employ some strategies to get those scores down.

Next Steps:  Strategies for Reducing Cyclomatic Complexity

In my next post, I'll be reviewing my next steps for tackling the CC of my top three methods, as well as reviewing some of my other tools that I'll be employing to hack down the problem and get an even greater understanding of what's happening within the rules engine;  for this, I'll be demoing a really fantastic tool, NDepend.  Stay tuned - oh, and Happy Halloween!

Wednesday, October 31, 2007 9:37:33 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [2] -
.net | better practices | refactoring | rnchessboardcontrol

# Tuesday, October 30, 2007

Via Larkware I just noticed this excellent web utility that takes the URL-shortening concept pioneered by TinyURL (among many others) and applies a little Web 2.0 secret sauce to convert your baboon ass-ugly addresses into something more in-step with modern web navigation semantics:

After making it "decent" we get:

As the author notes on his site, the advantage DecentURL provides over TinyURL is twofold:  It provides an URL that is disambiguous, human readable and easily communicated to others, and a clear indication of the website where the link redirects.  Unless you turn on the interstitial page for TinyURL, your users get automatically redirected to the target - this can be unnerving to some users.

Pretty cool service - in the "D'oh! Why didn't I think of it first?" category.

Tuesday, October 30, 2007 2:32:22 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
web20 | webtools

Via Bink.nu, news straight outta Redmond that the hitherto model for distributing WSS (ie. a separate, free download vs. OOTB bundle) is being revived.  The reason?

Starting with RC1 and going forward, Windows SharePoint Services 3.0 will have to be downloaded separately. Basically, we made this decision to allow customers to most conveniently obtain the technology while allowing Microsoft to have flexibility in the Windows SharePoint Services development process.

Oookaaaaaay.  I'm not sure how it's going to be more convenient for me to have to download the 70 MB+ install for WSS (excluding SPs, etc.) than have the core version installed by default or at least something that could be configured to install during setup - but that's just me.  Further, WSS was never integrated into the core for Windows Server 2003 - it always was a bolt-on that sat atop the .NET/ASP.NET framework - so, how is this impacting development again?

Maybe recent news on the Windows Server vs. Linux market share front is prompting this decision to encourage even greater penetration - but WSS seems like a no-brainer for the environments that Windows Server will be installed against, especially if you're giving it away and using it as a loss-leader to get MOSS 2007 in the back-door.

Tuesday, October 30, 2007 12:46:04 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
windows server 2008 | wss30

In the aftermath of moving my site from webhost4life to Alentus, my original article on my 4-year old .NET chess board control has become lost, in addition to the SharePoint page that I had set up to re-promote it.  So, this post is just a temporary beacon to let any and all interested parties know that I've relocated the source code and demo app to the new space.  You can download them from the following links:

While originally written under .NET 1.1, I've tested migrating the control code into .NET 2.0 without any compliation errors whatsoever, so this avenue is available if you want to work with the control straightaway.

In the interim, I'm currently doing some analysis of the code for a future series of articles on improving legacy apps using commonly available third party tools like NDepend, NUnit, Refactor! Pro, etc.  It's rather fascinating and instructive to get right into code I wrote some time ago and view it through the lens of better practices that I've developed since.

As a point of interest (which I've mentioned in posts over the years about the code), rnChessBoardControl employs a time-honoured technique of using long value types (UInt64) to represent the chess board, pieces and legal moves that's known as bitboarding.  Whereas other engines use arrays to do all move validating, bitboards alllow for lightning-fast operations using bitwise arithmetic and logic.  It's an application that has many more potential uses than just chess, and harkens back to a time when programming was more concerned with lower-level truth-table style logic than the higher-level abstractions we commonly use today.

Have fun and let me know if there's any issues with the files.

Tuesday, October 30, 2007 11:36:49 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
.net | announcement | rnchessboardcontrol

About Me
I am a Toronto-based software consultant specializing in SharePoint, .NET technologies and agile/iterative/lean software project management practices. Currently, I am employed by Microsoft Consulting Services (MCS) Canada as an Application Development and Information Worker Consultant, focusing on delivering guidance and subject matter expertise to enterprise customers who have or are in the process of deploying Microsoft technologies.

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Chris R. Chapman
Sign In
Archive
<November 2007>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678
Statistics
Total Posts: 194
This Year: 2
This Month: 0
This Week: 0
Comments: 109
All Content © 2010, Chris R. Chapman
DasBlog theme 'Business' created by Christoph De Baene (delarou)