private void NewGame(CrosswordSize size = CrosswordSize.UsePrevious) { activeCrossword.GenerateNewCrossword(size); RemakeTable(); RemakeWords(); }
public void GenerateNewCrossword(CrosswordSize newSize = CrosswordSize.UsePrevious) { if (newSize != CrosswordSize.UsePrevious) { size = newSize; } switch (size) { case CrosswordSize.Small: SizeX = SizeY = 17; break; case CrosswordSize.Normal: SizeX = SizeY = 24; break; case CrosswordSize.Large: SizeX = SizeY = 31; break; case CrosswordSize.VeryLarge: SizeX = SizeY = 45; break; } words.Clear(); if (initialWords.Count < 4) { MessageBox.Show("Not enough words left for a new crossword. Reloading wordlist file.", "", MessageBoxButtons.OK, MessageBoxIcon.Warning); InitialiseFromFile(); } const float GenerationComplexityFactor = 2.0f; blocks = new IBlock[SizeX, SizeY]; int InitialSizeWords = initialWords.Count; Random r = new Random(); DateTime timeStart = DateTime.Now; // Place first word at random bool Placed = false; while (!Placed) { int x = r.Next((int)Math.Ceiling(SizeX * 0.30), (int)Math.Floor(SizeX * 0.70)); int y = r.Next((int)Math.Ceiling(SizeY * 0.30), (int)Math.Floor(SizeY * 0.70)); int index = r.Next(initialWords.Count); Word w = GenerateWord(index, r); if (TryPlace(w, new Point(x, y), 0)) { initialWords.RemoveAt(index); Placed = true; } } int LoopsWithoutProgress = 0; float GenerationFactor = InitialSizeWords * GenerationComplexityFactor; int SingleIntersectionCount = 0; while (initialWords.Count > 0 && LoopsWithoutProgress < GenerationFactor) { int wordsPlaced = InitialSizeWords - initialWords.Count; float wordsPlacedPercent = wordsPlaced / InitialSizeWords; int index = r.Next(initialWords.Count); Word w = GenerateWord(index, r); int minIntersections = 1; if (wordsPlaced < 3) { if (w.GetCorrectWord().Length > 5) { minIntersections = 1; } else { continue; } } else if (LoopsWithoutProgress < GenerationFactor * 0.1) { minIntersections = 4; } else if (LoopsWithoutProgress < GenerationFactor * 0.3) { minIntersections = 3; } else if (LoopsWithoutProgress < GenerationFactor * 0.9) { minIntersections = 2; } else { minIntersections = 1; } LoopsWithoutProgress++; if (TryPlaceEverywhere(w, minIntersections, r)) { if (minIntersections == 1) { SingleIntersectionCount++; } LoopsWithoutProgress = 0; initialWords.RemoveAt(index); } } TimeSpan ts = DateTime.Now - timeStart; int ms = (int)ts.TotalMilliseconds; if (ms > 3000) { MessageBox.Show("Took " + ms + "ms to make this crossword.", "", MessageBoxButtons.OK, MessageBoxIcon.Information); } // Fill empty blocks for (int row = 0; row < blocks.GetLength(0); row++) { for (int col = 0; col < blocks.GetLength(1); col++) { if (blocks[row, col] == null) { blocks[row, col] = new BlackBlock(); } } } }