Archive

Archive for the ‘.NET’ Category

DeScramble - Game Logic

May 8th, 2009

This is the 4th installment about my Scramble solver, DeScramble.  You can check out the first 3 parts here, here, and here.  In this post I am going to write a little about the game logic and how the program is setup to play the game.

The rules of the game are pretty simple; find words on the game board using a chain of adjacent letters and use each letter only once per word.  The brunt of the logic, which isn’t much, is knowing which letters are adjacent to which.  Since the game board is a square and the adjacent letters are above and below one another, we have to create a map in the code to tell us which letters are next to which.

board

Valid Moves

0 => 1, 5, 6
1 => 0, 2, 5, 6, 7
….
12 => 6, 7, 8, 11, 13, 16, 17, 18
….
24 => 18, 19, 23

We could of course create a static map of which squares are adjacent to which, but this doesn’t allow us the flexibility to solve for different sized boards (Scramble has both 4×4 and 5×5 games).  So how do we go about creating this map in a flexible way?  Before I show the code to setup the valid character chains I think it will be helpful to go over a few of the basic constructs of the solver.

A game board is made up a many board letters:

Collection<BoardLetter> gameBoard = new Collection<BoardLetter>();
internal class BoardLetter
{
  public char Letter;
  public sbyte Position;

  public BoardLetter(char letter, sbyte position)
  {
    Letter = letter;
    Position = position;
  }
}

The dictionary of words is partitioned by first letter so searching goes a little faster:

Dictionary<char, List<string>> dictionary = new Dictionary<char, List<string>>();

 
The valid character chains are keyed off position and contain a list of BoardLetters adjacent:

Dictionary<sbyte, Collection<BoardLetter>> validCharacterChains =
  new Dictionary<sbyte, Collection<BoardLetter>>();

 
Creating the character chains is pretty straight forward.  The general formula for finding adjacent positions would be position ± 1 and position ± row ± 1.  This formula works for all positions except those on the edge of the game board (top/bottom row and right/left column).  Since we know the game boards are always square finding the edge positions to handle the exceptions is simplified.  The finished method:

private void LoadCharChains()
{
  validCharacterChains.Clear();
  for (sbyte i = 0; i < puzzleLength; i++)
  {
    validCharacterChains.Add(i, new Collection<BoardLetter>());
    double col = (i + 1) % square;
    if (col != 1) // not left col so there is a char to the left
    {
      validCharacterChains[i].Add(gameBoard[i - 1]);
    }
    if (col != 0) // not right col so there is a char to the right
    {
      validCharacterChains[i].Add(gameBoard[i + 1]);
    }
    if (i >= square) // not first row so there is a char above
    {
      validCharacterChains[i].Add(gameBoard[i - square]);
      if (col != 1) // not first row not left col so there is a char above left
      {
        validCharacterChains[i].Add(gameBoard[i - square - 1]);
      }
      if (col != 0) // not first row not right col so there is a char above right
      {
        validCharacterChains[i].Add(gameBoard[i - square + 1]);
      }
    }
    if (i < (puzzleLength - square)) // not last row so there is a char below
    {
      validCharacterChains[i].Add(gameBoard[i + square]);
      if (col != 1) // not last row not left col so there is a char below left
      {
        validCharacterChains[i].Add(gameBoard[i + square - 1]);
      }
      if (col != 0) // not last row not right col so there is a char below right
      {
        validCharacterChains[i].Add(gameBoard[i + square + 1]);
      }
    }
  }
}

 
Now that we have the valid moves mapped out we can just loop though the dictionary of words to see if they can be found on the game board.  We use recursion for this keeping track of where we have traversed on the board so we don’t use the same position twice.  Not the cleanest code but it works:

private void SolvePuzzle()
{
  foreach BoardLetter boardLetter in gameBoard)
  {
    foreach (string possibleAnswer in dictionary[boardLetter.Letter])
    {
      if (!answers.Contains(possibleAnswer))
      {
        foundAnswer = false;
        List<sbyte> testedPositions = new List<sbyte>();
        testedPositions.Add(boardLetter.Position);
        string startWord = boardLetter.Letter.ToString();
        if (startWord.Equals("q"))
        {
          startWord = "qu";
        }
        CheckBoardForAnswer(boardLetter, startWord, possibleAnswer, testedPositions);
      }
    }
  }
}

private void CheckBoardForAnswer(BoardLetter boardLetter, string workingWord, string possibleAnswer,
        List<sbyte> testedPositions)
{
  for (sbyte i = 0; i < validCharacterChains[boardLetter.Position].Count; i++)
  {
    if (!foundAnswer)
    {
      BoardLetter workingLetter = validCharacterChains[boardLetter.Position][i];
      if (!testedPositions.Contains(workingLetter.Position))
      {
        string testWord = String.Concat(workingWord, workingLetter.Letter);
        // if we've added a q then go ahead and add a u
        if (testWord.EndsWith("q"))
        {
          testWord += "u";
        }
        if (testWord.Equals(possibleAnswer))
        {
          answers.Add(possibleAnswer);
          foundAnswer = true;
        }
        else if (possibleAnswer.StartsWith(testWord))
        {
          testedPositions.Add(workingLetter.Position);
          CheckBoardForAnswer(workingLetter, testWord, possibleAnswer, testedPositions);
          testedPositions.Remove(workingLetter.Position);
        }
      }
    }
  }
}

 
In my next (and most likely last) post I will go over how the screen processing works.

.NET, DeScramble , , , , ,

Parallel Computing Videos

November 15th, 2008

In my PDC Day 3 post I mentioned how impressed I was with the Parallel Computing session.  Ryan, Richard, and I are still talking about some of the stuff we saw and learned in that session.  Daniel was kind enough to mention in the comments that the video from his PDC talk is now online.  If you weren’t able to attend PDC or you didn’t make it to the session this is a must see video!

I also noticed on Daniel’s blog that he posted links to a video of an interview he did about parallelism at Tech Ed EMEA .  This interview is a nice compliment to the PDC session as it reiterates some of the important points of parallel computing such as what parallelism is (as opposed to just multi-threading) and why it’s so critical to understand how to leverage the power of multiple cores today given the prospect that 32+ core machines will be standard in the not too distant future.

It’s inevitable that parallelism will become a critical aspect of software development in the future and it’s nice to see Microsoft doing some great work in this area bringing such a vital (and complex) technology to the mainstream.

.NET, Programming , , , ,

Anders C# 4.0 Followup

November 11th, 2008

Since C# 4.0 was introduced by Anders at PDC 2008 there has been a lot of buzz about the features that have been added to the language and why. Many people have questions about why something like dynamic static types needed to be added and what was the thinking behind such decisions. I have wondered along with everyone else about many of these questions. Thankfully channel9 has managed to get an interview with Anders and asked him to clarify some of the reasoning behind the decisions they hade with the language. Video is below:


C# 4.0 - Questions and reasons behind the answers

.NET, Programming , , , , , ,

DeScramble - UI Overview

November 3rd, 2008

About a month ago I wrote an introduction to DeScramble an application I wrote this summer to cheat at the Facebook game Scramble.  In this installment I will introduce the UI and the basic functionality of the application.  Below is a screenshot of the main UI and a description of what each element does:

descrambleUI

  1. Game window finder - drag this target to the browser window that is running the Scramble game.  This allows the program to grab the window handle that is later used to interpret the game board.  In a future version I may attempt to try and find the window handle automagically but this works fine for now.
  2. Send Answers toggle - checking this option tells the program to send the answers to the game.
  3. Answer Speed slider - use this slider to change how fast the program sends the answers to the game.  From my testing anything lower than about 40ms tends to choke the game UI.
  4. Auto Stop/Start toggle (bot mode) - checking this option tells the program to automatically start and stop the solver during live games.
  5. Burst Mode toggle - checking this option tells the program to send the first 3 answers to the game immediately and then send answers based on the indicated answer speed.  This option is to ensure that when the scores are first posted that you have some points.  This eliminates the “cheaters lag” effect that is noticed when people have to type the board into a solver.
  6. Solve/Stop Solve button - this button starts and stops the solver.

.NET, DeScramble, Programming , , , , , ,

PDC 2008 - Day 3

October 29th, 2008

Here are some random notes from PDC day 3:

During the keynote I was pretty impressed with the Second Light demo.  In the demo they held a surface (a piece of paper in this case) over the main surface computer and it “illuminated” additional information about the data being displayed on the bottom surface.  So think of a map being displayed on the main surface and then holding a piece of paper over that surface and having street names appear, but only on the second surface.  Hard to explain, but cool to see.  Maybe I can dig up a video and provide a link later.

The parallel programming for managed code session was amazing!  It was cool to see what they have added to the framework to support multiple core/cpu machines and how easy they have made it for developers to support these architectures.  They have added a new feature called task which is a lightweight unit of work that can be queued up on a specific thread as to not overload the machine with memory allocation that can result form spinning up too many threads.  The best part about the new support that they have added is that syntactically it is almost the same as how you currently create a thread.

I spent some time chatting with the Azure folks in the Big Room getting some info on how to get hooked up to the cloud and some of the plans that MS has for bringing this service to businesses.  It was very informative and interesting to hear how they are going to take some of the more complex things that most companies have to tackle in terms of redundancy and reliability and to provide those in a cost effective way to customers.  I also ran into an old friend Clemens who I haven’t seen since I was in Germany in 04.  It was nice to catch up with him and hear him talk a little but about his passion for supporting the service bus in the cloud.  Here is a picture of us together in the Azure lounge.

We also spent a little time in the MS Research booth talking to the Pex guys.  They showed us a demo of pex and how it can be used to create unit tests for your code and how it can be used to get a more accurate view of your code’s quality.  I was very impressed with what I saw and I am going to start using it right away.  I am also going to attend the session tomorrow morning that will be doing.

Another busy day, my mind it full and my body is exhausted!

.NET, Programming , , , , , ,

PDC 2008 - Day 2

October 29th, 2008

Yesterday was great and Day 2 was chalk full of windows 7 and Oslo goodness.  The keynote started off right with a demo of Windows 7 and some of the new features that will be included.  Some of the key things that will be introduced in 7:

  • Better performance - reduced disk IO, reduced memory consumption, and faster response times from the start menu
  • Mountable and bootable VHDs - this is probably the biggest feature in 7 IMO
  • Improved program management from the taskbar - you can see more details within program groups and even preview the larger screen
  • Customizable taskbar and system tray - you can change what the shutdown button does and which items show up in the system tray and how they notify you
  • Tweakable UAC notifications - they added a slider that allows you to change how often and under which circumstances you will see the UAC approval prompt.

After the windows 7 keynote Don Box and Chris Anderson did a little demo of putting a service in the cloud.  These guys are always interesting and they did not fail to entertain.  Probably the funniest part of the demo was when people in the audience started hitting their published service during the keynote since it was running live in the cloud.  The next part of the demo after that happened was showing how to secure a service in the cloud.  LOL

Next it was off to learn about Oslo.  The session was packed and it was a very interesting overview as to what Oslo is and what it is NOT.  The main point is that a model-driven approach is not something new and that we have been doing this all along with technologies from COM to .NET 3.0.  Oslo is a toolset to assist in this process we have been doing this whole time.  Oslo is made up of 3 main parts:

  • M - This is a textual language used to describe the models. This is used by devs to create and manipulate models.
  • Quadrant - This is a tool for interacting with models and DSLs.  It is a way to overlay visuals over the top of your models.
  • Repository - This is simply the database that holds all of the model data.

After getting a taste for Oslo we headed over to the M deep dive.  This was a very short demo that showed how you can use IntelliPad (an M dev tool) to build and populate models.  They also talked about the grammar processor that allows yo to make your own custom syntax for M to allow a more natural language way of manipulating models.

The day ended with the party at universal studios.  It was a Halloween theme with smoke everywhere and zombie-like actors walking around the park trying to scare people.  It was pretty over the top but luckily the bottom part of the park wasn’t full of these characters.  Best ride at the park has to have been the Mummy roller coaster.

.NET, Programming , , , , ,

PDC 2008 - Day 1

October 28th, 2008

PDC 08 Day 1 did not disappoint.  Here are some of the highlights from my day:

Keynote
They keynote was a pretty good introduction to Microsoft’s ideas about cloud computing and how they are going to bring it to the world.  I was more interested in the “cloud” after leaving the keynote than I was when I walked in so I guess that’s a good thing.  I can definitely see the benefit to putting and running a lot of stuff out in the cloud.  I was pretty disappointed that there was no funny/quirky video (ala Bill’s last day) during the keynote.  :(

CRM
My fist session was the MS CRM which was fairly interesting.  The CRM 4 stuff was pretty basic where they highlighted CRM’s offline ability and the seamless way the UI can be integrated right into outlook.  The really good stuff was when they showed the CRM 5 stuff.  They have done some great stuff in the designer allowing admins to really do a lot more with customizing the forms in CRM and making them more useful.  Things like related lookup fields which support the ability to cascade in the UI was a very cool feature.  Other new features are filtering lists, native charts with drill-down, inline sub-grids, support for headers and footers in the forms.  One other nice change was no more pop-up windows when you select records.  Instead they change the main window to show the record and then the navigation around the frame changes and the left nav “slides” off screen hidden from view but still accessible when you mouse into the left side of the page.

C# Futures
By far the coolest session of the day was Ander’s C# futures talk (here is the video from this talk).  Anders showed some of the really cool features coming in C# 4 as well as a few small peaks into 5!  The changes in C# 4.0 centered around 4 topics:

  1. Dynamic typed objects (this is the main feature of 4.0) - Basically this introduces a new static type in C# called dynamic… yes the irony of this new type’s name wasn’t missed!  LOL  By using dynamic types you can allow the runtime to figure out the type of the object instead of the compiler.  This allows you to write C# much in the same way you write JavaScript.  In fact it’s so similar to the way you write JavaScript at one point Anders took some JS and pasted it into C# and changed “var” to “dynamic” and “function” to void and it compile and ran!  Very Slick.
  2. Optional and named parameters - this is a great feature that will greatly reduce the number of signatures you need to write for some of your API’s.  Basically it allows C# to act a bit like VB in the sense that you can have your method parameters be optional and assign them default values to be used if they are not passed in.  Additionally the callers of methods can specify which parameter they are passing in by naming it in the call.  This is done with a semicolon used in the method call - i.e. object.Method(message: “this is the message”);
  3. Improved COM interop - Microsoft leveraged the features from the new dynamic type and optional parameters to greatly simplify the calling of COM object from C# code.  This essentially lets you call COM objects just like you would if you weren’t doing interop instead of having to pass in a bunch of placeholder objects for missing values.
  4. Co and Contra variance - Basically this features allows safe operations to be performed object that are more derived than their interface or delegate. So for instance you could pass a List<string> into a method that was taking IEnumberable<object> as an argument.

Beyond the 4.0 features Anders chatted a little bit about what they are tinkering with for C# 5.0. One of the biggest things they are doing is rewriting the C# compiler in managed code. Once the compiler is written in managed code the plan is to open up the compiler so that people can tinker around with it. Anders then proceeded to show a jaw dropping demo where he showed an application that could compile an app as you typed it into the command line and then show you the effects of the new compiled line of code immediately as you typed it. It was very impressive and the jam packed room was filled with open mouths and clapping hands.

After the sessions we headed over to the expo and stocked up on some conference swag. One of the most interesting things in the expo was Verne Troyer (aka mini-me) signing autographs at the devExpress booth.

All in all a great day @ PDC 2008!

.NET, Programming , , , , , ,

PDC 2008 - What’s it all about?

September 23rd, 2008

I just saw this video over on Channel9 about this year’s PDC and what the big “theme” is going to be this year.  In the past we’ve had such themes as the .NET PDC and the Longhorn PDC.  This year they are dubbing it the “Software + Services PDC”.  Doesn’t really roll of the tongue but they are promising some major paradigm shifts and some “industry changing” announcements.  Should be a pretty interesting time in LA this fall.

My favorite part of the video was the part about “the goods” they will be giving out this year:

“Plus……we’re announcing the very special gift that all PDC attendees will receive:  a 160GB external USB2 hard drive with all of the bits!”

I’ve embedded the video below:


Countdown to PDC 2008: This is the Software + Services PDC, Plus a Hard Drive Chock Full o’Bits is a PDC Attendee’s Dream Come True!

.NET, Programming , , ,

DeScramble - An Introduction

September 22nd, 2008

This summer I was introduced to a game on Facebook called Scramble. Essentially it’s Boggle but played in a web browser. I was immediately hooked on this game and started playing it regularly. One day as I was playing the game and wondered if I could write a program that could automate my playing this game. Surely software could play this game WAY more efficiently and accurately than I could right?

So I opened up my trusty IDE and started plugging away at trying to make a program smart enough to play Scramble better than I could. Seems like it should be easy enough with the bar set so low.

About a day later I had a very basic Scramble solver which could take a string of letters as input and then spit out a list of possible answers. While there some interesting things about writing a basic Scramble solver (these are very simple to make), I wanted something a little more automated. I also wanted something that didn’t just flat out cheat and win but would act more human to be less noticeable. About a week later I had it finished, my automated Scramble application affectionately called DeScramble.

It was a pretty fun summer project and I plan on spending the next several blog posts talking about the way it works and some of the things I learned as well as some of the challenges. I am also going to try and put together a video so everyone can see it in action.

So stay tuned.

.NET, DeScramble, Programming , , , , ,

Looking for the right exception?

December 16th, 2005

This is mostly for my own reference; I am usually looking for the right exception to throw so here is a single list with everything deriving from System.Exception nicely nested and linked:

System.Object
   System.Exception
      System.ApplicationException
         System.Reflection.InvalidFilterCriteriaException
         System.Reflection.TargetException
         System.Reflection.TargetInvocationException
         System.Reflection.TargetParameterCountException
      System.IO.IsolatedStorage.IsolatedStorageException
      System.Runtime.Remoting.MetadataServices.SUDSGeneratorException
      System.Runtime.Remoting.MetadataServices.SUDSParserException
      System.SystemException
         System.AppDomainUnloadedException
         System.ArgumentException
            System.ArgumentNullException
            System.ArgumentOutOfRangeException
            System.ComponentModel.InvalidEnumArgumentException
            System.DuplicateWaitObjectException
         System.ArithmeticException
            System.DivideByZeroException
            System.NotFiniteNumberException
            System.OverflowException
         System.ArrayTypeMismatchException
         System.BadImageFormatException
         System.CannotUnloadAppDomainException
         System.ComponentModel.Design.Serialization.CodeDomSerializerException
         System.ComponentModel.LicenseException
         System.ComponentModel.WarningException
         System.Configuration.ConfigurationException
         System.Configuration.Install.InstallException
         System.ContextMarshalException
         System.Data.DataException
            System.Data.ConstraintException
            System.Data.DeletedRowInaccessibleException
            System.Data.DuplicateNameException
            System.Data.InRowChangingEventException
            System.Data.InvalidConstraintException
            System.Data.InvalidExpressionException
               System.Data.EvaluateException
               System.Data.SyntaxErrorException
            System.Data.MissingPrimaryKeyException
            System.Data.NoNullAllowedException
            System.Data.ReadOnlyException
            System.Data.RowNotInTableException
            System.Data.StrongTypingException
            System.Data.TypedDataSetGeneratorException
            System.Data.VersionNotFoundException
         System.Data.DBConcurrencyException
         System.Data.Odbc.OdbcException
         System.Data.OracleClient.OracleException
         System.Data.SqlClient.SqlException
         System.Data.SqlServerCe.SqlCeException
         System.Data.SqlTypes.SqlTypeException
            System.Data.SqlTypes.SqlNullValueException
            System.Data.SqlTypes.SqlTruncateException
         System.Drawing.Printing.InvalidPrinterException
         System.EnterpriseServices.RegistrationException
         System.EnterpriseServices.ServicedComponentException
         System.ExecutionEngineException
         System.FormatException
            System.Net.CookieException
            System.Reflection.CustomAttributeFormatException
            System.UriFormatException
         System.IndexOutOfRangeException
         System.InvalidCastException
         System.InvalidOperationException
            System.Net.ProtocolViolationException
            System.Net.WebException
            System.ObjectDisposedException
         System.InvalidProgramException
         System.IO.InternalBufferOverflowException
         System.IO.IOException
            System.IO.DirectoryNotFoundException
            System.IO.EndOfStreamException
            System.IO.FileLoadException
            System.IO.FileNotFoundException
            System.IO.PathTooLongException
         System.Management.ManagementException
         System.MemberAccessException
            System.FieldAccessException
            System.MethodAccessException
            System.MissingMemberException
               System.MissingFieldException
               System.MissingMethodException
         System.MulticastNotSupportedException
         System.NotImplementedException
         System.NotSupportedException
            System.PlatformNotSupportedException
         System.NullReferenceException
         System.OutOfMemoryException
         System.RankException
         System.Reflection.AmbiguousMatchException
         System.Reflection.ReflectionTypeLoadException
         System.Resources.MissingManifestResourceException
         System.Runtime.InteropServices.ExternalException
            System.ComponentModel.Design.CheckoutException
            System.ComponentModel.Win32Exception
               System.Net.Sockets.SocketException
            System.Data.OleDb.OleDbException
            System.Messaging.MessageQueueException
            System.Runtime.InteropServices.COMException
            System.Runtime.InteropServices.SEHException
            System.Web.HttpException
               System.Web.HttpCompileException
               System.Web.HttpParseException
               System.Web.HttpRequestValidationException
         System.Runtime.InteropServices.InvalidComObjectException
         System.Runtime.InteropServices.InvalidOleVariantTypeException
         System.Runtime.InteropServices.MarshalDirectiveException
         System.Runtime.InteropServices.SafeArrayRankMismatchException
         System.Runtime.InteropServices.SafeArrayTypeMismatchException
         System.Runtime.Remoting.RemotingException
            System.Runtime.Remoting.RemotingTimeoutException
         System.Runtime.Remoting.ServerException
         System.Runtime.Serialization.SerializationException
         System.Security.Cryptography.CryptographicException
            System.Security.Cryptography.CryptographicUnexpectedOperationException
         System.Security.Policy.PolicyException
         System.Security.SecurityException
         System.Security.VerificationException
         System.Security.XmlSyntaxException
         System.ServiceProcess.TimeoutException
         System.StackOverflowException
         System.Threading.SynchronizationLockException
         System.Threading.ThreadAbortException
         System.Threading.ThreadInterruptedException
         System.Threading.ThreadStateException
         System.TypeInitializationException
         System.TypeLoadException
            System.DllNotFoundException
            System.EntryPointNotFoundException
         System.TypeUnloadedException
         System.UnauthorizedAccessException
         System.Web.Services.Protocols.SoapException
            System.Web.Services.Protocols.SoapHeaderException
         System.Xml.Schema.XmlSchemaException
         System.Xml.XmlException
         System.Xml.XPath.XPathException
         System.Xml.Xsl.XsltException
            System.Xml.Xsl.XsltCompileException
      System.Windows.Forms.AxHost.InvalidActiveXStateException

.NET