Archive for the ‘C#’ Category

Loving the Visual Studio 2008 compiler

Friday, December 5th, 2008

I have been finding lambda and extension methods really helpful in my game port.

Blobs of C styled single linked list code, when changed to generic lists boil down to one line.

like this:

Item item = player.itemsPtr;
while (item != null)
{
    Item next_item = item.next;

    if (item_type == item.type)
    {
        lose_item(item, player); // just removes from linked list.
    }
    item = next_item;
}

to this:

player.items.RemoveAll(item => item.type == item_type);

much nicer.

CodeCamp: Delegates

Saturday, November 1st, 2008

Wow, I’m sitting here in a C# 3.0 - A Whirlwind Tour talk, and the group has stalled on Delegates, a .Net 1.0 feature. Anonymous Delegates lost more people, Lambda functions are now messing with peoples heads….

Eeek, this is all 101 stuff, people!

It’s almost like nobody gets C function pointers or C++ functors.

TimeDirection graph

Monday, September 8th, 2008

A work college was wanting some trivial code to draw a time based direction plot, and insisted that I do it.

So here is my drawing class:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace LineCurve
{
    public class TimeDirection
    {
        public void Draw(Graphics g, Panel pnl, List<KeyValuePair<int,float>> data, int maxtime)
        {
            using (Brush brush = new SolidBrush(Color.Blue))
            {
                float halfx = pnl.Width / 2.0f;
                float halfy = pnl.Height / 2.0f;
                float scale = Math.Min(halfx, halfy) / (float)maxtime;

                foreach (KeyValuePair<int, float> kvp in data)
                {
                    int time = kvp.Key;
                    double dir = kvp.Value / 180.0 * Math.PI;

                    // subtrack y as 0 is top, and +y is bottom.
                    float fx = (float)(halfx + (Math.Sin(dir) * scale * time));
                    float fy = (float)(halfy - (Math.Cos(dir) * scale * time));

                    g.FillRectangle(brush,fx, fy, 1.0f, 1.0f);
                }
            }
        }
    }
}

And given the input:

List<KeyValuePair<int,float>> data = new List<KeyValuePair<int,float>>();
for (int i = 0; i < 40; i++)
{
    data.Add(new KeyValuePair<int, float>(i, i * 9.0f));
}

td.Draw(g, pnl, data, 40);

Looks like this:

time/direction based graph

This code is released under the MIT license, except it may not be used for web-based weather applications.

Cedric’s Coding challenge

Wednesday, July 2nd, 2008

I noticed Cedric’s Coding challenge while reading Robert Fisher’s blog.

Here is an interesting coding challenge: write a counter function that counts from 1 to max but only returns numbers whose digits don’t repeat.

For example, part of the output would be:

  • 8, 9, 10, 12 (11 is not valid)
  • 98, 102, 103 (99, 100 and 101 are not valid)
  • 5432, 5436, 5437 (5433, 5434 and 5435 are not valid)

Also:

  • Display the biggest jump (in the sequences above, it’s 4: 98 -> 102)
  • Display the total count of numbers
  • Give these two values for max=10000

Because I love coding problems, I whipped up a C# 2.0 solution which is not as succinct as some of the functional solutions, but it works on a ‘fast enough for me’ time scale.

using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApplication1
{
    class Program
    {
        static bool[] used = new bool[10];
        static int value = 0;
        static void Main(string[] args)
        {
            int gap = 0;
            int last = 0;
            int count = 0;
            Stopwatch timer = new Stopwatch();
            timer.Start();
            int mag = 1;
            for (int i = 1; i < 10; i++)
            {
                foreach (int x in Step(1, mag))
                {
                    gap = Math.Max(gap, x - last);
                    last = x;
                    count++;
                }

                mag *= 10;
            }
            timer.Stop();
            Console.WriteLine("Count: {0}", count);
            Console.WriteLine("Gap: {0}", gap);
            Console.WriteLine("Time: {0}", timer.Elapsed);
            Console.ReadKey();
        }
        static IEnumerable<int> Step(int start, int mag)
        {
            for (int i = start; i < 10; i++)
            {
                if (used[i] == false)
                {
                    if (mag == 1)
                    {
                        yield return value + i;
                    }
                    else
                    {
                       used[i] = true;
                       value += mag * i;

                       foreach (int x in Step(0, mag / 10))
                       {
                           yield return x;
                       }

                       used[i] = false;
                       value -= mag * i;
                   }
               }
           }
       }
    }
}

Giving the following output (for 1 - MaxIn, as compared to 1-10,000 in the original challenge)

Count: 5611770
Gap: 10469135
Time: 00:00:02.8350765

Finding reference .dll’s

Friday, March 14th, 2008

I am currently upgrading our build process from .bat files to CruiseControl.Net projects.  Mostly C++ projects but a few VB and one C#.

The C# project has a reference to NUnit.Framework.dll, and every thing worked well on the developer machines and the build server when building Visual Studio or using devenv.exe. But I have changed to using MSBuild.exe because that is what the CruiseControl.Net/NAnt example I’ve been following does.

When MSBuild.exe is ran at the command prompt the C# project runs fine, but when run from the CruiseControl.Net service I get the following errors:

errorCS0246: The type or namespace name 'NUnit' could not be found (are you missing a using directive or an assembly reference?)

After lots of hair pulling, I noticed one of the my C# projects had a <HintPath> element inside a <Reference> element.  The example was a relative path, but changing it to a full-path was required for my situation, as the projects are loaded to a different location on the build server.  So, in my C# project’s .csproj file, I have added this block:

<Reference Include="nunit.framework, Version=2.4.2.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files\NUnit 2.4.2\bin\nunit.framework.dll</HintPath>
</Reference>

I’m not sure how you would set the <HintPath> element from inside Visual Studio.