Showing posts with label Web API. Show all posts
Showing posts with label Web API. Show all posts

Friday, June 19, 2015

.Net Web API Help Files

Intro

Help me Rhonda, help help me Rhonda...
Sorry about that, my parents used to listen to the Beach Boys all the time in the car and that tune is pretty catchy. So I was sitting here thinking about ways to help people, and I thought of Web API help files. When you make a Web API that you want to publish for people, creating documentation can get a bit tedious. Wouldn't it be great if there was an automatic way of generating help files? Yeah you know it baby, there is such a thing! And of course, it's a NuGet package that's nice and easy to plug into your existing Web API projects in .Net. Let's see what this sucker does for us!


Note: The sample project is in Visual Studio 2013, .Net 4.5.

Usage

So the NuGet package name is Microsoft ASP.NET Web API 2.2 Help Page. Bit of a mouthful there huh?

To start off our efforts, I've created a blank Web API project in Visual Studio. I created a single controller named SampleController, with a get method that returns "hi". Here's the code for it in case you want to play along:

using System.Web.Http;

namespace BlogWebApiHelp.Controllers
{
    public class SampleController : ApiController
    {
        public IHttpActionResult Get()
        {
            return Ok("hi");
        }
    }
}


If you run the project in your browser and look at http://[baseurl]/api/sample, you'll get back a json file (or xml depending on your browser) with the word "hi".

OK time to install the Help package to see what it does for us. Open up the package manager console via Tools-->NuGet Package Manager-->Package Manager Console. Type this text into the Package Manager Console and hit Enter: Install-Package Microsoft.AspNet.WebApi.HelpPage. The package is now installed and you'll notice your solution has a new folder named Areas. There's quite a bit of content in here that's all Mvc-style, and yes you can customize it all you like. It's what generates the help pages for your API that you're about to see.

There's one more small code change you have to make in order for this stuff to work. Open up your Global.asax.cs file and put this one line in your Application_Start method:

AreaRegistration.RegisterAllAreas();


Note that you will have to add using clause for System.Web.Mvc if you don't have one already.

Let's see this little sucker in action! Fire up the Web API and navigate to http://[baseurl]/help. You should see a badass little page like this one on yer screen:

That's sweet! It found the Sample controller and is showing us that it has a Get method which we can execute by calling api/Sample. Huh, this thing doesn't have a description though? Lame! Stupid package should document my methods for me. Well it isn't quite that cool, but it's pretty close. Close the browser and head back to Visual Studio. Put an XML comment on the Get method of SampleController. There's a small code change you have to make too. Open up the file Areas\HelpPage\App_Start\HelpPageConfig.cs. In here you need to uncomment this line:

config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));

As you can see, this line tells the Help package that it should look for a file within your web app named XmlDocument.xml within the app_data folder. We haven't created any such file so let's tell our project to autogenerate that xml file for us. Right-click on your project and open up the Properties window. Check the checkbox next to "XML documentation file:", and for the name type "bin\XmlDocument.xml". Save.


Run this thing again and open up the help url. Aww yeah baby, our XML documentation is now our Web API Help file documentation! It doesn't get much better than this folks. You can put documentation on methods and classes, it will pick up parameter documentation, and you can style these pages as you like. Awesome!



What's Next?

Try creating your own Web Api with help files, or download the source code from the link above and play with mine. Open up the two links below in the Resources section and see what other features this thing has. Tip: you can hide methods and controllers from the API documentation!

Resources

Microsoft ASP.NET Web API 2.2 Help Page
Creating Help Pages for ASP.Net Web API

Thursday, April 16, 2015

Web API Global Exception Handling Made Easy

Intro

Exception handling can be a bit of a chore. It always ends up looking the same; the familiar try...catch pattern, maybe you log the exception, maybe you rethrow it, yadda yadda. In a Web API you might even throw back a server error 500 response when you encounter an exception.

I know you're all sitting there chanting impatiently, willing me to tell you I can make it better...easier even! You're probably sitting at your desk or staring at your phone, thinking "Peeticus, please save us from the doldrums of routine! Help us!!". Well OK, just this once.Only because I can see the tears of joy brimming in your eyes.

Example

So I've made a simple Web API. It has a single GET method that throws an exception. Here's the code:

using System;
using System.Web.Http;

namespace BlogWebApiExceptionHandling.Controllers
{
    public class HandlingController : ApiController
    {
        public IHttpActionResult Get()
        {
            throw new ApplicationException("hey, an error!");
        }
    }
}

Run this thing and send a request to it with Fiddler. Here's what you get:
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNccGVldGljdXNcZG9jdW1lbnRzXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xCbG9nV2ViQXBpRXhjZXB0aW9uSGFuZGxpbmdcQmxvZ1dlYkFwaUV4Y2VwdGlvbkhhbmRsaW5nXGFwaVxoYW5kbGluZ1w=?=
X-Powered-By: ASP.NET
Date: Fri, 17 Apr 2015 01:20:24 GMT
Content-Length: 2176

{"Message":"An error has occurred.","ExceptionMessage":"hey, an error!"...}

Server error 500 with a message. That's not too bad I guess, though the exception is unhandled. What if we want to log it, or send a notification email to somebody? you can put a try...catch around it sure. What if you have 5 methods? 50? all that try...catch becomes a pain in the arse. So, let's do this the easy way.

Now I add a new class to my Web API. This new class will be named GlobalExceptionLogger, but you can name yours whatever you want. Because this is only a demonstration of exception handling, I won't do anything complicated in here. I'm just setting a local variable to the Message property of the exception. Here it be:

using System.Web.Http.ExceptionHandling;

namespace BlogWebApiExceptionHandling
{
    public class GlobalExceptionLogger : ExceptionLogger
    {
        public override void Log(ExceptionLoggerContext context)
        {
            var stuff = context.Exception.Message;
        }
    }
}

There's one more line of code necessary to make this work. This new line of code goes in your WebApiConfig.cs file, within the Register method:

config.Services.Add(typeof(IExceptionLogger), new GlobalExceptionLogger());

If you now set a breakpoint back in the Log method of GlobalExceptionLogger and fire up the Web API using Fiddler, you'll see that the Log method is called for the unhandled exception. Hey, now it's globally handled! Any further Web API controllers and methods will use this thing, which is exceptionally cool. Like me! :)

Resources

What's New in ASP.Net Web API 2.1

Thursday, April 2, 2015

Web Api Request Validation Made Easy

Intro

Validating inputs into your system can be quite a chore. Field X might be a required field, Field Y might need to be email format, Field Z might need to be a number between 1-100. Coding such requirements isn't very difficult, just tedious. Wouldn't it be great if there was something that would lessen the monotony? Yeah, you know where I'm headed...there is such a beast, and we can bask in its magnificence!

Note: I'll be using Visual Studio 2013 Community Edition and Fiddler to do my work.


Sample

For starters, create a new Web Api application. I've created such a solution and named it BlogWebApiValidation. Add a new controller to it named ValidationController.


 Now add a new class to your Models folder named ValidationSampleRequest. It'll have just three properties, so it'll be pretty simple. Here it is:

using System.ComponentModel.DataAnnotations;

namespace BlogWebApiValidation.Models
{
    public class ValidationSampleRequest
    {
        [Required]
        public string RequiredString { get; set; }

        [EmailAddress]
        public string SomeEmail { get; set; }

        [Range(1, 100)]
        public byte SomeNum1To100 { get; set; }
    }
}

Now go back to your ValidationController class. It doesn't need to do much, it just needs a single method named Post that accepts an object of type ValidationSampleRequest. Here's what yours might look like:

using System.Web.Http;
using BlogWebApiValidation.Models;

namespace BlogWebApiValidation.Controllers
{
    public class ValidationController : ApiController
    {
        public IHttpActionResult Post(ValidationSampleRequest request)
        {
            if (ModelState.IsValid)
                return Ok();
            else
                return BadRequest(ModelState);
        }
    }
}


This Post method is pretty bare-bones, as we're just demonstrating model validation. All it does is check the validity of the ModelState (the request), and returns a 200 OK HTTP result if good, and a 400 Bad Request HTTP result if bad. Simple! Go ahead and run the project. You'll get a 403 Forbidden error in your browser but that's OK. Our testing involves something a little more complex than just firing up a browser window. But hey, leave the browser window open :)

Fire up Fiddler and let's play with this sucker. I'll skip some of the explanations and just show you real quick how to use Fiddler to test your Web APIs. There's a lot more to it than what I'll cover, I just want to demonstrate the API for now. Anyways, launch Fiddler. You can install it from the link below if you don't already have it.

First, click on the "File" menu, and click on the "Capture Traffic" menu item. This will tell Fiddler not to capture everything you're doing on the internet. That's too much noise for us to sift through.

Now click on the Composer tab. This brings you to a window where you can create your own requests. Select "POST" as the verb, and type in the URL of your web api controller. You can see mine below, though yours (especially the port) may be slightly different. In the headers field right below the URL you can just copy what I have. In the Request Body field, you can also copy what I have below.

Headers:
User-Agent: Fiddler
Accept: application/json
Content-Type: application/json

Request Body:
{
"RequiredString": null,
"SomeEmail": "not an email",
"SomeNum1To100": 101
}


Now hit the big Execute button. You'll see you now have a single request shown in the left-hand side of the window, and it should have a 400 result. Double-click this response record, then on the right-hand side of the window click on the "Raw" button. If you look down there in the response section it now shows you the raw HTTP response.

2 key points here:
  1. You received 400 Bad Request response. Poifect!
  2. The body of the response contains a JSON object which has details on what precisely went wrong. What good is model validation if the client doesn't know what they did wrong? If you keep scrolling to the right you can see that all 3 fields failed validation.


What's Next?

Validation has a lot more options like regular expressions, you can use nullable types like bool? to make a normally non-nullable field required, it will validate sub-objects in complex requests, credit cards, comparison of 2 properties, you can even create your own custom class validation methods, custom error messages, and much much more.

Fiddler also has a lot more options than what I breezed on through. Play around with it, it's great for testing Web API's.

Resources

Fiddler 
DataAnnotations (more validation options)

Thursday, March 19, 2015

.Net OData Services

Intro

I've talked about Web API in previous articles, and I think my overall opinion is pretty clear: I really like the direction MS has taken with internet-based services. I find Web API to be a big improvement over SOAP services and WCF. They're simpler and more flexible, and I find them to be just plain fun. However there is a more powerful alternative out there that is still quite simple: OData. OData is an "open protocol to allow the creation and consumption of queryable and interoperable RESTful APIs in a simple and standard way." For .Net, OData is supported in Web APIs with just a few minor tweaks to your code. So in essence you get queryable RESTful APIs with very little effort on your part. OK everybody, time to show me your OData face and let's get crackin!




Howdie Doodie

Time to talk specifics. Pretend you have a list of animals. You want a RESTful service that allows the client to query your list of animals by name. OK cool, sounds easy enough. You might create a Web API that has a GET method with a single parameter, name. The user hits your api, maybe with the url /api/animals/timmy, and this would return Timmy the lion (we'll just assume all your animals have unique names). Now what if the client wants to retrieve a list of mammals? You could always create a new GET method in your API that has a single parameter for class and the client would hit /api/animals/mammal, but now you've got 2 conflicting API methods and they each need their own special path. Plus you're making some duplicated code here, as in essence you're still just querying your list of animals for specific animal(s). OData gives you an easier out. Let's create an OData service that allows querying as per the previous desires.

First, fire up Visual Studio. I'm using VS 2013 here. Create a new empty Web API project.


Now add a class to your Models folder. Name the class Animal.

Make your class look like this:

using System.ComponentModel.DataAnnotations;
namespace BlogOData.Models
{
    public class Animal
    {
        [Key]
        public string Name { get; set; }
        public string Type { get; set; }
        public string Class { get; set; }
        public int Height { get; set; }
        public int Weight { get; set; }
    }
}

Note: The Key attribute is merely used to identify which is the unique property of our class that identifies individual instances of an animal. In the real world names aren't unique, but this is a blog not the real world.

Now it's time for our OData controller. Go ahead and add one named Animals to your Controllers directory as per the following screenshots:



You've now got a rather large file named AnimalsController.cs in your Controllers folder. It has a lot of extra actions that we don't need since all we care about is retrieving an animal or list of animals based on criteria specified by the client. Replace the code of your new controller with the following:

using System.Collections.Generic;
using System.Linq;
using System.Web.Http.OData;
using BlogOData.Models;

namespace BlogOData.Controllers
{
    public class AnimalsController : ODataController
    {
        public List<Animal> Animals;

        public AnimalsController()
        {
            Animals = new List<Animal>();
            Animals.Add(new Animal() { Class = "mammal", Type = "lion", Name = "timmy", Height = 64, Weight = 495 });
            Animals.Add(new Animal() { Class = "reptile", Type = "box turtle", Name = "billy", Height = 4, Weight = 2 });
            Animals.Add(new Animal() { Class = "reptile", Type = "leopard gecko", Name = "marzipan", Height = 1, Weight = 1 });
            Animals.Add(new Animal() { Class = "invertebrate", Type = "worm", Name = "willy", Height = 1, Weight = 1 });
            Animals.Add(new Animal() { Class = "mammal", Type = "house cat", Name = "sushi", Height = 1, Weight = 12 });
        }

        [EnableQuery]
        public IQueryable<Animal> Get()
        {
            return Animals.AsQueryable();
        }
    }
}

The first thing that is noteworthy is your class declaration for AnimalsController. We're descending from ODataController. Next in line, our constructor. It's not really all that special, but you can see we're populating a list of animals. Lastly the method Get. This has a few interesting bits:
  1. The EnableQuery attribute. This tells the runtime that we are returning a result from this method that is queryable using OData. 
  2. The return type is IQueryable<Animal>. This lets the result set be queried automatically via the OData backend.
  3. Lastly, we return our list of Animals as a queryable object. 
With this incredibly small amount of code, we've now created an OData controller that lets clients tell the server to return only specific results.

And now is where I tell you there's one more piece left. As things stand at the moment, there is no route to your OData controller, which means clients can't actually call it. Open up your WebApiConfig.cs file in the App_Start folder. Looking at the below code sample, you'll need to add the 3 lines of code underneath the comment "//OData Routes":

using System.Web.Http;
using System.Web.Http.OData.Builder;
using System.Web.Http.OData.Extensions;
using BlogOData.Models;

namespace BlogOData
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //OData Routes
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Animal>("animals");
            config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());

        }
    }
}


These 3 lines tell the runtime that we wish people to access our OData controller via the url /odata/animals (case-sensitive). That's it. Run this little sucker! When your browser first comes up, you'll probably see a 403 forbidden error like the following:


Not to worry though; that's not really the url you want. If you're debugging in IE, go ahead and open up a firefox window. It's easier to demo Web API and OData functionality with than IE. Leave the IE debugging window open though. Navigate to your localhost url plus "/odata/animals". You should now see this:


Cool! This is the JSON response from our OData controller showing the full list of animals. I hope you're now thinking "Geez Peeticus, that's cool! But hey, didn't you say the client could tell the server, via a query of some sort, which animals to return?". Well yes I did, and yes we can. OData has it's own special syntax that we can use for filtering, delivered via the $filter querystring parameter. Let's go ahead and use a basic query now...add this on to the url you already have in FireFox: "?$filter=Name eq 'timmy'" (note these filters are also case-sensitive, as are string values contained therein). Here's what your result looks like:

Try a few more queries. Maybe we want to see all the mammals with "?$filter=Class eq 'mammal'".

Holy poo this is cool! We didn't have to write a bunch of switch statements with dynamic querying, LINQ statements, or anything of the sort. All this filtering is handled automagically!


What's Next?

You have a lot more query options with OData than what I've shown you here today. Play around, see what all else you can do, and check out the OData website for more information. It's powerful stuff. You might also try creating a C# client to consume your OData service. Info on how to do that can be found here.

Resources

OData Home
Create an OData v4 Endpoint Using ASP.Net Web API 2.2

Thursday, March 12, 2015

.Net Web API Compression

Intro

Web API projects are great. But hopefully I've already convinced you of that in past blogs :)  What could make them better? Optimization of course! As you can guess by the title, I'm specifically going to talk about compression. Compression has a dual-purpose: it can optimize bandwidth, and as a result on many devices it optimizes speed as well from the user's point of view. Out of the box, your Web API's don't accept compressed requests and won't send back compressed responses. Lazy API! But we've got an easy way to make this happen, so read on fellow optimizers!


Example

First, let's create a Web API project in C#. We'll go without web optimization for now just so you can see the difference. Fire up Visual Studio and create a new project. Make it a c# web project.



Make it a empty project and give it Web API and Web Forms capabilities:

 Now give your site a new web API controller. Name it TestController. 






Your Web API doesn't need much in it, just set your code to this:

using System.Net.Http;
using System.Web.Http;

namespace BlogWebApiCompress.Controllers
{
    public class TestController : ApiController
    {
        public HttpResponseMessage Get(string id)
        {
            var result = new List();
            for (int i = 0; i < 10; i++)
                result.Add(id);
            return Request.CreateResponse(result);
        }
    }
}


If you run your web api by hitting your base url plus "/api/test/hi", the web api will return back the list of strings string containing "hi" (10 times) to you. Not much to that. Now let's pretend you sent up a 100 page pamphlet worth of text. You'd have not only a large request, you'd have a very large response as well. Compression can lessen the burden on your systems.

How do we get compression? It turns out there's already a NuGet package for that. NuGet kind of reminds me when iPhones were still pretty new and people kept saying "there's an app for that". Well with Visual Studio and NuGet, "there's a package for that". The one we want is named Microsoft.AspNet.WebApi.MessageHandlers.Compression. Good luck memorizing that. I'll assume you have some familiarity with NuGet by now, but if not drop me a line in the comments below. Fire up the package manager and install the above package.

Now open up the file App_Start/WebApiConfig.cs. At the end of your Register() method, copy in this line of code:

GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor()));

You may also have to add "using"s for these:

using Microsoft.AspNet.WebApi.MessageHandlers.Compression;
using Microsoft.AspNet.WebApi.MessageHandlers.Compression.Compressors;


Believe it or not, that's all you have to do on the server! Let's do another test of our Web Api using FireFox to see the compression in action. This time I'll put a much longer string into the request:



Notice how FireFox sent up the request header "Accept-Encoding: gzip, deflate" and the server sent back down gzip-encoded content? Sweet! That's all there is to it.



What's Next?

  • Go to the website of the NuGet package and see how to:
    • Only compress requests and responses that are above a certain size threshold, and
    • Write client-side code that tells the server you can accept a compressed response (hint, most browsers do this for you already if you are using JavaScript, but for C# clients you have a small amount of extra coding to do).


Resources

 Microsoft.AspNet.WebApi.MessageHandlers.Compression

Thursday, December 11, 2014

Data.Gov: Public Government Data API's


Intro

Believe it or not, there are actually a few free things out there. Freedom may cost you $1.05, but there are tons of freely available public APIs. Some are corporate APIs for retrieving information on weather, traffic and other useful things. You can probably find plenty such APIs with a small amount of Google-fu. Some free public APIs are made available by our government. You can retrieve data on economics, oceanography, demographics,utility rates, and more.


The API I Want to Use

We have to start somewhere, and I've picked an API that gives information on alternative fuel stations. Go ahead and dig around on this site for a minute then come back. This API includes information on fueling stations that use alternative fuels such as hydrogen, natural gas, ethanol and more. I don't have such a vehicle, but hey it's an interesting topic and I want to play with this API. Feel free to start somewhere else with your own code if you like.

The method I'm most interested in right now is the one that lists all locations which match specified query parameters. I could picture this information being useful for a person who wants to find the alternative fuel stations near their home or work so they can plan their daily commute.

This method has a large number of request parameters that you can supply on the querystring. It also allows you to specify whether you wish to receive the results as xml or json. Either way, the request is a simple HTTP GET with a specific URL and chosen querystring parameters, and you parse out the response with code. For example, let's say I want to retrieve a list of the first 5 alternative fuel stations in zip code 75006 that have E85 ethanol gasoline or electric refueling. For this API I would use the url: http://developer.nrel.gov/api/alt-fuel-stations/v1.json?api_key=DEMO_KEY&fuel_type=E85,ELEC&zip=75006&limit=5. The first part, "http://developer.nrel.gov/api/alt-fuel-stations/v1", is the base url of the service. the next part, ".json" tells the service that I want my results in JSON format. other possible values are ".xml" and ".csv" for this API. Next up, "api_key=DEMO_KEY". This is how we authenticate with the API. In our case we're just going to use their demo key rather than creating an API key on the website. Now we get to the first filter of our querystring, "fuel_type=E85,ELEC". This tells the API that we want to return a list of stations that are E85 Ethanol or electric refuel/recharge capable. Next up is the zip code, and the last querystring chunk, "limit=5", tells the API we want only the first 5 results. Paste this sucker into your browser and see what you GET (ha, internet pun!). You should see something like this, except mine's formatted nicer:

{
   "station_locator_url":"http://www.afdc.energy.gov/afdc/locator/stations/",
   "total_results":2,
   "station_counts":{
      "total":8,
      "fuels":{
         "E85":{
            "total":0
         },
         "ELEC":{
            "total":8,
            "stations":{
               "total":2
            }
         },
         "HY":{
            "total":0
         },
         "LNG":{
            "total":0
         },
         "BD":{
            "total":0
         },
         "CNG":{
            "total":0
         },
         "LPG":{
            "total":0
         }
      }
   },
   "fuel_stations":[
      {
         "access_days_time":"MON: 24 hours | TUE: 24 hours | WED: 24 hours | THU: 24 hours | FRI: 24 hours | SAT: 24 hours | SUN: 24 hours",
         "cards_accepted":null,
         "date_last_confirmed":"2014-12-11",
         "expected_date":null,
         "fuel_type_code":"ELEC",
         "id":45129,
         "groups_with_access_code":"Private",
         "open_date":null,
         "owner_type_code":null,
         "status_code":"E",
         "station_name":"Carrier Enterprise HQ",
         "station_phone":"888-998-2546",
         "updated_at":"2014-12-11T08:09:02Z",
         "geocode_status":"GPS",
         "latitude":32.933474,
         "longitude":-96.92574,
         "city":"Carrollton",
         "intersection_directions":null,
         "plus4":null,
         "state":"TX",
         "street_address":"2000 Luna Rd",
         "zip":"75006",
         "bd_blends":null,
         "e85_blender_pump":null,
         "ev_connector_types":[
            "J1772"
         ],
         "ev_dc_fast_num":null,
         "ev_level1_evse_num":null,
         "ev_level2_evse_num":4,
         "ev_network":"Blink Network",
         "ev_network_web":"http://www.blinknetwork.com/",
         "ev_other_evse":null,
         "hy_status_link":null,
         "lpg_primary":null,
         "ng_fill_type_code":null,
         "ng_psi":null,
         "ng_vehicle_class":null,
         "ev_network_ids":{
            "station":[
               "51671"
            ],
            "posts":[
               "20199",
               "19577",
               "11721",
               "9055"
            ]
         }
      },
      {
         "access_days_time":null,
         "cards_accepted":null,
         "date_last_confirmed":"2014-04-04",
         "expected_date":null,
         "fuel_type_code":"ELEC",
         "id":46370,
         "groups_with_access_code":"Private",
         "open_date":"2011-08-13",
         "owner_type_code":"P",
         "status_code":"E",
         "station_name":"General Electric - Dallas Office",
         "station_phone":null,
         "updated_at":"2014-04-04T19:00:52Z",
         "geocode_status":"GPS",
         "latitude":32.9838,
         "longitude":-96.845317,
         "city":"Carrollton",
         "intersection_directions":null,
         "plus4":null,
         "state":"TX",
         "street_address":"2508 Highlander Way",
         "zip":"75006",
         "bd_blends":null,
         "e85_blender_pump":null,
         "ev_connector_types":[
            "J1772"
         ],
         "ev_dc_fast_num":null,
         "ev_level1_evse_num":null,
         "ev_level2_evse_num":4,
         "ev_network":null,
         "ev_network_web":null,
         "ev_other_evse":null,
         "hy_status_link":null,
         "lpg_primary":null,
         "ng_fill_type_code":null,
         "ng_psi":null,
         "ng_vehicle_class":null
      }
   ]
}


I'll just summarize the results rather than detailing all of it: we found 2 stations that match our criteria, both of which are electric recharging stations. We also got their address, which is kinda nifty and we'll use that in a few minutes.


Code it Like It's Hot

This wouldn't be a very good coder's blog if I didn't code something, so let's call the API. Create yourself a new web project in Visual Studio. I chose an empty WebForms project, and it will be easier for you to follow along if you do the same. Now add a default page to your site, named "Default". Drop a button on there and give it the same properties as the button you see in my code below:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="BlogPublicApi.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Public API Test</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="btnExecuteApi" runat="server" Text="Execute API" OnClick="btnExecuteApi_Click" />
    </div>
    </form>
</body>
</html>



Now go to the code behind of your page. The first thing you'll want to do is install the Microsoft Web API Client Libraries. It's a NuGet package. You can find it by searching for "Microsoft.AspNet.WebApi.Client" within the NuGet package manager. After you've added that to your solution/site, copy the code from my button click event into your own:

using System;
using System.Net.Http;


namespace BlogPublicApi
{
    public partial class Default : System.Web.UI.Page
    {
        protected void btnExecuteApi_Click(object sender, EventArgs e)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://developer.nrel.gov/");
                var response = client.GetAsync("api/alt-fuel-stations/v1.json?api_key=DEMO_KEY&fuel_type=E85,ELEC&zip=75006&limit=5").Result;
                if (response.IsSuccessStatusCode)
                {
                    dynamic stationResponseData = response.Content.ReadAsAsync<Object>().Result;
                    Response.Write("Total Results: " + stationResponseData.total_results + "<br />");
                    foreach (dynamic station in stationResponseData.fuel_stations)
                    {
                        Response.Write(String.Format("<a target='_blank' href='https://www.google.com/maps/place/{0},+{1},+{2}+{3}'>{4}</a>", 
                            station.street_address, station.city, station.state, station.zip, station.station_name));
                        Response.Write("<br />");
                    }
                    Response.Write("Raw Result Object: <div>" + stationResponseData + "</div>");
                }
            }

        }
    }
}


The magic starts with the using statement within btnExecuteApi_Click. This is where we create our http client object. The next line of code we set the base address, and then after that we get our response. Assuming the request was successful, we then pull out the json from the response as a dynamic object so that we can access its properties. We write out the total # of results, then loop through the individual fuel stations to create a link. Then for a little extra fun, we link to the station on Google maps. Try plugging in your own zip code and give the code a whirl! It's pretty neat to see the results on a map.

Here's a screenshot of the results so you can visualize what we've done:



What's Next?

There are lots of other free, public APIs out there. Look around, and see what you can make with all the free data. Maybe you'll end up with a great idea for an app for your phone.


References

APIs | Data.gov
Alternative Fuel Stations API
All Stations API | Alternative Fuel Stations
JSON Formatter & Validator 
Calling a Web API From a .Net Client

Thursday, May 8, 2014

A Chess Project, Part 13 (The Final Chapter)

Intro

I can see the light at the end of the tunnel! It's an alternating black and white checkered light, but still, a light nonetheless. How many of you thought it would take 13 blog posts to get here? Well I sure didn't, but I'm glad we're almost done. Here in week 13 we'll be modifying our Web API that we created months ago. We'll make it call into our spiffy chess AI dll in order to determine the best move from a given board position. After all, that's what we were trying to do from the very start!

 

 Code Changes

First, here is the absolute latest code as it stands right now, before today's modifications. It's not the most optimized, and I dare say the AI isn't really all that great, but hey the point of this blog was learning new technologies not to make the perfect chess AI.

Let's get to work. Open up BlogChessController from the BlogChessApi project. That method named PostBestMove is the one we want to do our modifications in. Here's what it looks like currently:

        public HttpResponseMessage PostBestMove(ChessGame game)
        {
            try
            {
                //validate the game
                var validator = new ChessGameValidator(game);
                if (!validator.Validate())
                    return Request.CreateResponse(HttpStatusCode.BadRequest, validator.ValidationIssues);

                //calculate the best move
                IChessValidMoveCalculator moveCalculator = new ChessValidMoveCalculator(game);
                var validMoves = moveCalculator.CalculateValidMoves();

                //return the best move wrapped in an http "ok" result
                return Request.CreateResponse(HttpStatusCode.OK, validMoves);
            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
            }
        }


You'll notice we don't yet have a call into the AI dll. At the time we originally made this method we had no such AI dll, so I can forgive us. Before we can do the code though, we need to reference BlogChess.AI.Basic1 from the Web API project. Go ahead and do that now (I'm assuming you've seen that enough that no screenshots are necessary). Add a using statement up at the top of the unit while you're at it.

All we really need to do is add in a call to our Negamax evaluation, then add in a little bit of logic to look for win/draw conditions. All of this is just calling methods we've already written. Your newly modified should look like the following:

        public HttpResponseMessage PostBestMove(ChessGame game)
        {
            try
            {
                //validate the game
                var validator = new ChessGameValidator(game);
                if (!validator.Validate())
                    return Request.CreateResponse(HttpStatusCode.BadRequest, validator.ValidationIssues);

                //calculate the best move
                var bestMove = Negamax.Evaluate(game, 2, game.GameStatus == GameStatus.WhitesTurn);
                var responseGame = bestMove.Item2;
                responseGame.CurrentEvaluation = bestMove.Item1;

                //is a win or draw, set game move accordingly
                IChessValidMoveCalculator moveCalculator = new ChessValidMoveCalculator(game);
                var availableMoves = moveCalculator.CalculateValidMoves();
                if (availableMoves.Count == 0)
                {
                    var isKingInCheck = moveCalculator.IsKingInCheck(game.GameStatus == GameStatus.WhitesTurn, ((IList<ChessBoard>)game.Positions)[0]);
                    //look for checkmate
                    if (availableMoves.Count == 0 && isKingInCheck)
                        responseGame.GameStatus = game.GameStatus == GameStatus.WhitesTurn ? GameStatus.WhiteWin : GameStatus.BlackWin;
                    //look for draw
                    else if (availableMoves.Count == 0 && !isKingInCheck)
                        responseGame.GameStatus = GameStatus.Draw;
                }
                else //just the next turn now
                {
                    responseGame.GameStatus = game.GameStatus == GameStatus.BlacksTurn ? GameStatus.WhitesTurn : GameStatus.BlacksTurn;
                }

                //return the best move wrapped in an http "ok" result
                return Request.CreateResponse(HttpStatusCode.OK, responseGame);
            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
            }
        }



As advertised, just a couple minor additions to call our evaluator and check for end of game.


Testing It

Remember way back when, that web forms project BlogChessApiFlexer? It's right there in the solution, and it's just itching to call the modified web api method. We had already coded a call into the web api (in default.aspx.cs), but prior to now we were just passing in a dummy request and expecting a dummy response. Well now it's time for an appropriate request and response!

        public ChessGame Game
        {
            get
            {
                return Session["Game"] as ChessGame;
            }
            set
            {
                Session["Game"] = value;
            }
        }

        protected void btnServerTest_Click(object sender, EventArgs e)
        {
            //1. Create and setup client object
            using (var client = new HttpClient() { BaseAddress = new Uri("http://localhost:11482/"), Timeout = TimeSpan.FromSeconds(300) })
            {
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                //2. Create a blank chess game to send up in the post request
                if (Game == null)
                {
                    Game = new ChessGame() { GameStatus = GameStatus.WhitesTurn };
                    var positions = new List<ChessBoard>();
                    var sampleBoard = new ChessBoard(true);
                    sampleBoard.Board = new short[8, 8] { { -4, -2, -3, -5, -6, -3, -2, -4 }, { -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1, 1, 1, 1 }, { 4, 2, 3, 5, 6, 3, 2, 4 } };
                    positions.Add(sampleBoard);
                    Game.Positions = positions;
                }
                int numPositions = ((IList<ChessBoard>)Game.Positions).Count;

                //3. Send the request
                var response = client.PostAsJsonAsync("api/BlogChess/BestMove", Game).Result;
                if (response.IsSuccessStatusCode)
                {
                    //4. Read the result from the response, display the "best move"
                    var result = response.Content.ReadAsStringAsync().Result;
                    var resultObject = JsonConvert.DeserializeObject<ChessGame>(result);
                    Game.GameStatus = resultObject.GameStatus;
                    ((IList<ChessBoard>)Game.Positions).Clear();
                    for (int positionIndex = 0; positionIndex < numPositions + 1; positionIndex++)
                    {
                        if (((IList<ChessBoard>)resultObject.Positions).Count > positionIndex)
                            ((IList<ChessBoard>)Game.Positions).Add(((IList<ChessBoard>)resultObject.Positions)[positionIndex]);
                    }
                    lblResult.Text = "Success! :" + result;
                }
                else //5. Request failed; tell the user what happened
                    lblResult.Text = "Failzor'd!: " + response.StatusCode.ToString() + "::" + response.ReasonPhrase;
            }
        }



Let's start with the easiest part, the propert Game of type ChessGame. If you've done webforms before, this shouldn't require much of an explanation. This is just a handy, type-safe way for me to be able to reference the current game object from the session so I can persist information about a single game in memory. Moving on to the button click event...

And here's the meat. Some of this was already here. As I said above, we were already calling the web api. What's new is we're now creating and serializing a chess game object (the one from our session), and we're passing this game object to the web api. Then we're taking the result of this call and updating the Game property. This means that, if you keep clicking that button, the AI will play itself! How cool is that? Well it's moderately cool, as it's incredibly slow. But hey, baby steps.

Wrapping it Up

Thanks for sticking with this series of articles everybody. As can happen with coding endeavors, it got away from me a bit. I thought this might be a 4 or 5 article series, not 13. I hope you learned a few new things, and maybe even gained a little bit of interest in chess in the process of reading these.

Oh and here's the absolutely final code, all fanciful and whatnot.

What's Next?

There are a few things you could do really. You could load AI dlls dynamically, configurable via database entry or config file. This would make it easier for other people to create AI dlls that plug into your web api, and you could have clients configured to choose a specific AI. You could also optimize the existing AI dll further (or just make your own) to make it much much quicker (hint: bitboard!). Or just go have a beer, or martini, or diet dr pepper. Whatever.


Resources

online chess board editor at Apronus.com
Chess.com, a great site for everything chess related 

Thursday, April 17, 2014

A Chess Project, Part 12

Intro

This week we get into some really interesting stuff, namely our algorithm for picking which move is the "best" out of a list of evaluated resulting positions. Last week we planted the seed; we created a few classes to evaluate a position numerically, letting us decide what a specific position is worth to us. Now we decide what's the best position.

First, here's our updated project code.

 

Basics of our Algorithm

You might think that this week should be easy. We already did the hard part last week right? I mean, how hard is it to create a tree of moves and pick the one that gives us the best outcome? Well that doesn't quite work. If all you do is evaluate a tree of potential board positions multiple levels deep to find the leaf node with the highest value, you're going to be disappointed. Such a path requires your opponent to make the worst possible sequence of moves in order for you to arrive at your best possible outcome, which is unlikely to happen. So what do we do instead? The logic behind the algorithm is this:
  • Determine the level of depth you will look ahead of time. For example, if you know you can evaluate 5 moves ahead with relative ease, just pick the #5 outta yer butt.
  • Find every single combination of moves for a depth of 5. 
  • For each leaf node, evaluate the position. 
  • White will be trying to maximize the score on his moves, black will be trying to minimize the score on his turns (remember, a negative positional evaluation equates to an advantage for black). 
Check out this link for a great graphical representation of how the algorithm will work. The algorithm in question is called minimax, and has been used for game AI for some time.

And hey, we can improve on it! Don't worry, I'm not smart enough to improve on it myself. This improved version of minimax is called negamax, and it too has been around for a while. It's basically the same as minimax, except it lets you write the same algorithm as above by just negating values rather than using one algorithm for minimization and one for maximization.

Go ahead and take a look at the pseudocode for negamax. One thing you'll notice quickly if you spend a minute reading it, is that it uses recursion. Through recursion we can avoid using a tree structure to hold all the valid moves in memory. It's tough to visualize I admit, it took me hours to really understand how all this worked. If you have the time to spend, google around and read a few more articles about minimax and negamax. Then come back to the graphical representation from above. If you understand how the algorithms work then you'll get a better feel for how you can improve on them yourself should you so desire.

The Code

And now it's time for our code. Within the BlogChess.AI.Basic1 dll, create a new class called Negamax. Here's the code for it:

using System;
using System.Collections.Generic;
using System.Linq;
using BlogChess.Backend;
using System.Diagnostics;

namespace BlogChess.AI.Basic1
{
    public class Negamax
    {
        public static int NumEvaluations = 0;
        public static Stopwatch MoveCalculationTimer = new Stopwatch();
        public static Stopwatch BoardEvaluationTimer = new Stopwatch();

        public static Tuple<double, ChessGame> Evaluate(ChessGame game, int depth, bool isWhite)
        {
            if (game == null || game.Positions == null || game.Positions.Count() == 0)
                return new Tuple<double, ChessGame>(0, game);
            var moveCalculator = new ChessValidMoveCalculator(game);
            MoveCalculationTimer.Start();
            var availableMoves = moveCalculator.CalculateValidMoves();
            MoveCalculationTimer.Stop();
            var colorSign = isWhite ? Constants.WhiteTransform : Constants.BlackTransform;
            if (depth == 0 || availableMoves.Count == 0)
            {
                NumEvaluations++;
                IPositionEvaluator evaluator = new PositionEvaluator(game, availableMoves, moveCalculator);
                BoardEvaluationTimer.Start();
                var evaluation = evaluator.Evaluate();
                BoardEvaluationTimer.Stop();
                return new Tuple<double, ChessGame>(colorSign * evaluation, game);
            }
            var bestValue = new Tuple<double, ChessGame>(-AIConstants.PieceValues[Constants.King], game);
            foreach (var move in availableMoves)
            {
                ChessGame newGame = new ChessGame();
                var positions = new ChessBoard[((IList<ChessBoard>)game.Positions).Count + 1];
                ((IList<ChessBoard>)game.Positions).CopyTo(positions, 0);
                newGame.GameStatus = game.GameStatus == GameStatus.WhitesTurn ? GameStatus.BlacksTurn : GameStatus.WhitesTurn;
                positions[positions.Length - 1] = move;
                newGame.Positions = positions.ToList();
                var val = Evaluate(newGame, depth - 1, !isWhite);
                if (-val.Item1 > bestValue.Item1)
                    bestValue = new Tuple<double, ChessGame>(-val.Item1, val.Item2);
            }
            return bestValue;
        }
    }
}



First let me explain the Stopwatch and NumEvaluations members. Once I had this thing working at a depth of 1 I tried depth 2 and 3. At depth 3 it got incredibly slow; this currently takes 37s to calculate a fairly simple depth 3 board position with an obvious expected outcome (fork the opposing king and queen with a knight). I dropped in these extra member variables in an effort to optimize the code, and I came to the conclusion that I'd have to completely redo the valid move calculation code in order to get a significant improvement. However, we won't be doing that for the blog, so let's move on to the Evaluate method. (disclaimer: it was actually a 60s process to evaluate a depth of 3 on the first try; I made one small improvement to get it down to 37s, though for the sake of conciseness I won't get into what that improvement was).

Our Evaluate method looks very similar to the pseudocode of Negamax from wikipedia. That's because I started with it and modified it to fit our purposes. The main difference between our implementation and that pseudocode, in my opinion, is that I return a Tuple<double, ChessGame> whereas negamax usually returns just the numeric evaluation value. I decided that this would be a bit more intuitive at the potential sacrifice of a small amount of efficiency. Other than that, we recurse the tree to the expected depth, just like every other negamax implementation. Note that only leaf nodes actually have their position evaluated, as denoted by the line "if (depth == 0 || availableMoves.Count == 0)". This is because we don't care about the board evaluation of branch nodes, as they derive their value from their children.

What's Next

I strongly suggest you review all the updated code, especially the new unit tests I created (but did not discuss in the blog post) in our new class BlogChess.AI.Basic1.Test.NegamaxTests. I've created tests in here that make sure we call the Negamax.Evaluate method  properly and validate its parameters, as well as making sure the algorithm can produce the proper expected move for some canned test positions at a depth of 0-3. And guess what, it actually works!! If you are a true fanatic and are excited at the prospect of testing it out further, I encourage you to make your own unit tests, feeding the algorithm some positions where you know the expected outcome. Or hey, feed it some where you don't know the expected outcome and see what it comes up with! If you really want to go nuts, see what you can do to improve the valid move calculator. I didn't write it with efficiency in mind, and it's the biggest drain on CPU and clock time right now.

As for the next blog post...we should have only 1 remaining blog post for this project, yay! We haven't yet modified our Web API from way back when, and we need to make it call our lovely AI dll in order to calculate the "best" move and return it to the client. Once we get that, we've fulfilled the original project goal and can move on with life. See ya next week!


Resources

Wikipedia - Minimax
Wikipedia - Negamax

Thursday, March 27, 2014

A Chess Project, Part 10

Intro

We got a good start on our unit testing in the Chess Project Part 9 posting last week. We unit tested every possible move for white pieces, created a spiffy new html format for chess boards to ease our unit testing, and we tested many of our helper methods in other classes as well. This time around we will finish up unit testing the current suite of functionality. We have to add unit tests for some of the valid black piece moves (I only deem it worth our time to create tests for moves unique to black; his pawns and king castling moves, make sure black pieces can't put their own king in check) and we have just a few helper methods within ChessValidMoveCalculator to test out. Then we're green to move on to the super-fun part (next week), starting to figure out what the "best" move is for a given chess board!

The Code

Like last week, I think it best to start off by giving you this link to the code. There are too many new unit tests forming too much code to paste it in the blog, so at your leisure please download it from the link, open it up, build it, and take a look at the new unit tests. Then come on back so we can discuss them.

Unit Tests

We'll start with pawn moves. Obviously black's pawns move down the board while white's pawns move up the board, so their move calculations are different. This is why I decided to unit test black pawns separately from white pawns. You can see by looking at the unit test file that I mirrored all the white unit tests with black as far as pawns are concerned, so we should have full coverage.

I'm going to skip unit testing of black Knight, Bishop, Rook, and Queen moves. Why? These pieces move exactly the same whether they are white or black. The only difference is that white pieces can't put the white king in check, and black pieces can't put the black king in check, but I don't have to duplicate all my tests to check 1 situation per color. I did however recreate the majority of the king's unit tests as castling is different (white castles on row 7, black on row 0), so you can see in our unit test code that most but not all of the king testing is duplicated from white to black. I also renamed some of the unit tests to better denote color and direction.

We also added 8 more unit tests (4 each) for ColorThreatensSquare and IsKingInCheck, testing the positive and negative and black/white of each method.

You may have also noticed I had to fix more code. This just reaffirms my love of unit tests. See if you can find the code I had to fix. Here's a hint: it had to do with checking if a move would put the same-color king in check.

What's Next?

That's it for this week folks! We have 1 solution, 4 projects, dozens of classes, 80 unit tests, 1 web API, etc etc. Next week we'll FINALLY get to the whole point of this project, calculating the "best" move. I haven't a clue how long that will take us to do, it could be 1 post or 5, we'll just have to wait and see. 

Thursday, March 20, 2014

A Chess Project, Part 9

Intro

As promised last week in Part 8, this week is all about the unit tests. We've got a pretty sizable chunk of code going in this project and so far we have no way to test any of it. I don't plan on creating a GUI for this solution (at least not in this series of blog posts), so unit testing is the way to go. Please view my unit testing series of blog posts (UT1, UT2, UT3, UT4) for a quick refresher on unit testing if necessary.

The Code

I think it will be easier to understand what's going on if I give you a link to the code at the top of the article this time, so here you go. Once you have it pulled down, extracted and compiled come on back for the remainder of the article.

Unit Tests

As you can see in the screenshot below, I created a new unit test project in the solution named BlogChess.Backend.Test.
This is where all our unit tests for the project are going. As of the time I am writing this, there are 57 unit tests in the solution. That is a bit too many for us to walk through in the blog, so at your leisure please dig through the code and see what's going on. The unit tests at this point cover the vast majority of our functionality from the backend dll. We are testing the validation code, board size, and all the valid moves for white. The only things left to test are the black piece move validation methods, and we'll do that in the next blog post.

As a result of all this unit testing, I found 2 other things necessary. First, I had to fix some bugs. I know what you're thinking: "But Pete, you don't make mistakes!". Well I appreciate the kind words (you were thinking them, admit it!), but yes I actually do make mistakes. I bet I fixed a half-dozen of them thanks to the unit tests. I won't detail all of them (mostly because I don't remember what they were at this point), but suffice it to say they would have made this project rather useless if they had been left to fester. The second thing I found necessary while creating unit tests was to have a way to visualize a chess board so that I could set up specific positions in the unit tests, and validate piece movement. Cue dramatic new bold sub-heading...

New Format, New Formatter/Parser (use of html agility pack)

...So, I created a new chess format. Sure arrays are great for representing a chess board, but which is easier to work with when creating a unit test? This...

{ {-4, -2, -3, -5, -6, -3, -2, -4}, {-1, -1, -1, -1, -1, -1, -1, -1}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 1, 1, 1}, {4, 2, 3, 5, 6, 3, 2, 4} }


or this?

So, I invented a new chess format (it sounds a lot more impressive than it really is) and created a class to import the new format. Believe it or not, the above screenshot is pure html/css. There are no images in that. Well the screenshot itself is an image obviously, but it's showing just html/css.

How did we accomplish this? If you're moderately familiar with html/css, it's easier than you might think. It turns out that unicode defines special characters for each of the chess pieces, so as long as the font you are using supports these values, then you can use plain-old-text to represent the pieces. After that it's just a simple matter of putting a board around the pieces you want, and voila! You can look at some of the many samples I put in the solution, using the screenshot below as a guide to finding the files. The essence of the export format though is much simpler than these files allude to. All you need is elements on the page that have a data-col attribute of "a" through "h", and those same elements should have a data-row attribute of "1" through "8". These of course represent the 64 squares of the chess board. For ease of formatting I've elected to use a table (you could use div's, span's, or whatever other html element you feel like using), a modified sample of which you can see below.

    <table>
        <tbody>
<tr>
            <td>8</td>
            <td data-col="a" data-row="8"></td>
            <td data-col="b" data-row="8"></td>
            <td data-col="c" data-row="8"></td>
            <td data-col="d" data-row="8"></td>
            <td data-col="e" data-row="8">♚</td>
            <td data-col="f" data-row="8"></td>
            <td data-col="g" data-row="8"></td>
            <td data-col="h" data-row="8"></td>
        <tr>
</tbody></table>

For some more thorough and much cleaner looking samples with css to format them nicely, take a look at any of the unit test files in the solution as you see highlighted below. These samples all import perfectly fine using our new formatter object, and are also very easy to use the mark-1 eyeball to see what's going on with the board itself by just viewing the file in any modern web browser. Again the above html table is just a sample; obviously you'd need the other 56 squares to make a full board :)




Now, on to the design and code of the formatter. In the future I can see myself wanting to import and export various other chess formats/notations (there are plenty of them), so let's use an interface to represent any type of formatter. We'll call the interface IChessBoardFormatter. Then, because the format we want right now is html based, we'll just call the class HtmlChessBoardFormatter and have the class implement the new interface.


IChessBoardFormatter defines 4 methods: Import, Export, ExternalPieceToNative, NativePieceToExternal. Import and Export should be pretty self-explanatory. ExternalPieceToNative converts an external representation of a piece (in whatever format) to a native piece (a short value from -6 (black king) to +6 (white king). NativePieceToExternal just goes the other direction.

HtmlChessBoardFormatter is the class we'll use to translate boards between our internal representation(arrays of short) and the new human-friendly format (html). For the moment I didn't implement the capability to export; just import. For now I only need this class in order to read in html files for unit testing. It's too much code to put in this blog post, so open up HtmlChessBoardFormatter and take a look at the Import and ExternalPieceToNative methods; they're where the magic is.

If you've never used the Html Agility Pack I highly recommend it for your HTML parsing needs in .net. I've used it in the Import method of the formatter class in order to find html elements with a data-row and data-col attribute, as they are the elements that contain our chess pieces. Here's a sample of it:

            var document = new HtmlDocument();
            document.LoadHtml(sourceBoard);
            foreach (var node in document.DocumentNode.SelectNodes("//*[@data-row]"))
            {
                var sourceRow = node.Attributes["data-row"].Value;
                var sourceCol = node.Attributes["data-col"].Value;


Spiffy huh? Resilient html parsing made easy in .net.

What's Next?

As you may have guessed, we'll have to hit up the unit tests for black pieces/movement and any other public methods of the valid move calculator next week. I can finally see the light at the end of the space-time continuum though, we're almost ready to start coding our "best move" logic! And, thanks to these unit tests, we'll actually be able to suggest valid moves.

Resources

Wikipedia Chess
Wikipedia en Passant
Wikipedia Chess Symbols in UnicodeHtml Agility Pack

Thursday, March 13, 2014

A Chess Project, Part 8

Intro

We're moving right along with this sizable project, a Web API that will tell you the "best" move to make for a given chess position/game. We've created a test page, a Web API for clients to call, and we're still in the middle of calculating valid moves. If you need a refresher, look back through the history of this blog and find parts 1-7; they'll give you the info you need. On to part 8!

Can't Put Your Own King in Check

As I mentioned last week, there is still one major restriction we need to code: you cannot make a move that puts your own king in check. Here is an illustration of such an illegal move:

(white's turn)


Normally the white pawn at d2 (the one with the red arrow pointing at it) could move forward/up one square to d3, or two squares to d4. However, because the black bishop on b4 would threaten the king if the pawn moved out of the way, the pawn cannot in fact move from its current location. This is the type of move we are trying to prevent, so let's figure out how to do that.

Logically speaking, the best thing I can come up with is to pretend that the white piece has moved, and then check the valid moves of all the black pieces. If a black piece would be capable of "taking" the white king, then the previous move was invalid. Keep in mind that this invalidity could count for any type of piece; a pawn move can't put your king in danger, a rook move can't, and so on. This means a logical place to put the code would be in AddMoveToList, as it's already called every single time we add a move to, well, the list.

This isn't where we'll start though. We'll first create a method that tells us if the king is in check. We'll be creative and call it IsKingInCheck. Here's the code for it:

        protected bool IsKingInCheck(bool colorIsWhite, ChessBoard board)
        {
            var kingPosition = FindKing(colorIsWhite, board);
            return ColorThreatensSquare(!colorIsWhite, board, kingPosition.Item1, kingPosition.Item2);
        }


Pretty short and sweet; we find the king, and then return a boolean telling us if the opposite color threatens the square that the king is on. We haven't yet created the FindKing function though, so let's do that now:

        protected Tuple<short, short> FindKing(bool colorIsWhite, ChessBoard board)
        {
            short kingPieceValue = (short)(Constants.King * (colorIsWhite ? Constants.WhiteTransform : Constants.BlackTransform));
            for (short row = 0; row < 8; row++)
            {
                for (short col = 0; col < 8; col++)
                {
                    if (board.Board[row, col] == kingPieceValue)
                        return new Tuple<short, short>(row, col);
                }
            }
            throw new Exception("King not found");
        }


This method determines what the short constant value is for the king based on the color we are looking for, then loops through the board to find the king on it. If there is no king we throw an exception.

It's worth pointing out now that we only need to traverse 1 branch into the tree to check for checks; after all, when you're checking if a piece threatens the king, you don't really care if the piece can actually make the move; you only care if the square is threatened. Because of this we now need to create a new field of class ChessValidMoveCalculator that tells us whether we should allow multi-layer traversal of the tree:

protected bool m_allowCheckSubTrees = true;


If you'll recall, IsKingInCheck calls the pre-existing function ColorThreatensSquare. It is in this function that we calculate the next color's valid moves to see if a square is threatened, so it's in this method that we need to set m_allowCheckSubTrees to false. Here's the updated version of this function:

        public bool ColorThreatensSquare(bool colorIsWhite, ChessBoard board, short row, short col)
        {
            var game = new ChessGame();
            var positions = new List<ChessBoard>();
            positions.Add(new ChessBoard(true) { Board = (short[,])board.Board.Clone() });
            game.Positions = positions.ToList();
            game.GameStatus = colorIsWhite ? GameStatus.WhitesTurn : GameStatus.BlacksTurn;
            var futureCalculator = new ChessValidMoveCalculator(game);
            futureCalculator.m_allowCheckSubTrees = false;
            var futurePositions = futureCalculator.CalculateValidMoves();
            var colorSign = colorIsWhite ? Constants.WhiteTransform : Constants.BlackTransform;
            foreach (var position in futurePositions)
                if (Math.Sign(position.Board[row, col]) == colorSign)
                    return true;
            return false;
        }


What did we do to this method? We first set the game.GameStatus to the turn of the appropriate color, based on who we are checking using the parameter colorIsWhite. I realized when I opened up this unit that I had never set whose turn it is in this "future" game, so I needed to do that in order to keep things from splodin. I then set futureCalculator.m_allowCheckSubTrees to false, so that we don't check to make sure the piece can actually move to determine if it threatens a square, as we don't want a nigh-infinite traversal of our logic tree.

The last thing we need to do is call our new method IsKingInCheck. As I said a few paragraphs ago, the best place to do this is in AddMoveToList.

        protected IList<ChessBoard> AddMoveToList(ChessBoard startingBoard, IList<ChessBoard> boards, short oldRow, short oldCol, short newRow, short newCol)
        {
            var resultArray = new ChessBoard[boards.Count];
            boards.CopyTo(resultArray, 0);
            var result = resultArray.ToList();
            if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8)
            {
                //check the sign (color) of the current square and future square; if same, don't allow the move
                var startingPieceSign = Math.Sign(startingBoard.Board[oldRow, oldCol]);
                var futurePieceSign = Math.Sign(startingBoard.Board[newRow, newCol]);
                if (startingPieceSign != futurePieceSign)
                {
                    var futureBoard = (short[,])startingBoard.Board.Clone();
                    var piece = futureBoard[oldRow, oldCol];
                    futureBoard[oldRow, oldCol] = Constants.Empty;
                    futureBoard[newRow, newCol] = piece;
                    var newBoard = new ChessBoard(true);
                    newBoard.Board = futureBoard;
                    //check if new board and starting board are the same; if so don't add to valid moves list
                    var equal = futureBoard.Rank == startingBoard.Board.Rank &&
                        Enumerable.Range(0, futureBoard.Rank).All(dimension => futureBoard.GetLength(dimension) == startingBoard.Board.GetLength(dimension)) &&
                        futureBoard.Cast<short>().SequenceEqual(startingBoard.Board.Cast<short>());
                    //make sure the move wouldn't put the current color's king in check
                    var wouldPutSameColorKingInCheck = false;
                    if (m_allowCheckSubTrees)
                    {
                        var futureBoardContainer = new ChessBoard(true);
                        futureBoardContainer.Board = futureBoard;
                        wouldPutSameColorKingInCheck = IsKingInCheck(m_game.GameStatus == GameStatus.BlacksTurn, futureBoardContainer);
                    }
                    //add move to list of valid moves
                    if (!equal && !wouldPutSameColorKingInCheck)
                        result.Add(newBoard);
                }
            }
            return result;
        }


The addition to this function starts with the comment "make sure the move wouldn't put the current color's king in check". Here we first determine if we're supposed to check sub-trees, because if not then we don't care if the move would put the king in check. If we are allowed to check sub-trees we set a local variable wouldPutSameColorKingInCheck to the appropriate value by calling IsKingInCheck, passing in the potential future board. Lastly we add the move to our list of valid moves only if it would not put the king in check.

What's Next?

We're moving right along. Next week we'll create our unit tests. We won't make any actual progress on the "best" move calculation while creating our tests, but we'll give ourselves better confidence that what we've done so far is actually correct and most likely we'll be able to find and fix some bugs.

Here's the link to the current source code.

Resources

  • Online chess board editor "Apronus"