//Check the word is within the bounds of the grid. public bool checkHorizontalWordFitsGrid(WordData word, int startPointX, int startPointY) { if (startPointX < 0) { return(false); } if (startPointX + word.Length <= columnSize) { return(true); } else { return(false); } }
//Check each word in the grid has a valid number of intersections. //This method can be easily adapted to suit your needs. public bool checkGridIntersections(WordData word, int startPointX, int startPointY, int direction) { //Add the word to the crozzle map. crozzleMap.addWord(word, startPointX, startPointY, direction); Coord[,] grid = crozzleMap.GameGrid; int maxIntersetions = 2; bool isValid = true; foreach (WordData placedWord in wordsInGrid) { int intersectionCount = 0; for (int i = 0; i < placedWord.Length; i++) { if (placedWord.Direction == Constants.HORIZONTAL_WORD) { //Check if X and Y is true for the coordinate, if both true an intersection exists. if (grid[placedWord.Y, placedWord.X + i].X && grid[placedWord.Y, placedWord.X + i].Y) { //Increment the intersection count. intersectionCount++; } } else if (placedWord.Direction == Constants.VERTICAL_WORD) { if (grid[placedWord.Y + i, placedWord.X].X && grid[placedWord.Y + i, placedWord.X].Y) { intersectionCount++; } } } //Check if there is a valid number of intersections. if (intersectionCount > maxIntersetions) { isValid = false; } } //Remove the word from the tracking grid, it will be officially added when the word is added to the grid later. crozzleMap.removeWord(word, startPointX, startPointY, direction); return(isValid); }
public bool checkTouchingVerticalWords(WordData word, int connectPointX, int connectPointY) { bool isValid = true; foreach (WordData wordInGrid in wordsInGrid) { if (wordInGrid.Direction == Constants.VERTICAL_WORD) { if (wordInGrid.X >= connectPointX - 1 && wordInGrid.X <= connectPointX + 1) { if (wordInGrid.Y < connectPointY - 1 && wordInGrid.Y + wordInGrid.Length >= connectPointY) { isValid = false; } else if (wordInGrid.Y >= connectPointY - 1 && wordInGrid.Y <= connectPointY + word.Length) { isValid = false; } } } } return(isValid); }
//Methods. public void addWord(WordData word) { words.Add(word); wordCount++; }
private WordData createConnectingWordPlacement(WordData previousWord) { WordData optimalWord = null; char[] previousWordCharArray = previousWord.Text.ToCharArray(0, previousWord.Length); //Iterate over all words in the word list. foreach (WordData word in completeWordList) { //Check if grid already contains the word. if (!crozzleGrid.WordsInGrid.listContains(word)) { //Iterate through letters of the previously placed word. for (int previousWordIndex = 0; previousWordIndex < previousWordCharArray.Length; previousWordIndex++) { //Iterate through the letters of the current word. for (int wordIndex = 0; wordIndex < word.Length; wordIndex++) { //If the two words share a letter. if (word.Text[wordIndex] == previousWordCharArray[previousWordIndex]) { int wordLeftHalfSize; //Calculate the size of the left half of the word, to ensure when place within the grid //it doesnt exceed x < 0. if (wordIndex > 0) { wordLeftHalfSize = wordIndex; } else { wordLeftHalfSize = 0; } if (previousWord.Direction == Constants.HORIZONTAL_WORD) { //Check the word fits within the grid. if (crozzleGrid.checkVerticalWordFitsGrid(word, previousWord.X + previousWordIndex, previousWord.Y - wordLeftHalfSize)) { //If the word intersects any other words place on the grid ensure the intersecting letters match. if (crozzleGrid.checkVerticalWordPath(word, previousWord.X + previousWordIndex, previousWord.Y - wordLeftHalfSize)) { //Check there is a valid amount of space around the word, (i.e. conforms to game spacing rules. if (crozzleGrid.checkTouchingVerticalWords(word, previousWord.X + previousWordIndex, previousWord.Y - wordLeftHalfSize)) { if (crozzleGrid.checkGridIntersections(word, previousWord.X + previousWordIndex, previousWord.Y - wordLeftHalfSize, Constants.VERTICAL_WORD)) { //Check the word is at least 4 characters in length (this is to ensure maximum connectivity is possible for future words that are to short //decrease the change for future connectivity). Smaller words can be added later in another optimisation type of method, smaller words should //however be added last (this is a heuristic rule I came up with). //These statements (vertical aswell) here can and should be tweaked to get the best possible solution according to your set of rules. if (optimalWord == null || word.Length >= 4) { optimalWord = word.getCopy(); optimalWord.X = previousWord.X + previousWordIndex; optimalWord.Y = previousWord.Y - wordLeftHalfSize; optimalWord.Direction = Constants.VERTICAL_WORD; } } } } } } else if (previousWord.Direction == Constants.VERTICAL_WORD) { if (crozzleGrid.checkHorizontalWordFitsGrid(word, previousWord.X - wordLeftHalfSize, previousWord.Y + previousWordIndex)) { if (crozzleGrid.checkHorizontalWordPath(word, previousWord.X - wordLeftHalfSize, previousWord.Y + previousWordIndex)) { if (crozzleGrid.checkTouchingHorizontalWords(word, previousWord.X - wordLeftHalfSize, previousWord.Y + previousWordIndex)) { if (crozzleGrid.checkGridIntersections(word, previousWord.X - wordLeftHalfSize, previousWord.Y + previousWordIndex, Constants.HORIZONTAL_WORD)) { if (optimalWord == null || word.Length >= 4) { optimalWord = word.getCopy(); optimalWord.X = previousWord.X - wordLeftHalfSize; optimalWord.Y = previousWord.Y + previousWordIndex; optimalWord.Direction = Constants.HORIZONTAL_WORD; } } } } } } } } } } } return(optimalWord); }