/// <summary>
        /// Thread body which performs one game loop step and renders map to buffer.
        /// </summary>
        private void PerformGameLoopStep(object sender, EventArgs e)
        {
            // game loop steps per second
            double gsps = 10;

            // milliseconds per game loop step
            double mspgs = 1000.0 / gsps;

            // last time game loop step was performed
            double lastTime = lastTimeGameLoopStep;

            GameViewModel gameView = viewModel;

            //current time
            double currentTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;

            // lock game view, perform game loop step and pass task with data context update
            if ((currentTime - lastTime) >= mspgs)
            {
                while (!Monitor.TryEnter(gameView))
                {
                    Thread.Sleep(100);
                }
                try
                {
                    gameView.GameLoopStep();
                } catch (Exception ex)
                {
                    // todo: something
                }

                bool winner = gameView.GameInstance.IsWinner;
                if (gameView.GameInstance.IsWinner)
                {
                    ((DispatcherTimer)sender).Stop();
                    viewModel.AddGameMessage($"Player {gameView.GameInstance.Winner.Name} has won!");
                }
                lastTimeGameLoopStep = currentTime;
                Application.Current.Dispatcher.Invoke(() => {
                    viewModel   = gameView;
                    DataContext = viewModel;
                    gameView.NotifyPropertyChanges();
                    if (winner)
                    {
                        OnGameEnded();
                    }
                });
                Monitor.Exit(gameView);
            }
        }