AdSense

Friday 31 October 2014

Get to work Arduino Nano V3.0 Clone with CH340G

At Ebay you can buya clone of the Arduino Nano for less than 3 Euro. Often it can be found under names like  "Nano V3.0 ATmega328 CH340G" with the addition "for Arduino" or "Arduino compatible", for example here.

These clones don't use a FT232R as USB-Serial converter  like the "original". The use a CH340G (as you can guess), so the drivers of the Arduino IDE won't work with the clone. You have to install a special driver on your own. You can download it here from the manufacturer. There are also drivers for MAC und Linux but I will only explain how to install the driver for Windows. At first, you have to extract the ZIP archive. If you use Windows 64bit, you have to copy the file "DRVSETUP64.exe" from the folder "DRVSETUP64" to its parent folder which contains (amongst others) the file "CH341SER.INF". Depending on your system you then have to run "SETUP.EXE" (32bit) or "DRVSETUP64.exe" (64bit). Click "INSTALL" and the driver is beeing installed. The Arduino board MUST NOT be connected to your computer, when you install the driver. Connect the Arduino AFTER the successful installation. Windows will then recognize it.

Sunday 5 October 2014

C# - Program to solve a sudoku

(Deutsche Version) To solve a sudoku by hand is not that difficult. But after some time, a programmer wants to write a program which can also do this. The basic principle is pretty easy. The first empty bracket is filled (with a 1). Afterwards, the program checks whether the sudoku is still correct. If so, the next bracket is filled, if not, the previous bracket is counted up about 1. This is continued until the Sudoku is completely filled.

First, I created a window which shows a sudoku:

<Window x:Class="SudokuSolver.SudokuShowWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SudokuShowWindow" Height="550" Width="550">
    <Grid Name="Grid1" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="50"></ColumnDefinition>
            <ColumnDefinition Width="50"></ColumnDefinition>
            <ColumnDefinition Width="50"></ColumnDefinition>
            <ColumnDefinition Width="50"></ColumnDefinition>
            <ColumnDefinition Width="50"></ColumnDefinition>
            <ColumnDefinition Width="50"></ColumnDefinition>
            <ColumnDefinition Width="50"></ColumnDefinition>
            <ColumnDefinition Width="50"></ColumnDefinition>
            <ColumnDefinition Width="50"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
        </Grid.RowDefinitions>

    </Grid>
</Window>

And the corresponding code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace SudokuSolver
{
    /// <summary>
   /// Interaktionslogik für SudokuShowWindow.xaml
    /// </summary>
    public partial class SudokuShowWindow : Window
    {
        public SudokuShowWindow()
        {
            InitializeComponent();
        }

        public int[] numbers;
        public TextBlock[] TextBlocks;

        public void refreshValues(int[] _numbers)
        {
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    if (_numbers[i * 9 + j] != numbers[i * 9 + j])
                    {

                        TextBlocks[i * 9 + j].Text = _numbers[i * 9 + j].ToString();
                    }
                }
            }
        }

        public static SudokuShowWindow newSudokuShowWindow(int[] numbers)
        {
            SudokuShowWindow window = new SudokuShowWindow();
            window.numbers = new int[81];
            window.TextBlocks = new TextBlock[81];
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    window.numbers[i * 9 + j] = numbers[i * 9 + j];
                    TextBlock tb = new TextBlock();
                    tb.Text = numbers[i * 9 + j].ToString();
                    tb.HorizontalAlignment = HorizontalAlignment.Center;
                    tb.VerticalAlignment = VerticalAlignment.Center;
                    Grid.SetRow(tb, i);
                    Grid.SetColumn(tb, j);

                    Thickness thk = new Thickness(0, 0, 0, 0);
                    if (i == 2 || i == 5)
                    {
                        thk.Bottom = 1;
                    }
                    if (i == 3 || i == 6)
                    {
                        thk.Top = 1;
                    }
                    if (j == 2 || j == 5)
                    {
                        thk.Right = 1;
                    }
                    if (j == 3 || j == 6)
                    {
                        thk.Left = 1;
                    }
                    Border border = new Border();
                    border.BorderThickness = thk;
                    border.BorderBrush = Brushes.Black;
                    Grid.SetRow(border, i);
                    Grid.SetColumn(border, j);

                    window.Grid1.Children.Add(border);
                    window.Grid1.Children.Add(tb);

                    window.TextBlocks[i * 9 + j] = tb;
                }
            }
            window.Show();
            return window;
        }


    }
}

This is now used to show the sudoku. The solver shows the actual sudoku and opens a new window for every found solution. MainWindow is empty, it is just used to start the program.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SudokuSolver
{
    /// <summary>
   /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Thread thread = new Thread(workLoop);
            thread.Start();
        }

        private SudokuShowWindow window;
        private int numberCounter;
        private int[] initialNumbers;
        private int[] numbers;
        List<int[]> Solutions = new List<int[]>();

        private void workLoop()
        {
            //The initial Sudoku which should be solved
            initialNumbers = new int[81]
            {
                5,3,0,   0,7,0,   0,0,0,
                6,0,0,   1,9,5,   0,0,0,
                0,9,8,   0,0,0,   0,6,0,

                8,0,0,   0,6,0,   0,0,3,
                4,0,0,   8,0,3,   0,0,1,
                7,0,0,   0,2,0,   0,0,6,

                0,6,0,   0,0,0,   2,8,0,
                0,0,0,   4,1,9,   0,0,5,
                0,0,0,   0,8,0,   0,7,9
            };
            numbers = new int[81];
            for (int i = 0; i < 81; i++)
            {
                numbers[i] = 0;
            }

            //Invoke window actions because we are not in the main thread
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                window = SudokuShowWindow.newSudokuShowWindow(initialNumbers);
            }));

            //Position of the "cursor" in the sudoku
            numberCounter = 0;

            int ctr = 0;
            bool noi = false;


            while (true)
            {
                if (isItValid())
                {
                    noi = false;

                    //A valid solution!
                    if (numberCounter > 80)
                    {
                        int[] totalNumbers = new int[81];
                        for (int i = 0; i < 81; i++)
                        {
                            totalNumbers[i] = initialNumbers[i];
                            if (totalNumbers[i] == 0)
                            {
                                totalNumbers[i] = numbers[i];
                            }
                        }

                        bool eq = false;
                        foreach (int[] solution in Solutions)
                        {
                            bool leq = true;
                            for (int i = 0; i < 81; i++)
                            {
                                if (solution[i] != totalNumbers[i])
                                {
                                    leq = false;
                                }
                            }
                            if (leq)
                            {
                                eq = true;
                            }

                        }
                        if (!eq)
                        {
                            int[] tmp = new int[81];
                            for (int i = 0; i < 81; i++)
                            {
                                tmp[i] = totalNumbers[i];
                            }
                            Solutions.Add(tmp);
                        }
                        else
                        {
                            System.Console.WriteLine("Done!");
                            break;
                        }

                        Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            SudokuShowWindow.newSudokuShowWindow(totalNumbers);
                        }));

                        //Check for other solutions?

                        noi = true;
                        while (true)
                        {
                            numberCounter--;
                            if (initialNumbers[numberCounter] == 0)
                            {
                                if (numbers[numberCounter] >= 9)
                                {
                                    numbers[numberCounter] = 0;
                                }
                                else
                                {
                                    numbers[numberCounter]++;
                                    break;
                                }
                            }
                        }
                    }

                    if (numberCounter > 80)
                    {
                        break;
                    }

                    if (numbers[numberCounter] == 0 && initialNumbers[numberCounter] == 0)
                    {
                        iterateOne();
                    }
                    else
                    {
                        if (!noi)
                        {
                            increaseNumberCounter();
                        }
                    }
                }
                else
                {
                    if (numberCounter > 80 || numberCounter < 0)
                    {
                        break;
                    }
                    if (numbers[numberCounter] >= 9)
                    {
                        decreaseOne();
                        Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            int[] totalNumbers = new int[81];
                            for (int i = 0; i < 81; i++)
                            {
                                totalNumbers[i] = initialNumbers[i];
                                if (totalNumbers[i] == 0)
                                {
                                    totalNumbers[i] = numbers[i];
                                }
                            }
                            window.refreshValues(totalNumbers);
                        }));

                    }
                    else
                    {
                        iterateOne();
                    }
                }
                ctr++;
                if (ctr > 1000)
                {
                    ctr = 0;
                    Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        int[] totalNumbers = new int[81];
                        for (int i = 0; i < 81; i++)
                        {
                            totalNumbers[i] = initialNumbers[i];
                            if (totalNumbers[i] == 0)
                            {
                                totalNumbers[i] = numbers[i];
                            }
                        }
                        window.refreshValues(totalNumbers);
                    }));
                    Thread.Sleep(1);
                }
            }
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                window.Close();
            }));
        }

        void increaseNumberCounter()
        {
            numberCounter++;
            while (numberCounter <= 80 && initialNumbers[numberCounter] != 0)
            {
                numberCounter++;
            }
        }

        void iterateOne()
        {
            if (numberCounter > 80)
            {
                return;
            }
            while (initialNumbers[numberCounter] != 0)
            {
                numberCounter++;
            }
            numbers[numberCounter]++;
        }

        void decreaseOne()
        {
            if (numberCounter > 80)
            {
                numberCounter = 80;
            }
            numbers[numberCounter] = 0;
            if (numberCounter == 0)
            {
                return;
            }

            while (numberCounter >= 0)
            {
                numberCounter--;
                while (numberCounter > 0 && initialNumbers[numberCounter] != 0)
                {
                    numberCounter--;
                }
                if (numberCounter < 0)
                {
                    return;
                }
                if (numbers[numberCounter] < 9)
                {
                    numbers[numberCounter]++;
                    return;
                }
                else
                {
                    numbers[numberCounter] = 0;
                }
            }
        }

        bool isItValid()
        {
            int[] totalNumbers = new int[81];
            for (int i = 0; i < 81; i++)
            {
                totalNumbers[i] = initialNumbers[i];
                if (totalNumbers[i] == 0)
                {
                    totalNumbers[i] = numbers[i];
                }
            }
            //Check Horizontal
            List<int> testList;
            for (int i = 0; i < 9; i++)
            {
                testList = new List<int>();
                for (int j = 0; j < 9; j++)
                {
                    if (testList.Contains(totalNumbers[i * 9 + j]))
                    {
                        //Invalid
                        return false;
                    }
                    if (totalNumbers[i * 9 + j] != 0)
                    {
                        testList.Add(totalNumbers[i * 9 + j]);
                    }
                }
            }

            //Check Vertical
            for (int j = 0; j < 9; j++)
            {
                testList = new List<int>();
                for (int i = 0; i < 9; i++)
                {
                    if (testList.Contains(totalNumbers[i * 9 + j]))
                    {
                        //Invalid
                        return false;
                    }
                    if (totalNumbers[i * 9 + j] != 0)
                    {
                        testList.Add(totalNumbers[i * 9 + j]);
                    }
                }
            }
            //Check squares
            for (int ii = 0; ii < 3; ii++)
            {
                for (int jj = 0; jj < 3; jj++)
                {
                    testList = new List<int>();
                    for (int i = ii * 3; i < ii * 3 + 3; i++)
                    {
                        for (int j = jj * 3; j < jj * 3 + 3; j++)
                        {
                            if (testList.Contains(totalNumbers[i * 9 + j]))
                            {
                                //Invalid
                                return false;
                            }
                            if (totalNumbers[i * 9 + j] != 0)
                            {
                                testList.Add(totalNumbers[i * 9 + j]);
                            }
                        }
                    }
                }
            }
            //Valid
            return true;
        }
    }
}

Visual Studio - Application with automatic updates takes long until startup

(Deutsche Version) If you publish a project in Visual Studio and then start the application, at first the application looks for updates. This can take a lot of time and is annoying if you want to have the application as fast as possible. Luckily you can set the moment of the updates so the application only looks for updates after it has started. At the next startup, you can install the updates without having to wait too much.

To set this, you have to go to the project properties. There is a submenu "Publish" with the Button "Updates". Here you have the wanted setting: "Choose when the application should check for updates". Usually, "Before the application starts" is selected, to shorten the startup time, you have to choose "After the application starts".

Show disk space usage clearly arranged - WinDirStat

(Deutsche Version) With increasing data volume, it gets harder to keep track of all your data and so it can easily happen that the hard drive is full and you don't know which files are responsible for this. To face this problem, there is a useful program: WinDirStat.

This program shows the disk space usage of a partition clearly arranged as you can see in the following image:
You can now select folders and a white border will appear around the disk usage of the whole folder. Every file is represented by a rectangle so you can easily spot big files. Personally, I deleted lots of gigabytes of unnecessary files and can recommend this program to everyone.