private void OnStartGame(object sender, ExecutedRoutedEventArgs e)
 {
     BombCount = (int)((Rows * Columns) * (Difficulty / 10d));
     _gameRules = GameRules.NewGame(Rows, Columns, BombCount);
     // HACK: force update crap (as well as before timer starts)
     OnPropertyChanged("MineField");
     IsGameConfigEnabled = false;
     CheckCurrentGameState();
 }
 internal static GameRules NewGame(int rows, int cols, int bombCount)
 {
     // lets fill out a new chunk of state for someone
     var newGameRules = new GameRules
     {
         GameField  = new ObservableCollection<FieldSpot>(CreateNewField(rows, cols)),
         BombCount   = bombCount,
         Rows        = rows,
         Columns     = cols
     };
     SpreadSomeBombs(newGameRules);
     newGameRules.GameState = GameState.Initialized;
     return newGameRules;
 }
        public MineSweeperViewModel(MainView owner)
        {
            _owner = owner;
            _owner.CommandBindings.Add(new CommandBinding(FieldSelectedCommand, OnFieldSelected, CanFieldSelectExecute));
            _owner.CommandBindings.Add(new CommandBinding(FieldFlaggedCommand, OnFieldFlagged, CanFieldSelectExecute));
            _owner.CommandBindings.Add(new CommandBinding(StartGameCommand, OnStartGame));
            _owner.CommandBindings.Add(new CommandBinding(ResetGameCommand, OnForceResetGame));
            _uiTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(UI_UPDATE_RATE_MS), DispatcherPriority.Background, OnUiUpdateTimerTick, _owner.Dispatcher);

            // give some defaults here for initial window load to not be empty
            Difficulty = 1;
            Rows = 8;
            Columns = 8;
            BombCount = 5;
            _gameRules = GameRules.NewGame(Rows, Columns, BombCount);
            // kick off a fresh game
            ResetGame();
        }
        //private static FieldSpot FieldAt(IEnumerable<FieldSpot> fields, int row, int col) { return fields != null ? fields.FirstOrDefault(f => f.Row == row && f.Column == col) : null;  }
        //private FieldSpot FieldAt(int row, int col) { return GameField != null ? GameField.FirstOrDefault(f => f.Row == row && f.Column == col) : null;  }
        private static void SpreadSomeBombs(GameRules gameRules)
        {
            Debug.Assert(gameRules != null);
            Random rand = new Random((int)DateTime.Now.Ticks); // loss of precision is intentional here
            List<Point> usedLocations = new List<Point>();

            for (int i = 0; i < gameRules.BombCount; i++)
            {
                Point newBombPoint;
                while (usedLocations.Contains(newBombPoint = new Point(rand.Next(gameRules.Rows), rand.Next(gameRules.Columns))) && usedLocations.Count < gameRules.BombCount)
                {
                    // generate a unique point
                }

                int scalarX = (int)newBombPoint.X;
                int scalarY = (int)newBombPoint.Y;
                usedLocations.Add(newBombPoint);
                var field =  gameRules.GameField.FirstOrDefault(f => f.Row == scalarX && f.Column == scalarY);
                if (field != null)
                    field.IsBomb = true;
            }
        }