/// <summary> /// Конструктор, инициализирующий элементы класса /// </summary> /// <param name="cells">Игровое поле</param> public Model(DeskOfCells cells) { if (!cells.IsCorrect()) { throw new ArgumentException("Wrong cells Length!"); } _cells = cells; }
/// <summary> /// Конструктор, инициализирующий компоненты данного класса /// </summary> /// <param name="allCells">Игровое поле</param> public ViewModel(DeskOfCells allCells) { model = new Model(allCells); model.PropertyChanged += Model_PropertyChanged; List <Cell> cells = new List <Cell>(); foreach (Cell cell in model.Cells) { cells.Add(cell); } Cells = cells; RestartCommand = new RelayCommand(par => model.Cells.Clear()); RulesCommand = new RelayCommand(par => MessageBox.Show(ConstValues.Rules, "Правила игры")); }
/// <summary> /// Конструктор, инициализирующий компоненты данного элемента управления /// </summary> /// <param name="cells">Игровое поле</param> /// <param name="isGenerated">Сгенерированно ли поле</param> public View(DeskOfCells cells, bool isGenerated) { InitializeComponent(); IsGenerated = isGenerated; cells.AmountOfTrials = (cells.AmountOfTrials != 0) ? cells.AmountOfTrials : ((cells.Difficulty == LevelDifficultyEnum.Beginner) ? 5 : ((cells.Difficulty == LevelDifficultyEnum.Improving) ? 4 : 3)); DataContext = new ViewModel(cells); trialsTextBlock.Text = ConstValues.TrialsText + ((ViewModel)DataContext).Mod.Cells.AmountOfTrials; miniRulesTextBlock.Text = ConstValues.MiniRulesText; records = Records.RecordDeserializer(); }
/// <summary> /// Конструктор, инициализирующий компоненты класса, /// а также запускает отсчет таймера /// </summary> /// <param name="cells">Класс - игровое поле</param> /// <param name="isGenerated">Сгенерированно ли поле</param> public GameWindow(DeskOfCells cells, bool isGenerated) { InitializeComponent(); if (File.Exists(ConstValues.LightHousePath)) { try { Icon = new BitmapImage(new Uri(ConstValues.LightHousePath, UriKind.Relative)); } catch (Exception) { } } if (!cells.IsClear()) { MessageBoxResult res = MessageBox.Show(ConstValues.ContinueLastGame, ConstValues.ContinueTitle, MessageBoxButton.YesNo); if (res == MessageBoxResult.No) { cells.Clear(); cells.TimeStart = 0; cells.AmountOfTrials = (cells.Difficulty == LevelDifficultyEnum.Beginner) ? 5 : ((cells.Difficulty == LevelDifficultyEnum.Improving) ? 4 : 3); } } else { cells.TimeStart = 0; } timer = new DispatcherTimer(); timer.Tick += new EventHandler(Timer_Tick); timer.Interval = new TimeSpan(0, 0, 1); timer.Start(); TimeNow = cells.TimeStart; timerTextBlock.Text = "0:00:00"; viewModelControl.Content = new View(cells, isGenerated); }
/// <summary> /// Генерирует поля размера fieldSize x fieldSize /// </summary> /// <param name="fieldSize">Размер поля</param> /// <returns>Сгенерированное поле</returns> public static DeskOfCells Generator(int fieldSize) { // Экземпляр класса, в который будет записано сгенерированное поле DeskOfCells cells = new DeskOfCells("Головоломка", fieldSize); // Коллекция объектов, хранящее числа, отвечающие за некоторую клетку поля List <int> allElements = new List <int>(fieldSize * fieldSize); // Коллекция, хранящяя места, где точно не может быть кораблика HashSet <int> crosses = new HashSet <int>(); // Заполнение коллекции числами от 0 до (размер поля)^2 для различия элементов for (int i = 0; i < fieldSize * fieldSize; i++) { allElements.Add(i); } // Цикл, отвечающий за генерацию корабликов на поле for (int i = 0; i < fieldSize; i++) { // Выбор случайного элемента из allElements int num = rnd.Next(allElements.Count); // Добавление кораблика в поле на место, // соответствующее выбраннному элементу int row = allElements[num] / fieldSize, column = allElements[num] % fieldSize; cells[row, column].Value = CellValueEnum.Boat; // Исключение из allElements элементов, соответствующих // кораблику и соседним с ним клеткам (крестикам) AddCrosses(fieldSize, allElements, num, crosses); } // Выбор количества маяков, которые будут сгенерированы int amountOfLighthouses = rnd.Next((int)(fieldSize * 8 / 10), fieldSize + 1); // Цикл, отвечающий за генерацию маяков на поле for (int i = 0; i < amountOfLighthouses; i++) { // Выбор случайного элемента из allElements int num = rnd.Next(allElements.Count); // Добавление маяка в поле на место, // соответствующее выбраннному элементу int row = allElements[num] / fieldSize, column = allElements[num] % fieldSize; cells[row, column].Value = CellValueEnum.Lighthouse; cells[row, column].AmountOfLightedBoats = cells.CountBoats(row, column); // Исключение из allElements элементов, соответствующих // маяку и соседним с ним клеткам (крестикам) AddCrosses(fieldSize, allElements, num, crosses); // Удаление из allElements элементов, находящихся на одной вертикали // или диагонали для исключения возможности пересечения двух маяков for (int j = 0; j < fieldSize; j++) { allElements.Remove(row * fieldSize + j); allElements.Remove(j * fieldSize + column); } // Выход из цикла при недостатке свободных мест if (allElements.Count == 0) { break; } } // Создание коллекции с элементами, соответствующими всем полям, // кроме корабликов и маяков, а также выбор количества мелей на поле List <int> unusedCells = (from el1 in allElements select el1).Concat (from el2 in crosses select el2).ToList(); int amountOfUnavailable = rnd.Next((int)(unusedCells.Count / 8)); // Добавление мелей на поле for (int i = 0; i < amountOfUnavailable; i++) { // Выбор случайного элемента из unusedElements int num = rnd.Next(unusedCells.Count); // Добавление мели в поле на место, // соответствующее выбраннному элементу int row = unusedCells[num] / fieldSize, column = unusedCells[num] % fieldSize; cells[row, column].Value = CellValueEnum.Unavailable; // Удаление из unusedElevents элемента, соответствующего мели unusedCells.Remove(unusedCells[num]); } // Удаление мелей вокруг маяков foreach (var el in cells) { if (el.Value == CellValueEnum.Lighthouse) { cells.MakeCrosses(el.Row, el.Column); } } // Очистка поля от корабликов и маяков и возвращение результата cells.Clear(); return(cells); }