Thursday, January 9, 2014

A Chess Project, Part 1

Intro

For the next few weeks I want to shake things up a bit. Rather than blogging about a specific topic for a post or two, I will detail a project and we will create it from start to finish. Along the way we will discuss requirements gathering, technical design, and probably some json and web api along with other things.

Project Overview and Requirements

I like to play chess. I'm really not too good at it but I find it fun and the concept of creating a computer opponent fascinates me. I'm not looking for a fully-fledged chess-playing app here though, as that would take more blog space and time than we've got, so we'll limit the scope a bit. I would like for us to create a reusable Chunk of Awesomeness (CoA) that can be called from multiple languages and different types of interfaces (web GUI, windows, IOS, etc). This CoA should be fed a chessboard/game, and spit out what move it thinks should be made; ie the "best" move available. Sounds simple neh? Wrong!

Before we get into the technical design, let's start with the business side of things. What exactly does a CoA need to know (input) in order to calculate the "best move" (output)?


Inputs:

  • You need to know every single board position that has occurred this game. Why? 
    • A threefold repetition of the same position means that either player can claim a draw. Because the point of the game is to win, or if all else fails you try for a draw, knowing when a draw might occur is useful knowledge. We will not code "draw" logic into our "best move" calculations in this project however due to our desire for simplicity.
    • 50 moves in a row that involve no captures and no pawn movements results in a draw. We won't code this logic in there either, but hey we might in the future.
    • You need to know if either player has moved their king or each rook. Moving the king and the rook that would be used in a castling in any way forfeits the ability to castle with that pair of pieces, so it takes away one potential type of movement the king has. This is very important logic that we will code into this initial release of our project.
    • Note: we will only require a single board position as input. This is because we want our project to be able to handle chess puzzles too, and in puzzles you don't usually get the full game history but instead get just a specific position and are asked to find the best move(s). So, we require only a single board position, but we allow the user to send up the whole game's board positions. Due to sheer laziness, if the initial board position sent up is not the standard chess game starting position then we will assume castling is still possible if a king and rook are in the proper positions.
  • Whose turn is it? This value is required only if we were not sent the entire game's board positions. If we have those, we can pretty easily figure out whose turn it is based on who moved last.
Note that there is an alternative input to every board position that's occurred: You could have the project assume a standard starting position and just send in the chess notation for all moves that have been performed this game. Again, I don't like this option because it limits our ability to have the project evaluate chess puzzles.

Outputs:

  • Algebraic chess notation of the move that the CoA deems best. (see below for a link to algebraic chess notation; we'll use the short form)
  • It's possible the computer may wish to offer a draw or offer to resign; however, that's outside the scope of this project. A draw offer is covered by chess notation anyways so it doesn't really mean we would need further output field(s), and our computer foe will never surrender!

(bonus points for anyone that figures out why i pasted this image in here)

Technical Overview

First, the requirement to have this be a "reausable chunk of awesomenss" that can be called from multiple languages and different types of interfaces. To me this pretty much screams "web service". The evolution of web services in .Net over the past few years has gone something like this: Soap Web Service-->WCF-->Web API.

Soap web services have 2 main drawbacks: 1) They are a little bloated due to SOAP. SOAP is xml which is verbose compared to many other formats. I'm really not too worried about that for this project though as I don't think bandwidth will be that much of a concern. 2) SOAP web services have a rigid definition for calls into the service, so making modifications to the interface of your web service (the method signatures) requires that clients be updated/recompiled. I find this to be a large pain point with SOAP web services in .Net, so they're out.

Windows Communication Foundation (WCF) services were the next evolution of callable services on the web for the .Net platform. I've disliked them from day 1; the big drawback with these is they are a huge pain in the arse to configure correctly. They also have the same flexibility problem that regular web services do (and again, they are XML), so these are also out.

This takes us to Web API. These handy little services are built on a JSON foundation rather than XML. JavaScript Object Notation (JSON) is the new fad for data communication because of its portability (just about every platform out there today can create/parse JSON files), and it is less verbose than XML. Web API services don't really have any pain points in my opinion as they are easy to configure, and as long as you know what you are doing, updating a Web API service is much less likely to require clients to update their references/code.


The logic for determining the "best move" might get complex however, so we don't want this logic plopped directly into our web api service. This logic and any associated classes will be in a backend DLL. This gives us 2 advantages: 1) Unit testing the code will be both possible and much easier with the business logic being in a backend dll. 2) We can reuse this DLL later if we desire, for example in a GUI.



What Next?

I hope the above project description and technical overview got you interested in what's to come. For those of you that aren't familiar with chess, or just want a refresher, there is a link below in the resources section that gives some info. You can also pick up a book or two from pretty much any bookstore, or if you know me personally just ask and you can borrow one of the many chess books I have in my library.

You are also welcome to dip your toes into the world of JSON and web api, or you could review some of the older blogs on this site. You can even experiment with evaluating a chess position on your own via c# code if you're super-bored!

Resources

http://en.wikipedia.org/wiki/Rules_of_chess 
http://www.asp.net/web-api
http://en.wikipedia.org/wiki/Chess_notation

No comments:

Post a Comment