Starbeamrainbowlabs

Stardust
Blog


Archive

Mailing List Articles Atom Feed Comments Atom Feed Twitter Reddit Facebook

Tag Cloud

3d account algorithms android announcement architecture archives arduino artificial intelligence artix assembly async audio bash batch blog bookmarklet booting c sharp c++ challenge chrome os code codepen coding conundrums coding conundrums evolved command line compilers compiling compression css dailyprogrammer debugging demystification distributed computing documentation downtime electronics email embedded systems encryption es6 features event experiment external first impressions future game github github gist graphics hardware hardware meetup holiday holidays html html5 html5 canvas infrastructure interfaces internet io.js jabber javascript js bin labs learning library linux low level lua maintenance manjaro network networking node.js operating systems performance photos php pixelbot portable privacy problem solving programming problems project projects prolog protocol protocols pseudo 3d python reddit reference release releases resource review rust secrets security series list server software sorting source code control statistics storage svg technical terminal textures three thing game three.js tool tutorial tutorials twitter ubuntu university update updates upgrade version control virtual reality virtualisation visual web website windows windows 10 xmpp xslt

Learning Three.js 2: Catch the Sphere

Catch the sphere in action.

The second thing that I have made in my endeavours to learn three.js is a simple catch the sphere game. Every time you get close to the orange sphere, it will move it to another random place in the room, add one to your score, and play a sound.

I cheated a little bit on the collision detection... I really ought to look into writing a simple 3D collision detection library that uses boxes and spheres.

The collision detection for the sphere is really done in 2D - I check only on the x and z axes to see if you are within a certain distance of the sphere since your y position doesn't change. For the bounding box, I simply check to make sure that your x and z co-ordinates aren't too big or too small.

You can find it here: two

Rob Miles has Linked to This Blog!

This is a quick post to say that Rob Miles has linked to this blog in his latest post. You can find that post here.

Coding Conundrums 2

Number two in a series of more than one. Definitely.

Welcome to my solutions to Rob Miles' Coding Conundrums 2. The problem descriptions can be found below, along with pastebin and 32 bit binary links (other binary type available upon request). If you need any help, please ask in the comments below.

2.1: Crazy Times Tables

Description

A teacher friend wants to be able to print out stupid times-tables for their kids at school. Perhaps they are not a maths teacher. I have no idea. Anyhoo, the program should request the number of the table (for examplethe3.7 times table) and then print out 1 to 12 timesthat value:

What times table do you want? 3.71

times 3.7 is 3.72 times 3.5 is 7.4..

and so on

The teacher tells you that the 0 times table and the 1 times table are too easy and the program should reject those, but any other value (including negative ones) is OK.

My Solution

This solution works ok, but you get a few inaccuracies with certain values. Changing float to double or decimal would probably solve those issues.

using System;

public class CrazyTables
{
    public static void Main(string[] args)
    {
        if(args.Length != 1)
        {
            Console.WriteLine("Use it like this: ");
            Console.WriteLine("    CrayTables.exe <float>");
            Console.WriteLine("\n<float>: The number to use when generating the times table.");
            return;
        }

        float number = float.Parse(args[0].Trim());

        if(number == 0 || number == 1)
        {
            Console.WriteLine("Invalid times table number.");
            return;
        }

        for(int i = 0; i < 12; i++)
        {
            Console.WriteLine("{0,2} times {1} is {2,2}", i + 1, number, (i + 1) * number);
        }
    }

    public static bool ValidateInput(float number)
    {
        if (number == 0 || number == 1)
            return false;
        else
            return true;
    }
}

(Pastebin, 32 bit binary)

2.2: Scrabble™ Scores

Description

Scrabble™ is a word game. Players take turns to make words out of letter tiles. Each tile has a particular value. Generally, the rarer the letter in words, the higher the value. The tiles have the following values:

  • (1 point)-A, E, I, O, U, L, N, S, T, R
  • (2 points)-D, G
  • (3 points)-B, C, M, P
  • (4points)-F, H, V, W, Y
  • (5 points)-K
  • (8 points)-J, X
  • (10 points)-Q, Z

I want a program that will tell me how much a given word is worth in Scrabble™. Turns out that Rob Miles is worth 12 points, I'd like to be able to find out if anyone else has a name worth more than mine.

My Solution

Another C♯ Dictionary here.

using System;
using System.Collections.Generic;

public class ScrabbleScorer
{
    public static void Main(string[] args)
    {
        if(args.Length != 1)
        {
            Console.WriteLine("Use it like this:");
            Console.WriteLine("    ScrabbleScorer.exe <word>");
            Console.WriteLine("\n<word>: The word to calculate the score for.");
            return;
        }

        Console.WriteLine("'{0}' scores {1} points.", args[0], CalculateWordValue(args[0]));
    }

    public static Dictionary<char, int> wordValues = new Dictionary<char, int>()
    {
        { 'a', 1 }, { 'b', 3 }, { 'c', 3 }, { 'd', 2 }, { 'e', 1 }, { 'f', 4 }, { 'g', 2 }, { 'h', 4 }, { 'i', 1 },
        { 'j', 8 }, { 'k', 5 }, { 'l', 1 }, { 'm', 3 }, { 'n', 1 }, { 'o', 1 }, { 'p', 3 }, { 'q', 10 },{ 'r', 1 },
        { 's', 1 }, { 't', 1 }, { 'u', 1 }, { 'v', 4 }, { 'w', 4 }, { 'x', 8 }, { 'y', 4 }, { 'z', 10 }
    };

    public static int CalculateWordValue(string word)
    {
        word = word.ToLower();
        int totalScore = 0;

        foreach(char ch in word)
        {
            int chScore = 0;
            if(wordValues.TryGetValue(ch, out chScore))
            {
                totalScore += chScore;
            }
        }

        return totalScore;
    }
}

(pastebin, 32 bit binary)

2.3: Scrabble™ Validity Tester

Description

Staying with Scrabble. A standardScrabble&153; set contains the following set of tiles: A-9. B-2. C-2. D-4. E-12. F-2. G-3. H-2. I-9. J-1. K-1. L-4. M-2. N-6. O-8. P-2. Q-1. R-6. S-4. T-6. U-4. V-2.

Plus two blanks which can be assigned any letter when they are played.

For extra bonus points you could improve your program so that it indicates whether or not the word could actually entered during the game. The program could also indicate whether or not a blank tile is required.

My Solution

The problem description is missing some of the tile counts for me, so I am using data from [this website]. I tried to compact the array of tile counts for this one, but it didn't work too well because I ended up writing more code to read the array than I saved by compacting it.....

using System;
using System.Collections.Generic;

class ScrabbleValidator
{
    // from http://scrabblewizard.com/scrabble-tile-distribution/
    // the coding conundrums seems to have a few letter counts missing
    public static string[] letterCounts = new string[]
    {
        "", // 0
        "jkqxz", // 1
        "bcfhmpvwy*", // 2 - * = blank tile
        "g", // 3
        "dlsu", // 4
        "", // 5
        "nrt", // 6
        "", // 7
        "o", // 8
        "ai", // 9
        "", // 10
        "", // 11
        "e", // 12
    };

    public static int blankTileCount = 2;

    static void Main(string[] args)
    {
        if(args.Length != 1)
        {
            Console.WriteLine("This program works out whether a word is a valid scrabble word.");
            Console.WriteLine("Use it like this:");
            Console.WriteLine("    ScrabbleValidator.exe <word>");

            Console.WriteLine("\n<word>: The word you want to validate.");
            return;
        }

        string word = args[0].Trim().ToLower();

        // count the number of each letter in the word
        Dictionary<char, int> letterCounts = new Dictionary<char, int>();
        foreach (char ch in word)
        {
            if (letterCounts.ContainsKey(ch))
            {
                letterCounts[ch] += 1;
            }
            else
            {
                letterCounts.Add(ch, 1);
            }
        }

        // loop over the letter counts and validate the word
        string invalidReasons = "";
        int usedBlanks = 0;
        foreach (KeyValuePair<char, int> letterCount in letterCounts)
        {
            char currentChar = letterCount.Key;
            int currentCharCount = letterCount.Value;
            int maxCharCount = getLetterCount(currentChar);

            if (currentCharCount > maxCharCount)
            {
                if(usedBlanks + (currentCharCount - maxCharCount) <= blankTileCount)
                {
                    usedBlanks += currentCharCount - maxCharCount;
                }
                else
                {
                    invalidReasons += String.Format("The character '{0}' is used {1} times (scrabble has {2} tiles for that letter).\n", currentChar, currentCharCount, maxCharCount);
                }
            }
        }

        if(invalidReasons.Length > 0)
        {
            Console.WriteLine("{0} is not valid. Reasons: ", word);
            Console.WriteLine(invalidReasons);
        }
        else
        {
            Console.WriteLine("{0} is a valid scrabble word.", word);
            Console.WriteLine("It would use {0} blank tiles.", usedBlanks);
        }
    }

    static int getLetterCount(char ch)
    {
        for(int i = 0; i < letterCounts.Length; i++)
        {
            if(letterCounts[i].Contains(Char.ToLower(ch).ToString()))
            {
                return i;
            }
        }
        return 0; // the character wasn't recognised, so there won't be any tiles that match it.
    }
}

(pastebin, 32 bit binary)

Note that I don't have any analytics on this site yet, so the only way I know you have been here at all is through the comments (and the server logs).

Splitting your C♯ Code into Multiple Files 2: DLLs

I have found out about compiling and linking to DLLs. I think this is called Dynamic Linking but again, I could be wrong.

We will be using the example files from last time:

filea.cs:

using System;

class ClassA
{
    public static void Main()
    {
        Console.WriteLine("This is a test from file A");
        Someplace.ClassB.PrintHello();
    }
}

fileb.cs:

using System;

namespace Someplace
{
    public class ClassB
    {
        public static void PrintHello()
        {
            Console.WriteLine("Another hello from file B!");
        }
    }
}

This is a 2 step process. First we need to compile the DLL, then we need to compile the main exe and link to the DLL.

To compile the DLL, you type something like this:

csc /target:library fileb.cs

The important bit here is /target:library. This tells the C♯ compiler to compile your code to a DLL and not and exe.

To compile the main exe, you need to type something like this:

csc /reference:fileb.dll filea.cs

This tells the C♯ compiler to compile the code in filea.cs into an exe, and link it to fileb.dll.

Taken from this MSDN page.

Learning Three.js: Spinning Cube

A Spinning Cube

TL; DR: I am going to learn Three.js. I made this.

3D programming is much harder than 2D programming. You have to think about renderers and scenes and cameras and that extra dimension when specifying co-ordinates. I have wanted to break into the 3D world with my programming for some time, but every time I tried, I got confused.

Enter Three.js.

Three.js is a Javascript library that abstracts away all the complications of 3D programming that come with WebGl and makes 3D programming much easier. This series (hopefully!) will document the things that I learn about Three.js and programming in 3D.

This post is about my first attempt: A spinning cube. I found this tutorial to start me off. Although it is a little bit outdated, it works fine for my purposes.

The first thing I needed to wrap my head around were co-ordinates. In Three.JS they work as follows:

Three.js Co-ordinates visualisation

(Image credit: Originally made by Keistutis on openclipart.org, tweaked for use here by me)

If you imagine your physical laptop screen as the 3D space that your stuff lives in, then the x co-ordinate is from side to side (left: negative, right: positive), the y co-ordinate goes up (positive) and down (negative), and the z co-ordinate goes in front and behind (coming out of your screen: positive, going into your screen: negative) of your screen.

I am noting down the co-ordinate system here for my own reference... :D

You can see the code in action that I have written here: one - spinning cube.

If you can't see it, please check get.webgl.org. It will tell you whether your browser supports WebGL or not. Some (older?) chromebooks also have a buggy WebGL implementation if you use one of those.

Procedural Castle Generation

See the Pen Procedural Castle Generator by Starbeamrainbowlabs (@sbrl) on CodePen.

(Full screen)

The subreddit /r/proceduralgeneration has recently set up monthly challenges, and after missing the first one I decided to enter the second one. February's challenge was to generate random castles procedurally. The challenge was a lot of fun to take part in - my entry can be seen above.

I've published the code behind my entry on Github, too if you're interested in checking it out.

There were 15 other entries apart from mine. Here are all the entries next to each other:

All the entries

(Full size image [15MB])

I liked zapetch's because although it's 2D, the generated castles are very varied and they look nice and simple. Moosekk's was great too - The towers look complicated and it has buildings and trees too. Comment down below with your favourites. Why did you like them? Voting is now open - please go and vote here. Your votes will decide who gets to decide on the next challenge!

How it works

Since I can't write a post on something that I've done without explaining just a little bit about how it works, I've written up a quick overview below. If anyone is interested in a longer writeup or any specific part of the generator, please comment down below and I will get back to you as soon as I can.

The generator works by picking a random regular shape, and then randomly altering the location of each of the resulting corners a little bit. After that the towers (and their stairs) and the keep are generated, and the flags are placed. Since the wind only flows in one direction, all the flags all face the same direction.

The moat is generated as a closed smooth line, with it's control points generated by taking the corners of the castle and moving them a set distance away from the main keep. Since the moat originally was way too wide for the drawbridge (whose parameters don't actually have anything to do with the moat at all!), I added a pair of extra control points to the moat's smooth line to bring it closer to the 2 towers that sit either side of the entrance (the moat was built intentionally, right?).

Originally I was going to generate random buildings inside the castle and draw paths between them, the towers, the keep, and the entrance, but the maths behind that got rather complicated and I didn't have time to wrap my head around it. I was also going to generate random people in the castle too, but again I didn't have time for this. I'll probably come back to this at a later date and work on these features.

If this challenge looks interesting, then /r/proceduralgeneration are hosting another challenge this month - this time the challenge is to procedurally generate a side-scrolling platformer.

This blog now has a mailing list!

I've been meaning to add a mailing list to my blog here for a while now, and I've finally gotten around to writing one. After an afternoon's work, you can now subscribe here. Once you have subscribed, my blog will email you every time it releases a new post. Because of the way that I've implemented it, you'll still get an email when I mess up the date on posts that I write and quickly fix them again, although I'll try really hard not to do this :)

Fighting Spam on your blog

Since I have written my own blog script from scratch, I have learnt a lot about how spambots spam my site in order to implement measures to stop them. This post is a compilation of all the methods that I have discovered so far.

Currently I have yet to rate the effectiveness of each of these measures since at the time of writing this post I have only just finished rewiring the commenting script so that I can 'measure' the effectiveness of each of the methods described below.

Method 1: Honeypots

If you don't take either an email address or a web address on your blog, try adding a email or website field and hiding it via CSS. The more complex, indirect, and obscure the CSS you hide it with, the better. Just make sure that is actually hidden.

This blog uses a hidden website field along with a warning for users who see it due to poor browser support.

Method 2: No super long comments

This isn't really a proper method, but I found that spam comment on my blog were generally really long. So I am imposing a 2000 character limit on comments. If people have more to say, then they can reply to their own comment, and use service like pastebin or hastebin for code.

Method 3: Keys

This is the really important one. I was finding that while the above 2 methods were stopping some of the spam, I was getting some smart spambots with chrome/firefox-like user agent strings that I can only summarise knew how to tell whether a from control was hidden or not by reading the CSS or my website.

The hidden key field is basically a timestamp of when page was served to the user by the server. In it's simplest form, it can just be the output of PHP's time() function.

In this blog, however, the timestamp is run through a number of different functions, such as base64_encode() and strrev(). Pick a few string manipulation functions that are reversible.

This timestamp can then be analysed by the server. If the timestamp is too far in the past (say 24 hours old), or under 10 seconds old, then the comment is rejected. Spambots will either fetch and cache your page for longer than 24 hours, or they will fetch your page and post a comment immediately. As soon as I set this blog to reject comments posted within 10 seconds of loading the page, I haven't had a single spam comment :)

Summary

So there you go: 2 1/2 methods to banish spam on your blog - for now. The real secret here to log as much information about your commenters as possible (in my case I have been capturing the contents of $_POST, $_GET, and $_SERVER) and working your way through it comparing the requests of legitimate commenters and spammers. The above are simply exploits of the differences I found (with some help from Google). If you can think of any more tricks, please post a comment below!

Value vs Reference: A Performance Test

I have recently started to learned about classes and objects in C♯. In one of my lectures, Rob Miles mentioned that passing by reference introduced a slight performance hit, and I decided to test this.

Here is the code I used:

using System;
using System.Diagnostics;

class ValueVsReference
{
    public static void SetValue(int somenumber, int maxi)
    {
        for (int i = 0; i < maxi; i++)
        {
            somenumber = i;
        }
    }

    public static void SetReference(ref int somenumber, int maxi)
    {
        for(int i = 0; i < maxi; i++)
        {
            somenumber = i;
        }
    }

    public static void Main()
    {
        int iterations = 100000;
        int a = 0;
        Console.Write("Iterations: {0} ", iterations);

        Console.Write("Value: ");
        Stopwatch valuetime = new Stopwatch();
        valuetime.Start();
        SetValue(a, iterations);
        valuetime.Stop();
        Console.Write("{0} ", valuetime.Elapsed);

        Console.Write("Reference: ");
        Stopwatch referencetime = new Stopwatch();
        referencetime.Start();
        SetReference(ref a, iterations);
        referencetime.Stop();
        Console.WriteLine(referencetime.Elapsed);
    }
}

(gist: https://gist.github.com/sbrl/b10bf5c765630562431f)

The results for 10,000 iterations can be found in this pastebin.

Average times:

  • Value: 0.0000885
  • Reference: 0.00009295

Final result: References are indeed slower than values, by ~5% (100 - ((0.00009295/0.0000885)*100)). Normally you would not need to worry about this performance drop though since it is so small.

Coding Conundrums 1

This is the 50th post I have written for this blog! (There are a few posts scheduled to be released, so you may not be able to see posts #48 and #49 at the time of this post's release) This is also the first time I am trying to insert a post before two scheduled posts. Hopefully they come out in the right order.

Recently Rob Miles has released the first of a series of problem problems called "Coding Conundrums" with this tagline:

Number one in a series of more than one. Probably.

I have decided to write solutions for these problems and post them here on my blog for you. Each solution comes with it's associated description, a pastebin link, and a link to a compiled 32 bit binary (other types of binary are available, just ask in the comments).

1.1: Sequence Reversal

The challenge:

I want a program that reads in 10 numbers and prints them out in the reverse order to the order they were entered. I've no idea why I want this, I just do.

My solution:

using System;

class Program
{
    public static void Main(string[] args)
    {
        if(args.Length != 10)
        {
            Console.WriteLine("Coding Conundrums Problem 1.1 Solution: Sequence Reversal");
            Console.WriteLine("---------------------------------------------------------");
            Console.WriteLine("Problem Description:");
            Console.WriteLine("    I want a program that reads in 10 numbers and prints them out");
            Console.WriteLine("    in the reverse order to the order they were entered.");
            Console.WriteLine();
            Console.WriteLine("(You entered {0} numbers)", args.Length);
            Console.WriteLine();
            Console.WriteLine("Use it like this: ");
            Console.WriteLine("    sequencereverse.exe 1 2 3 4 5 6 7 8 9 10");

            return;
        }

        int[] numbers = new int[args.Length];
        for(int i = 0; i < args.Length; i++)
        {
            if(!int.TryParse(args[i], out numbers[i]))
            {
                Console.WriteLine("Error: {0} is not a number.", args[i]);
                return;
            }
        }
        Array.Reverse(numbers);

        for(int j = 0; j < numbers.Length; j++)
        {
            Console.Write("{0} ", numbers[j]);
        }
        Console.WriteLine();
    }
}

(Pastebin, 32 bit Binary)

1.2: Number Shuffle

Problem Description:

I want a program that will print outthe numbers 1,2,3,4,5,6,7,8,9 in a shuffled order. The order must be different each time the program runs. Note that the same number must be different each time. It should be possible to extend this to work with 52 numbers, in which case I can make a shuffled deck of cards.

My solution:

using System;

class Program
{
    public static void PrintHelp()
    {
        Console.WriteLine("Coding Conundrums Problem 1.2 Solution: Number Shuffle");
        Console.WriteLine("------------------------------------------------------");
        Console.WriteLine("Problem Description:");
        Console.WriteLine("    I want a program that will print outthe numbers 1,2,3,4,5,6,7,8,9 in a");
        Console.WriteLine("    shuffled order. The order must be different each time the program runs. Note");
        Console.WriteLine("    that the same number must be different each time. It should be possible to");
        Console.WriteLine("    extend this to work with 52 numbers, in which case I can make a shuffled");
        Console.WriteLine("    deck of cards.");
        Console.WriteLine();
        Console.WriteLine("Use it like this: ");
        Console.WriteLine("    numbershuffle.exe <count-to>");
        Console.WriteLine();
        Console.WriteLine("Paramters:");
        Console.WriteLine("    <count-to>: The number to count up to when generating the initial sequence of numbers.");
    }

    public static void Main(string[] args)
    {
        if(args.Length != 1)
        {
            PrintHelp();
            return;
        }

        int numberCount;
        if(!int.TryParse(args[0], out numberCount))
        {
            PrintHelp();
            return;
        }

        int[] numbers = new int[numberCount];
        for(int i = 0; i < numberCount; i++)
        {
            numbers[i] = i + 1;
        }

        int swapsCount = numberCount * 2;
        int temp, a, b;
        Random random = new Random();
        for(int i = 0; i < swapsCount; i++)
        {
            a = random.Next(numbers.Length);
            b = random.Next(numbers.Length);

            temp = numbers[a];
            numbers[a] = numbers[b];
            numbers[b] = temp;
        }

        for(int i = 0; i < numbers.Length; i++)
        {
            Console.Write("{0} ", numbers[i]);
        }
    }
}

(pastebin, 32 bit binary)

1.3: Shoe Popularity Contest

Problem Description:

I want a program that reads in 20 integers and tells me how much of each number was entered. I actually have a use for this, in that each day I sell 20 pairs of shoes and I want to find out the most popular shoe sizes

My solution:

I looked up and used a C♯ Dictionary for this one.

using System;
using System.Collections.Generic;

class Program
{
    public static void PrintHelp()
    {
        Console.WriteLine("Coding Conundrums Problem 1.2 Solution: Number Shuffle");
        Console.WriteLine("------------------------------------------------------");
        Console.WriteLine("Problem Description:");
        Console.WriteLine("    I want a program that reads in 20 integers and tells me how much of each number");
        Console.WriteLine("    was entered. I actually have a use for this, in that each day I sell 20 pairs of");
        Console.WriteLine("    shoes and I want to find out the most popular shoe sizes. It's amazing that I");
        Console.WriteLine("    manage to hold down my lecturing job, what with all the shoe sales I'm involved");
        Console.WriteLine("    with.");
        Console.WriteLine();
        Console.WriteLine("Use it like this: ");
        Console.WriteLine("    shoesales.exe");
    }

    ///<summary>
    ///Gets an integer from the user between min and max inclusive.
    ///</summary>
    ///<param name="prompt">The prompt to display to the user.</param>
    ///<param name="min">The minimum value the user should enter.</param>
    ///<param name="max">The maximum value the user should enter.</param>
    static int ReadNumber(string prompt, int min, int max)
    {
        int number;
        while (true)
        {
            Console.Write(prompt);
            try
            {
                number = int.Parse(Console.ReadLine().Trim());
            }
            catch
            {
                Console.WriteLine("That was not a number. Numbers may contain numeric characters only.");
                continue;
            }

            if (number < min)
            {
                Console.WriteLine("That number was too low. Please enter a number between " + min + " and " + max + ".");
                continue;
            }
            if (number > max)
            {
                Console.WriteLine("That number was too high. Please enter a number between " + min + " and " + max + ".");
                continue;
            }

            break;
        }

        return number;
    }

    public static void PrintShoeSizes(Dictionary<int, int> shoes)
    {
        Console.WriteLine("Shoe Sizes:");
        Console.WriteLine("-----------");
        Console.WriteLine("Size     Count");
        foreach(KeyValuePair<int, int> shoeSize in shoes)
        {
            Console.WriteLine("{0,-8} {1}", shoeSize.Key, shoeSize.Value);
        }
    }

    public static void Main(string[] args)
    {
        if(args.Length == 1 && args[0].ToLower().Trim('-') == "help")
        {
            PrintHelp();
            return;
        }

        int shoeTotal = 20;

        Dictionary<int, int> shoes = new Dictionary<int, int>();
        for(int i = 0; i < shoeTotal; i++)
        {
            PrintShoeSizes(shoes);
            int currentShoeSize = ReadNumber(String.Format("Enter the shoe size #{0}: ", i + 1), 1, 12);

            if(!shoes.ContainsKey(currentShoeSize))
            {
                shoes.Add(currentShoeSize, 1);
            }
            else
            {
                shoes[currentShoeSize] += 1;
            }
        }
    }
}

(pastebin, 32 bit binary)

Art by Mythdael