Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Friday, December 16, 2011

Code generation in C#

I wrote my first code generator on the weekend. The real work - generating the C# class files - was trivial. Getting the generator into a state so that it could be easily used was more difficult.

There are a few ways you could do code generation in .NET. I explored:
I went with T4 Templates. They were a little obscure at first but provided the easiest entry point into using the code generator. You just build-up your source file and then right-click and select "Run Custom Tool" on the .tt file to generate the code.

I encounted a few issues when trying to write my template. They were:
  • Extension methods can't be embedded into a T4 Template. There is a workaround. I ended up converting my extension methods into normal methods (I only had two).
  • Accessing your assemblies is difficult in Visual Studio 2010. It has been explained very well. I managed to access my assemblies by writing something like <#@ assembly name="$(SolutionDir)..\DomainEntities\bin\Debug\Cpa.DomainEntities.dll" #>
The example T4 Templates I found on the Internet were a little more complex than what I wanted. (Examples should be as simple as possible.) I wanted to load a source file into memory and generate class files from that. Download my example template if you want something similar. It loads in a CSV file that has two columns (first column is the name of the class, second column the name of the property) and generates some puesdo-code of what the class files will eventually look like. I used this as my base template, then expanded it to create proper C# class files.




Wednesday, September 14, 2011

Some funny code...

I often sigh while reading the source code at me new job. Occasionally, I have a few laughs too. For example:

            catch (Exception exception)
            {
                throw new Exception(exception.ToString());
            }


I'm not sure what it is about exception handling but it seems to be the most frequently mis-understood/mis-used area of programming C#. The lines above are not nearly has bad as:

            catch (Exception exception)
            {
            }

which I've seen a lot of too, but it's more of a sigh moment than laugh.

Tuesday, June 28, 2011

Computer Opponent: Noughts & Crosses

The next task on my list for making a strategy game is writing a computer opponent. In the tutorial I describe how I’ve used variations on the minimax algorithm to play noughts and crosses (tic-tac-toe). I chose noughts and crosses because it’s finite (always ends in 5-9 moves) and simple, yet there are thousands of different solutions. Eventually, I plan on using a minimax type algorithm for a game which will use the hex board tutorial I created in Unity earlier.

The C# source code for this project is available here.
The tutorial is available here.

The end result of this project is a console application that plays noughts and crosses with itself. It cycles through games using negamax, alpha-beta pruning and negascout. Every game is, of course, a draw. (You may notice that negascout is slower than alpha-beta pruning. This is because I haven’t ordered the search tree, it’s such a simple game that it isn’t worth it.) There is also a test project that runs a number of tests to make sure that the algorithms are doing what I expect them to do.

Friday, June 17, 2011

Unity, hexagons and path-finding

I’m creating a strategy computer game again. This time I thought I’d write some tutorials as I go. In this tutorial, I bring path-finding on an hexagonal grid together with Unity.

I assume a good knowledge of C# and no knowledge of Unity. If you know how the A* search algorithm works, you’ll probably be able to read all the code without any problems.

You can access the tutorial here.
The source code and Unity project file are available here (7zip).
A Windows binary is available here.
A Mac binary is available here.


Screenshot of the result

Wednesday, June 8, 2011

MSI, Orca and file permissions: or it's 2011 and installers still suck

I had to create an MSI for distributing some software. After installing, I noticed that one of the files didn't allow read/write permissions to my application. You'd think that would be easy to fix: just go into Visual Studio, select the file and change the security permissions, right? Wrong.

If you have the same problem, one way to resolve it is:
  1. Download Orca (it allows you to edit MSI files)
  2. Run Orca and open an MSI file
  3. Go to the LockPermissions table
  4. Add a new row and fill in four of the five fields (see image). The fields are:
    1. LockObject (the ID of the file, this is found in the File table);
    2. Table (the name of the table that you're editing, in this case the "File" table, but it could be "Registry" or something else);
    3. Domain (I left this bank);
    4. User (I put in "Everyone" which is incredible insecure, but I really don't care);
    5. Permission (the meaning of the numbers is explained here);
  5. Save the MSI and exit Orca


Usually, installed files take on the permissions of the directory they are installed to. If you install to "C:\Program Files," your files will get the permissions that the program files directory has. However, using LockPermissions will overwrite all of these permissions and just assign SYSTEM and the permissions you added in the LockPermissions table. This is super-dodgy, but then, the whole thing is super-dodgy. Other people recommend using a custom action as part of the installation, e.g., using "ICacls". This is probably a better way to do it, I was just running out of time.

Wednesday, May 11, 2011

WPF copy/paste column names on DataGrid

I always forget that you can easily include column names when copying a DataGrid by setting
ClipboardCopyMode="IncludeHeader"
in the XAML of the DataGrid.

Thursday, March 10, 2011

The worst thing about Entity Framework

Generally, I like Entity Framework, especially the newest version (part of Visual Studio 2010). The absolute worst thing about it is the error message you can get when you are hooking-up your POCO files to an entity model. The error message is: "Mapping and metadata information could not be found for EntityType [...]"

EF tells you in which class the error is located, but that's it. It could be any of the properties that don't work! If you have a database table with 20 or 50 fields, good luck in tracking down the error. The best info I've found is that the error can be caused by:
  • Misspelled properties (case-sensitive!)
  • Properties missing in the POCO class
  • Type mismatches between the POCO and entity-type (e.g., int instead of long)
  • Enums in the POCO (EF doesn't support enums right now as I understand)
It has got to be the worst error message I've seen from Microsoft in a long time.

Monday, November 15, 2010

WPF ComboBox and XAML parser

For the past few days I have been trying to figure out why my ComboBox didn't work when I selected an item from a list of data-bound items. I've gone through the code over and over, tried different types of collections and different ways of accessing the selected item (SelectedValue or SelectedItem as int, string or object). Nothing worked.

Data-binding to a ComboBox in WPF/Silverlight isn't always as smooth as one would assume. People have problems here, here and there. The XAML was fairly easy to lay out, I thought. I had:

<ComboBox SelectedItem="{Binding Path=ReferenceType}"

ItemsSource
="{Binding Path=ReferenceTypes}" />

It wasn't until I read "I always set the ItemSource before the SelectedItem and all works fine." that I thought I'd try switching my code to:

<ComboBox ItemsSource="{Binding Path=ReferenceTypes}" 

SelectedItem
="{Binding Path=ReferenceType}" />

This way I define ItemsSource before SelectedItem. However, I never thought for a second that the XAML parser would care. I assumed the parser would figure out that it needs to know about the collection before it cared about what was selected. Obviously, if this were c# code I'd always specify the collection first, but this was XML, what does it care about the order of attributes?

I had broken the first rule of programming, never assume.

Tuesday, October 5, 2010

Learning a new (programming) language

I'm attempting to learn a new programming language. The main issue here is that F# isn't just a new language, it's a new type of language. There are three main (i.e. popular) paradigms of programming languages: imperative (the one you learn at school), object-orientated (the one most programmers use), and functional (the one I'm trying to learn). Object-orientated is really just an extension of imperative programming, so for me, learning F# is about learning how to re-think how to do things.

I thought I'd try to do the Euler problems like Andrew is doing at a misdirected effort.

My solution for problem 1 in F#:
let multiple x = if x % 3 = 0 || x % 5 = 0 then x else 0

let sequenceOfNumbers n = [1 .. n]

let euler1 numbers =
numbers
|> Seq.map multiple
|> Seq.sum

printf "Result = %i" (euler1 (sequenceOfNumbers 999))
The way I'd do it in C#, however, is:
static int Euler1(int maxValue)
{
var sum = 0;
for (var i = 1; i <= maxValue; i++
if
(i % 3 == 0 || i % 5 == 0)
sum += i;

return sum;
}
Is there really all that much difference? Could I have expressed it in F# in a more functional way? I don't know. Hopefully I can change the way I think about functional programming as I move through the problems.

Friday, August 27, 2010

Metaheuristic

I was trying to explain the sorts of algorithms I use at work to a friend the other night. In general, they're called metaheuristics (in particular, I have experience with simulated annealing and genetic algorithms.) I used an analogy of an ordinary heuristic like one that tries to find the shortest path between to points.

Shortest path: Imagine you want to find X marks the spot on a map. However, there are all these barriers in the way and you can't really be sure if the route you're taking will 1) get you there; or 2) get you there with the least steps. However, so long as there is someone/something telling you how far away you are from the X, you should always be able to find the shortest route - if there is one. That's A*.

To describe when to use a metaheuristic, however, I said "well, imagine you don't actually know where X marks the spot is." But it's much worse than that. Imagine you don't really know where it is and no matter which direction you take you don't necessarily or reliably get any closer to X. For example, you start a long way from X; you go ten metres north and you're close; then go twenty metres south and you're just as close. But, actually, the closest you could ever get to X might be five metres east from the start! It just doesn't make any sense. Like someone calling out "hotter" or "colder" seemingly at random when you're trying to find something. They aren't lying to you, it's just really hard to find. If you have a situation like that, use a metaheuristic, or punch them.

Friday, August 6, 2010

Genetic Algorithms

There is something a little bit creepy about writing genetic algorithms. I'm not quite sure what it is...


// Run selected breeding program
while (stopWatch.Elapsed < _parameters.SimulationExecutionTime)
{
population = Selection(population).ToList();

var children = Breed(population);

Mutate(children);

population.AddRange(children);
}

Wednesday, August 4, 2010

Subversion

I have decided to hide subversive quotes in the software I am working on.

If you find them all, you unlock "The Revolution Complete" achievement.

Thursday, July 1, 2010

ToolTips and ShowDuration

This took me a while to figure out, so I thought I'd mention it for others searching. If you want to set a global ToolTip show duration in WPF, you can do it for each type of control as a style in the XAML file. E.g.


<Window.Resources>
<Style TargetType="Label">
<Setter Property="ToolTipService.ShowDuration" Value="120000" />
</Style>
</Window.Resources>


This means that for the Window, all the Label ToolTips will remain for two minutes.

If you want good looking ToolTips, go here.

Friday, April 23, 2010

My HSL colour class

Want a unique set of colours without having to do any work? You need HSL.

Use:


for (var i = 0; i < 10; i++)
(Color)new ColorHsl((byte)((float)i / 10 * 255), 127, 127)


Class (Note, I mostly ripped this off from elsewhere, but mine 1) actually works, 2) is easy to use.):


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;

namespace UserInterface
{
public class ColorHsl
{
public ColorHsl(byte h, byte s, byte l)
{
H = h;
S = s;
L = l;
}

public byte H, S, L;

public static implicit operator Color(ColorHsl colorHsl)
{
double r, g, b, h, s, l; //this function works with floats between 0 and 1
double temp1, temp2, tempr, tempg, tempb;
h = colorHsl.H / 256.0;
s = colorHsl.S / 256.0;
l = colorHsl.L / 256.0;

//If saturation is 0, the color is a shade of gray
if (s == 0)
{
r = g = b = l;
}
else
{
//Set the temporary values
if (l < 0.5)
{
temp2 = l * (1 + s);
}
else
{
temp2 = (l + s) - (l * s);
}

temp1 = 2 * l - temp2;
tempr = h + 1.0 / 3.0;

if (tempr > 1)
{
tempr--;
}

tempg = h;
tempb = h - 1.0 / 3.0;
if (tempb < 0)
tempb++;

//Red
if (tempr < 1.0 / 6.0) r = temp1 + (temp2 - temp1) * 6.0 * tempr;
else if (tempr < 0.5) r = temp2;
else if (tempr < 2.0 / 3.0) r = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempr) * 6.0;
else r = temp1;

//Green
if (tempg < 1.0 / 6.0) g = temp1 + (temp2 - temp1) * 6.0 * tempg;
else if (tempg < 0.5) g = temp2;
else if (tempg < 2.0 / 3.0) g = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempg) * 6.0;
else g = temp1;

//Blue
if (tempb < 1.0 / 6.0) b = temp1 + (temp2 - temp1) * 6.0 * tempb;
else if (tempb < 0.5) b = temp2;
else if (tempb < 2.0 / 3.0) b = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempb) * 6.0;
else b = temp1;
}

return Color.FromRgb(Convert.ToByte(r * 255), Convert.ToByte(g * 255), Convert.ToByte(b * 255));
}
}
}