Evil Science A whole load of stuff


YouTube walk through of Scott Adams classic text adventure Mission Impossible

The awesome Text Adventurer has put together a video of a complete walkthrough of the Scott Adams classic Mission Impossible (aka Secret Mission) complete with an ambient soundtrack!


Notepad++ Emmet jQuery Template

Here's a little addition I've made for the excellent Notepad++ plugin Emmet. It's a shortcut that creates a HTML5 template with a link to jQuery "jquery-2.1.3.min.js" and a "$(document).ready" function, as shown below.


It's straightforwards to do, and requires three additions to Emmet's "snippets.json" file, that is located in the Notepad++ direction "\plugins\EmmetNPP\emmet\".

Addition 1, to?the section "snippets", a child of "html":

"jqdocready": "\\$(document).ready(function() {\n\n});"

Additions 2 and 3, to?the section "abbreviations", a child of "html":



In situ, the three additions look like this:




Obviously, make changes at your own risk, but if done correctly, this will work. Cheers m'dears,

Filed under: HTML5, Main No Comments

FastStone Capture – Windows Screen Capture Tool

FastStone Capture is a powerful, flexible and intuitive screen-capture utility. It allows you to capture anything on the screen including windows, objects, full screen, rectangle regions, freehand-selected regions and scrolling windows/web pages.


Filed under: Main No Comments

Checking the validity of an NHS Number using 1 line of C#

This article is an implementation of the method for checking NHS Number validity, as described in the article:


This is an experiment to reduce the checking method to one line of code, and makes no?attempt at being efficient.?This single line, below, is arranged into 8 lines to make it easier to read.

pNHSNumber.ToCharArray().Where (i=> i>= 48 && i <=57).Count() != 10 ? false :
new List() { pNHSNumber.ToCharArray()
.Where((value, index) => index < 9)
.Select((value, index) => (10 - index) * (value - 48))
.Sum() }
.Select(i=> i % 11)
.Select(i=> (11 - i) == 11 ? 0 : (11-i))
.First() == (pNHSNumber[pNHSNumber.Length - 1] - 48);

It is constructed as follows:

  • Line 1: Checking the string length is 10 and consists only of digits
  • Lines 2 - 5:? Multiply the first nine digits by a weighting factor and sum, storing the?result, a single value, in a generic list.
    • Line 3 : select the first 9 digits of pNHSNumber.ToCharArray()
    • Line 4: Multiply each of the digits by it's weighting - first digit by 10 e.g. (10 - index of 0), second digit by 9 (e.g. 10 minus index of 1) etc
    • Lin 5: sum the values produced by line 4
  • Line 6: Get the remainder of the sum when divided by 11
  • Line 7: Subtract the remainder from 11, and if the resultant value is 11 change to 0
  • Line 8: Test if the check digit is equal to last digit


Wrap up the above in a function:

bool CheckNNHSNumber (pNHSNumber string)
pNHSNumber.ToCharArray().Where (i=> i>= 48 && i <=57).Count() != 10 ? false :
new List() { pNHSNumber.ToCharArray()
.Where((value, index) => index < 9)
.Select((value, index) => (10 - index) * (value - 48))
.Sum() }
.Select(i=> i % 11)
.Select(i=> (11 - i) == 11 ? 0 : (11-i))
.First() == (pNHSNumber[pNHSNumber.Length - 1] - 48);

and call it, thusly:

//valid NHS number

//invalid NHS Number

Filed under: C#, Main No Comments

Doctor Who missing episode totals by year


The above says it all - the number of episodes of Doctor Who missing by year, the reason for the drop is due to pure look and the dedication of Doctor Who fans in searching for missing episodes.

For more information, go to The Destruction of Time: What Is Missing.

Tagged as: No Comments

A C# algorithm to build interesting cave systems for your Roguelike !!!UPDATE!!!

Export map array as Bitmap

I have noticed that people have expressed an interest in getting an image of the generated map to pass into Unity3D. So I have updated the Github link to add a new function to the class?csCaveGenerator.cs, that when called generates a bitmap of the map array, and I have pasted it below for your interest.

/// <summary>
/// Generate a bitmap from the contents of the map array
/// </summary>
/// <returns></returns>
public Bitmap GetMapImage()
//adjust to change the pixel size on the image
Size blocksize = new Size(5, 5);

Bitmap bmp = new Bitmap(MapSize.Width * blocksize.Width, MapSize.Height * blocksize.Height);
using (Graphics g = Graphics.FromImage(bmp))
using (SolidBrush sbBlack = new SolidBrush(Color.Black))
for (int x = 0; x < MapSize.Width; x++)
for (int y = 0; y < MapSize.Height; y++)
if (Map[x, y] == 1)
g.FillRectangle(sbBlack, new Rectangle(x * blocksize.Width, y * blocksize.Height, blocksize.Width, blocksize.Height));


Filed under: Main 1 Comment

Simple Roguelike Dungeon Generator Using C#

Building a dungeon for your character to explore, along with being able to see that dungeon, ?is one of the most important parts of a Roguelike, and unlike sight algorithms there is a near infinite number of ways that a dungeon can be generated.?This article describes a simple map building algorithm using rooms and corridors, which is written in C# 3.5 - links to the code are the bottom of this article.

Building a Map

Using the app is pretty simple: select one of the two options in the combobox in the top left corner and click the button Build and a map will be generated. The property grid on the left hand side can be used to adjust various map building properties, which are discussed in more detail below.


Two options are offered for building a map:

  1. Build_OneStartRoom - a start room is placed in the centre of a map as starting point, and rooms and corridors are built of it.
  2. Build_ConnectedStartRooms - two rooms are placed on opposite sides of the room and joined with a corridor?as starting point, and rooms and corridors are built of it.

The difference between the two methods is that Build_OneStartRoom()?produces a map with rooms and corridors clustered together, whilst Build_ConnectedStartRooms?produces a more distributed map that fills more of the map area.

Map Properties

Adjusting the properties, which are discussed in more detail below, can produce maps with different appearances. Here are a few examples:

Build Probability: 100 - this will cause corridors to only be built of existing corridors.
Build Probability: 0 - this will cause corridors to only be built of existing existing rooms.
Rooms to Build: 5 and Maximum Corridor Turns: 25. Nice twisty corridors!
Corridor Spacing: 10, Break Out: 1000. Corridors must be a distance of 10 units away from other corridors. Break Out counter is increased?to allow successful map generation.


Map Building Logic

Both of the map building options use the following logic to build a map:

  1. Place start room or rooms.
  2. Required number of rooms built? No, go to step 2, else quit.
  3. Get a random point on the edge of a room, or a corridor,
  4. Test if the only point is valid. Yes, go to step 3, else step 1.
  5. Attempt to build a corridor and examine the outcome of that method:
    1. The corridor has hit an existing room: build corridor
    2. The corridor has hit an existing corridor: build corridor.
    3. The corridor operation has completed: attempt to build a room on the end point of the corridor, and if successful build the corridor.
  6. If?break out?property exceeded exit the loop. Prevents the loop from getting stuck.
  7. Go to step 1.


Mapbuilder has a number of properties which can be adjusted to determine the appearance of the generated map:

  1. Corridor Related
    1. Corridor Spacing - the number of empty cells the corridor has to have on either side of it for it to be built. This is dependant upon the direction it is travelling. If travelling north, it must have that number of empty cells to the east and west of it.
    2. Minimum Length - the minimum length of a corridor.
    3. Maximum Length - the maximum length of a corridor.
    4. Maximum Turns - the maximum number of direction changes a corridor can make whilst it is being built.
  2. Map
    1. Map Size - the size of the rectangle containing the dungeon.
    2. Break Out - When this value is exceeded, exit the dungeon generating While loop.
  3. Probability
    1. Select room - the value between 1 and 100, that when exceeded will cause a room to be selected as the starting point for a corridor build operation.
  4. Room
    1. Corridor Distance - the minimum distance a room can be placed from existing corridors.
    2. Distance from other rooms - the minimum distance a room can be from other rooms before it can be built.
    3. Maximum Size - the maximum size of a room.
    4. Minimum Size - the minimum size of a room.
    5. Rooms to build - the total number of rooms to build.

Corridor Building

The process for finding a start point for a corridor is:

  1. To randomly choose a start point on a corridor or room and a direction the corridor will "grow" in using the method?Corridor_GetStart. The property?Select Room is used to determine the probability of choosing a corridor or room, by default it is set to 50%.
  2. If step 1 successful pass the start point and direction the method?CorridorMake_Straight and examine the return value to determine what to build, some of the return values are:
    1. Completed: corridor has been completed without running into anything.
    2. Hit existing corridor: corridor has hit an existing corridor.
    3. Hit existing room
    4. Hit self

(All return types are described in the enum?CorridorItemHit).

In the example method Build_ConnectedStartRooms()?and Build_OneStartRoom(), if the corridor is completed, an attempt to build a room of it is made and if that is successful both the room and corridor are built. If the corridor hits an existing room, an existing corridor or itself the corridor is built.

Corridors are added to the map array, and also stored in the generic list?lBuilltCorridors to enable additional tests when attempting to build other rooms or corridors. When a corridor is being built it is stored in the generic list?lPotentialCorridor.

Room Building

A room is a rectangle which is built of a corridor end point in the direction the corridor was moving. After a rectangle has been created using the properties?Minimum Size?and?Maximum Size, it is tested in the method Room_Verify()??for the following:

  1. Check it occupies legal, empty coordinates in the map 2d array.
  2. It is expanded by the property?RoomDistance and tested to see if it makes contact with any current rooms stored in the generic list?rctBuiltRooms.
  3. It is expanded by the property CorrdiorDistance?and tested to see if it makes contact with any current rooms stored in the generic list?lBuilltCorridors?.

If the above criteria are met, the room is built - it is added to the 2d array map, and the rectangle which defines it is added to the?generic list?rctBuiltRooms.


When a corridor is being built a direction is chosen using one of the two methods:

  1. Direction_Get(Point dir) - get a random direction, as long as that direction is not the opposite of the one provided to the method. This prevents back tracking.
  2. Direction_Get(Point pDir, Point pDirExclude) -??get a random direction, as long as that direction is not the opposite of the one provided to the method AND the direction specified in?pDirExclude. The later direction is the first direction chosen when a corridor is built - this will stop a generating corridor from going in the opposite direction to the one ?it started with. Makes longer, less twisty corridors.

The corridor building method?CorridorMake_Straight () offers a parameter called?PreventBackTracking,?that when set to to true will select the later option and when false the former. In all build_ examples, a value is selected randomly.

Break out, or getting stuck

Adjusting the properties will produce mazes with different characteristics, but may cause prevent the map from being built, for example if one specifies 100 rooms in a relatively small map the loop contained within the build method will never exit as 100 rooms won't fit, so a counter is placed within the loop that will cause the loop to exit when the property?Break Out?is exceeded?and the method will return false and in the provided application a messagebox will alert the user to this.

The Map Builder Code

The class?csMapbuilder.cs?contains the code used to build a map.

The public methods?Build_ConnectedStartRooms() and?Build_OneStartRoom() are called to build a map, and the boolean value returned indicates if building a map was successful; success occurs when the required number of rooms are built before the property?Break Out is exceeded.

The public property Map, a two dimensional integer array contains the built map. A value of 1 indicates a solid cell and value of 0 is an empty space your adventurer can explore.

Here's a bit of pseudo code demonstrating the above:

csMapbuilder mpbuild?= new csMapbuilder(150, 150); //the numbers are the starting map size

if (mpbuild.Build_ConnectedStartRooms() == true)

//map drawing code to go here

Get the code

To download the C# source code click here.

Github: click here.

Filed under: Main 6 Comments

And I’m back…

...did you miss me? of course you didn't, as nobody reads what I post or visits this site. Hey ho.

A while back, WordPress was giving me an error when I tried to hit the site, saying a file, wp-db.php, was missing. I ignored it for a while, and then it started to depress so I set about fixing it. I wasn't really sure what to do, and after spending some time examining the error logs I worked out the aforementioned file was missing, so I downloaded the latest version of WordPress, acquired an FTP Client and uploaded the missing file.

Great success!

Filed under: Main 1 Comment

Trolls: fantasy versus reality!

Filed under: Main No Comments

Excel Macro: colour alternate ranges of the same value in the specified column

'   Process a column of values, colouring alternate ranges of the same value.
'   Work down a column of cells, stopping when a blank is hit.
'   If a cell is a different value to the one preceding it, invert the
'   value of the toggle variable.
'   If the toggle variable is true colour the cell.
Public Sub main()

    Dim w As Worksheet
    Set w = Worksheets("Sheet1")
    Dim rowCtr As Integer
    rowCtr = 2
    Dim toggle As Boolean
    toggle = False
    While w.Cells(rowCtr, 1).Value <> ""
        If rowCtr > 2 Then
            If w.Cells(rowCtr, 2).Value <> w.Cells(rowCtr - 1, 2).Value Then
                toggle = Not toggle
            End If
        End If
        If toggle Then
            With w.Cells(rowCtr, 2).Interior
                .ColorIndex = 6
                .Pattern = xlSolid
            End With
        End If
        rowCtr = rowCtr + 1

End Sub
Filed under: Main No Comments