Tuesday, January 21, 2014

A Chess Project, Part 3

Intro

This is part 3 in a series on creating a chess Web API HTTP Service. In Part 1 we gave an overview of the project requirements. In Part 2 we created the very basic Web API Service skeleton. Here in Part 3 we cover how to connect to a Web API Service two different ways, one using c# code and one using JavaScript. For the purposes of this tutorial we will do all our communication via JSON, though you could almost as easily communicate via XML or even create your own serialization scheme.

Viewing Sample Data

Before we get started on connecting to the API with client code I thought I'd make a small modification to the ChessBoard struct from last week, just for the purpose of visualization. Specifically, I want to initialize the 8x8 array of short that represents the pieces on the board. It currently is an empty 8x8 array, but I want to initialize the values to all 0's. I plan on using 0 to mean that the square is empty, so it's logical that we would want to start with an empty board. The updated code is shown below:

using System;

namespace BlogChess.Backend
{
    public struct ChessBoard
    {
        public short[,] Board;

        /// 
        /// Constructor
        /// 
        /// as implied by the parameter name, this parameter is useless.
        /// It is only here because you cannot have a parameterless constructor in a struct.
        public ChessBoard(bool throwAway) : this()
        {
            Board = new short[8, 8];
            for (int row = 0; row < 8; row++)
            {
                for (int column = 0; column < 8; column++)
                    Board[row, column] = 0;
            }
        }
    }
}


It's not really much of a change, as you can see. The only difference is the addition of the nested for loops. The real reasons behind doing this is so that you can visualize better what a ChessBoard object looks like in JSON, and so it will be easier to create the appropriate classes in JavaScript.

In this next snippet of code I've added a new method to the BlogChessController class, GetSampleGame. This method is here solely to return a default-populated ChessGame object, thus making it easier for a JavaScript client to know what to send up. That's it; it's just an aid for clients and peoplezez.

        /// 
        /// This is a simple get method so someone can see the structure of a chess game object and its sub-objects
        /// 
        /// A default-state chess game object
        public HttpResponseMessage GetSampleGame()
        {
            var result = new ChessGame() { GameStatus = GameStatus.BlackWin };
            var positions = new List<ChessBoard>();
            positions.Add(new ChessBoard(true));
            result.Positions = positions;
            return Request.CreateResponse(result);
        }


As you can see above, this method has the same return type as the method from Part 2 of the tutorial. What we are doing here is creating a ChessGame, populating it's positions property (an enumerable of type ChessBoard) with a single default ChessBoard (all 0's), and returning that ChessGame. The WebMethod above starts with th word "Get", so it will respond to the HTTP Get verb. This should be your first moment of ah-ha excitement for the week; you can now fire up the service in the VisualStudio debugger and browse to the url for this WebMethod http://localhost:11482/api/BlogChess/SampleGame (note that your port may be different). You will probably be asked (it depends on your browser) if you want to open a .json file. If so click yes. You will then see the following output:

{"Positions":[{"Board":[[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],[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]]}],"GameStatus":3}

Huzza! We have now called a quick and dirty sample webmethod (albeit one that we don't need for the final result of the project) using nothing but a web browser! The end part of the URL shown above is our web method; Note that you just use "SampleGame", not "GetSampleGame" as the purpose of the word Get above is just to denote which HTTP verb we respond to.

Connecting via C# Client

OK now it's time to really roll up the sleeves and get crackin. We're going to connect to the original API Method PostBestMove via some C# code. Go ahead and add a new Web Application to your BlogChess solution.


Choose Visual C#, Web, ASP.Net Web Application. Change the name to BlogChessApiFlexer, click OK.

Choose the "Empty" template, check the box for "Web Forms", and click the OK button.


Now you've got a project in your solution named BlogChessApiFlexer. But hey, you already knew that because you just did it. Add a new web form to this new project; name the web form Default. Right-click on the new project, click Add, then Web Form, type in the name and hit OK.


The easiest way to call our Web API Service using C# is to add the Web API Client Libraries to our project. You already have this thing installed into your solution, you just need to add it to the BlogChessApiFlexer project. Go to Tools, Library Package Manager, Manage NuGet Packages for Solution.



 Click on Installed Packages, All, Microsoft ASP.Net Web API Client Libraries, and click the Manage button.


Click the checkbox next to BlogChessApiFlexer and click the OK button.




Close the NuGet packages window. You'll also need to add a reference to BlogChess.Backend in the BlogChessApiFlexer project. Go ahead and do that, I'll wait.

Now it's time to mess with Default.aspx. We're going to keep the page pretty simple. It needs 2 buttons and 1 label, that's it. One button will postback to the server and have a server-side Click event handler. The other button we'll deal with later. The label will have the results of our tests in it, but for now it can be empty. Here is the full default.aspx file as of right now:

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

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    Ooh, Web API Sample Clients
</head>
<body>
    <form id="form1" runat="server">
    
</form> </body> </html>


Here is the C# code-behind file, Default.aspx.cs. I'll explain it below the source code.

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using BlogChess.Backend;

namespace BlogChessApiFlexer
{
    public partial class Default : System.Web.UI.Page
    {
        protected void btnServerTest_Click(object sender, EventArgs e)
        {
            //1. Create and setup client object
            HttpClient client = new HttpClient() { BaseAddress = new Uri("http://localhost:11482/") };
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            //2. Create a blank chess game to send up in the post request
            var game = new ChessGame() { GameStatus = GameStatus.Draw };
            var positions = new List<ChessBoard>();
            positions.Add(new ChessBoard(true));
            game.Positions = positions;
            //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 bestMove = response.Content.ReadAsStringAsync().Result;
                lblResult.Text = "Success! :" + bestMove;
            }
            else //5. Request failed; tell the user what happened
                lblResult.Text = "Failzor'd!: " + response.StatusCode.ToString() + "::" + response.ReasonPhrase;
        }
    }
}



In section 1 we create an HttpClient object and assign it headers that will tell the server we expect a JSON response. This HttpClient object is what we will use to connect to the Web API Service. In section 2 we create a blank chess game that will be used as the single request parameter in the server post. Section 3 posts the request to the server; note that using the PostAsJsonAsync method will automatically convert that 2nd parameter to json for us. Section 4 assumes success, and reads the resulting "best move" from the response, displays it to the user. Section 5 assumes failure, displaying the HTTP error code and reason for failure.

Now run the website, loading up the default.aspx page. Click on the button "Server Test". You should see a result of 'Success!: "e4"'. Your C# client code has now called your server-side Web API Service. That's about it for the C# client! On to JS...


Connecting Via JavaScript Client

One easy way to connect to a Web API Service is through the use of a JavaScript library called JQuery. We'll probably get into JQuery more in a future blog post, but for now what you need to know is how to use it in your page. Modify the header of Default.aspx to look like this:


    Ooh, Web API Sample Clients
    




The change above is the addition of the script tag. We're just referencing the jquery library so we can use it. Now we have to add some more JavaScript in order to call the API, but you probably guessed that. Gold star for you! But no soup; the soup is mine. Here are the changes, and I'll explain the changes below the code:

    



Note: the above script tag goes in your header, below the script tag we added earlier for referencing JQuery. Section 1 of this new script tag is the definition of our JavaScript function bestMove(). This function will be used to call the API. Section 2 is where we setup some initial variables before making the call. Not much special, we just need an object of the proper format to send to our API method. Section 3 is where we call the API, and this is the most interesting part of the JS code. the jquery $.ajax() method is an easy way to make calls to services. As you can see, it is very easy to specify the url, type (post, get, etc), the content type (we want json!), and functions to call on success and failure. By default this function call is asynchronous, so these handlers (success function and error function) are how you will know that the call to the service is done. Section 4 is where we hook up the button click event to the function we declared above.

Now run the website, loading up default.aspx. Click the button market "Client Test". You should see the resulting string 'e4'. That wasn't too bad was it? You've now created a Web API and called it using 2 different languages. Fun stuff, highly useful, and highly portable. Gotta love Web API.


What's Next

Next week we'll have to code in some game validation and the logic for checking for victory, draw, etc. I believe that leaves us a 5th and hopefully final posting in this series for tackling the AI. Thanks for reading, and I hope you are looking forward to post #4!

Resources

  • http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client
  • http://www.codeproject.com/Articles/424461/Implementing-Consuming-ASP-NET-WEB-API-from-JQuery
  • http://www.json.org/
  • http://jquery.com/ 
  • http://api.jquery.com/jquery.ajax/

Thursday, January 16, 2014

A Chess Project, Part 2

Intro

We're going to continue our chess project, the one we introduced last week in Part 1 of the series. In week 1 we covered the requirements of the project. The capabilities we are looking for and the input and output required. Here in Part 2 we will start creating the "interface" that our clients will use. This interface will be in the form of a Web API HTTP Service that client code can call from anywhere, as long as they have an internet connection.

Introduction to Web API

What is Web API? Web API is Microsoft's platform for building RESTful HTTP services. I'll assume you already know what HTTP is, but let's take a look at RESTful. First, REST stands for Representational State Transfer. The concept of RESTful architecture has been around for some time in the programming world; the Web is based on it. It basically means that the client doesn't necessarily need to know anything about what information and processes the server contains, as long as it has a uniform way to communicate with the server (via HTTP for the web). For our purposes we will be able to call our service RESTful if it properly applies HTTP verbs and resources. For example, if we want to post information to the service to have it calculate the best move and return it, we would use an http POST to accomplish this. There are of course other HTTP verbs such as GET, DELETE, PUT, and more, but for our small service POST will be the only applicable one. With Microsoft Web API HTTP Services you can rely on JSON and/or XML data. They are extremely portable due to accepting both JSON (very easy to find libraries based on JSON) and XML (also easy to find libraries based on XML). The coding is really quite simple I promise, so let's see how to create one.

Step-by-Step Instructions for Creating our Web API HTTP Service

First off, I assume that you have Visual Studio 2013. I am using Express for Web 2013 myself, so your screens may look a little different if you are using a different version.

Start by clicking on File-->New Project. Choose Visual C#, and ASP.Net Web Application. Type in the name BlogChess for the solution and hit the OK button.

On the next screen choose "Empty", click the checkbox to add folders and core references for Web API and hit the OK button.





You now have your very own Web API Service. I'd like to rename the project (not the solution, the project) to BlogChessApi so do that now. Right-click on the project, click Rename, type in the name BlogChessApi. Your Solution Explorer window should now look like this:



The next step is to decide how the client will communicate with the service. I believe a single post should do nicely for us, so we only need a single method. We'll call it CalculateMove. What will the client send for data? We'll create a ChessGame class that has a list of boards, and a single enum for whose turn it is. The board object will actually be just an 8x8 2-dimensional array of short where each short value represents a different piece (or no piece).

Just in case we use the ChessGame class elsewhere (and we probably will!), let's put it in a DLL rather than directly in the web service. Add a new DLL (class library) named BlogChess. Right-click the solution, choose Add and New Project.



In the window that comes up choose Visual C#, Windows, Class Library, type in the name BlogChess.Backend, and hit the OK button.


Now rename the file Class1.cs to ChessGame.cs, as this will be our data class.






Go ahead and add a public struct to BlogChess.Backend as well. This struct will be named ChessBoard. It's the easiest way we have to ensure that everywhere we want to represent a board as an 8x8 array of shorts that we will get it right. The code for Chessboard.cs is shown below.

using System;

namespace BlogChess.Backend
{
    public struct ChessBoard
    {
        public short[,] Board;

        /// 
        /// Constructor
        /// 
        /// as implied by the parameter name, this parameter is useless.
        /// It is only here because you cannot have a parameterless constructor in a struct.
        public ChessBoard(bool throwAway) : this()
        {
            Board = new short[8, 8];
        }
    }
}

Now we need to setup the ChessGame class so that it contains a list of ChessBoard objects as well as an enum that represents the status of the board position (black's turn, white's turn, draw, win for black, win for white). The code for ChessGame.cs is shown below.

using System.Collections.Generic;

namespace BlogChess.Backend
{
    /// 
    /// Current status of a chess game
    /// 
    public enum GameStatus
    {
        BlacksTurn,
        WhitesTurn,
        Draw,
        BlackWin,
        WhiteWin,
    }

    /// 
    /// A game of chess
    /// 
    public class ChessGame
    {
        public IEnumerable<chessboard> Positions { get; set; }
        public GameStatus GameStatus { get; set; }
    }
}

Lengthy post huh? Hang in there, we're making good progress here. If you've made it this far, drop by my office sometime and I'll give you a hearty pat on the back.

We've done what we needed to do in the backend dll, so let's dive back into the Web API Service.Web API Services follow the Model-View-Controller pattern (we'll probably discuss this more in the distant future) so you have to add a Controller class. The controller is what contains your methods that clients of your web service can see.

Right-click the Controllers folder in the BlogChessApi project and select Add, Controller.




On the next dialog select "Web API 2 Controller - Empty" and click the Add button.


Name the controller BlogChessController.


We're about to create the method BestMove that our clients will call, but first we need to add a reference in BlogChessApi to BlogChess.Backend. In the BlogChessApi project, right-click References, and click Add Reference.



Click Solution, BlogChess.Backend, and click OK.


The reference to BlogChess.Backend from BlogChessApi is now complete. It's time to get codin! Below you can see the entire BlogChessController.cs unit. It's really pretty sparse:

using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using BlogChess.Backend;

namespace BlogChess.Controllers
{
    public class BlogChessController : ApiController
    {
        public HttpResponseMessage PostBestMove(ChessGame game)
        {
            //basic input validation...if required fields not specified, return an error message wrapped in an http "bad request" 400 result
            if (game == null || game.Positions == null || game.Positions.ToList().Count == 0)
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "The game and at least 1 position must be specified.");
            //calculate move here
            string bestMove = "e4";
            //return the best move wrapped in an http "ok" result
            return Request.CreateResponse(HttpStatusCode.OK, bestMove);
        }
    }
}


Yes that's the entire unit. The first thing to note is our class descends from ApiController. This was already here when we generated the class. ApiController is a basic web api controller class that gives us a few goodies to make life a little easier.

The 2nd part of note is our single method PostBestMove. Let's start with the return type HttpResponseMessage. Here we are telling the service to return a valid HttpResponseMessage so that our result conforms to http message protocol. We could return a 404 (url not found), 400 (invalid request), 200 (OK), or any other http response we want by specifying this as the return type. The next noteworthy item is the name of the method, PostBestMove. When you put the word Post in the front of a method name in a Web API controller, you tell .Net what HTTP method your method will accept and respond to. In our case we want the user to send an HTTP post containing the information, so we use the word Post. You can also see that we accept a single parameter of type ChessGame. This is the list of board positions that we expect the client to provide in order for us to calculate and return the best move.

The 3rd thing to be aware of is our input validation section. The validation itself isn't very interesting; pretty mundane actually. The interesting part here is the return statement. Using Request.CreateErrorResponse, we can tell .Net to create an HTTP error response with the specified error code (in our case it's 400, Bad Request) and optionally tack a helpful string for the client onto the response.

The last thing to note is the calculation and return of the best move. The calculation is bare-bones for now. We'll fill that in a couple blogs from now. The return statement looks similar to the last return statement, except here we use CreateResponse instead of CreateErrorResponse. We're just telling the client that all is hunky dory.

Calling and debugging your brand new service is pretty easy; however, this post is already huge so I'll save that for next week. Teaser: you can access the debug version of your Web API service at http://localhost:11482/api/BlogChess/bestmove. You'll have to replace the port # with whatever port # your asp.net server runs on though.

What's Next?


That's it for this week guys! Tune in next week to see how to call the web api service using JavaScript and C#. I'll also cover how ASP.Net knows to access your service at http://localhost:11482/api/BlogChess/bestmove. Hint: the magic of routing!

 Feel free to read up on routing, Web API, and of course chess if you want to get ahead of the class. We've still got a good amount of work to do to round out this series!

Resources

http://www.asp.net/web-api
http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api

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