/// <summary> /// Returns list of moves that can be done with a specific hand /// </summary> /// <param name="board">string array of letters on the board for that</param> /// <param name="hand">List of length 1 strings in the player's hand</param> /// <param name="rowOrCol">Position</param> /// <param name="col">True if it runs up/down</param> /// <returns>List of moves, formed in an array [string word, int[1,1] position, bool NorthSouth]</returns> public List <Move> GetMovesInArray(ScrabbleBoard board, List <string> hand, string[] rowOrCol, bool col, int pos) { List <Move> moves = new List <Move>(); List <string> boardLetters = new List <string>(); Move possibleMove; int[] position = new int[2]; foreach (string letter in rowOrCol) { if (letter != null) { boardLetters.Add(letter); } } foreach (string word in GetPossibleWordsForRow(hand, boardLetters)) { for (int c = 0; c + word.Length < (col ? board.GetCol(pos).Length : board.GetRow(pos).Length); c++) { position[0] = (col ? pos : c); position[1] = (col ? board.GetRow(pos).Length - 1 - c : pos); possibleMove = new Move(word, position, col); if (board.CheckIfValidMove(word, position, col, hand)) { moves.Add(possibleMove.Clone()); } } } return(moves); }
/// <summary> /// Returns the best possible move, given a ScrabbleBoard and a list of strings representing the player's hand. /// </summary> /// <param name="board">ScrabbleBoard that the move will be played on</param> /// <param name="hand">List of length 1 strings that the player has in his/her hand</param> /// <returns></returns> public Move GetBestPlay(ScrabbleBoard board, List <string> hand) { List <Move> allMoves = new List <Move>(); for (int c = 0; c < this.board.GetRow(0).Length; c++) { foreach (Move move in GetMovesInArray(board, hand, board.GetCol(c), true, c)) { allMoves.Add(move); } } for (int c = 0; c < this.board.GetCol(0).Length; c++) { foreach (Move move in GetMovesInArray(board, hand, board.GetRow(c), false, c)) { allMoves.Add(move); } } Move bestMove = new Move(null, null, true);; int topScore = 0; int currentScore; foreach (Move move in allMoves) { currentScore = board.GetPredictedScore(move.GetWord(), move.GetPosition()[0], move.GetPosition()[1], move.GetIfNorthSouth()); if (currentScore > topScore && !board.CheckIfRetread(move)) { System.Diagnostics.Debug.WriteLine(move.ToString()); topScore = currentScore; bestMove = move; } } return(bestMove); }
/// <summary> /// Returns a deep copy of this ScrabbleBoard /// </summary> /// <returns>Clone of ScrabbleBoard</returns> public ScrabbleBoard Clone() { string[,] newBaseBoard = (string[, ]) this.baseBoard.Clone(); ScrabbleBoard newBoard = new ScrabbleBoard(newBaseBoard, this.dictionary, letterValues); newBoard.SetBoard((string[, ]) this.lettersOnBoard.Clone()); return(newBoard); }
/// <summary> /// Constructor for the solver that uses default WWF Dicionary /// </summary> /// <param name="board">ScrabbleBoard to be played on</param> public Solver(ScrabbleBoard board) { this.board = board; string[] lines = System.IO.File.ReadAllLines("WWFDictionary.txt"); this.dictionary = new List <string>(); foreach (string s in lines) { dictionary.Add(s); } }
/// <summary> /// Checks the validity of the words in a row or column /// </summary> /// <param name="position">position of the row or column</param> /// <param name="col">True if it is a column to be checked</param> /// <returns>True if all words are valid words.</returns> public bool CheckRowOrCol(int position, bool col, ScrabbleBoard testBoard) { string[,] lettersOnBoard = testBoard.GetLetterBoard(); int counter = 0; string charAtPos; string wordSegment = ""; List <string> wordsToCheck = new List <string>(); while (counter < lettersOnBoard.GetLength(col ? 1 : 0)) //find what individual words are seperated by blank space { charAtPos = (col ? lettersOnBoard[position, lettersOnBoard.GetLength(1) - 1 - counter] : lettersOnBoard[counter, position]); if (charAtPos == null) { if (!wordSegment.Equals("")) { wordsToCheck.Add(new String(wordSegment.ToCharArray())); wordSegment = ""; } } else { wordSegment = wordSegment + charAtPos; } counter++; } foreach (string word in wordsToCheck) //check if the words greater than length 1 are in the dictionary { System.Diagnostics.Debug.WriteLine(word); if (word.Length != 1 && !dictionary.Contains(word)) { return(false); } } return(true); }
/// <summary> /// Checks to see if a move is a valid move, given also the hand that will play it. /// </summary> /// <param name="word">Word to be played</param> /// <param name="position">(x,y) position of the first letter in the word</param> /// <param name="northSouth">True if the play runs up/down.</param> /// <returns>True if the move is valid</returns> public bool CheckIfValidMove(string word, int[] position, bool northSouth, List <string> hand) { List <string> handCopy = new List <string>(hand); int positionIncrementer = 0; string charAtPosition; bool boardersALetter = false; char[] wordAr = word.ToCharArray(); //word.Substring(positionIncrementer,positionIncrementer) was making strings //longer than length 1. Odd. while (positionIncrementer < word.Length) //checks if it is placable { charAtPosition = (northSouth ? lettersOnBoard[position[0], position[1] - positionIncrementer] : lettersOnBoard[position[0] + positionIncrementer, position[1]]); if (charAtPosition == null && //checks to see if the character on the board is null and that the letter handCopy.Contains(wordAr[positionIncrementer].ToString())) //is also in the hand { handCopy.Remove(charAtPosition); } else if (charAtPosition != null && //checks if character on board is not null and that it is equal to the corresponding wordAr[positionIncrementer].ToString().Equals(charAtPosition)) //character in the word to be played { boardersALetter = true; } else { return(false); } if (northSouth) { if ((position[0] + 1 < lettersOnBoard.GetLength(0) && lettersOnBoard[position[0] + 1, position[1] - positionIncrementer] != null) || (position[0] - 1 > 0 && lettersOnBoard[position[0] - 1, position[1] - positionIncrementer] != null)) { boardersALetter = true; } } else { if ((position[1] + 1 < lettersOnBoard.GetLength(1) && lettersOnBoard[position[0] + positionIncrementer, position[1] + 1] != null) || (position[1] - 1 > 0 && lettersOnBoard[position[0] + positionIncrementer, position[1] - 1] != null)) { boardersALetter = true; } } positionIncrementer++; } if (!boardersALetter) { return(false); } //now check if if this creates any non-words in the process ScrabbleBoard testBoard = this.Clone(); positionIncrementer = 0; foreach (char character in wordAr) { testBoard.PlaceLetter(character.ToString(), position[0] + (northSouth ? 0 : positionIncrementer), position[1] - (northSouth ? positionIncrementer : 0)); positionIncrementer++; } if (!CheckRowOrCol((northSouth ? position[0] : position[1]), northSouth, testBoard)) //checks col/row word was placed along { return(false); } for (int c = 0; c < word.Length; c++) { if (!CheckRowOrCol((northSouth ? position[1] - c : position[0] + c), !northSouth, testBoard)) { return(false); } } return(true); }
/// <summary> /// Constructor for solver that takes in custom dictionary /// </summary> /// <param name="board">ScrabbleBoard to be played on</param> /// <param name="dictionary">List of strings that are valid words</param> public Solver(ScrabbleBoard board, List <string> dictionary) { this.board = board; this.dictionary = dictionary; }
//generate solution private void button1_Click(object sender, EventArgs e) { foreach (TextBox letterBox in board) { letterBox.ForeColor = Color.Black; } int[] pos = new int[2]; pos[0] = 5; pos[1] = 6; Move move = new Move("hi", pos, true); List <string> hand = new List <string>(); hand.Add(handLetter0.Text); hand.Add(handLetter1.Text); hand.Add(handLetter2.Text); hand.Add(handLetter3.Text); hand.Add(handLetter4.Text); hand.Add(handLetter5.Text); hand.Add(handLetter6.Text); while (hand.Contains("")) { hand.Remove(""); } string[,] baseBoard = new string[15, 15]; Dictionary <string, int> letters; if (WWFRadio.Checked) { letters = new Dictionary <string, int>() { { "a", 1 }, { "b", 4 }, { "c", 4 }, { "d", 2 }, { "e", 1 }, { "f", 4 }, { "g", 3 }, { "h", 3 }, { "i", 1 }, { "j", 10 }, { "k", 5 }, { "l", 2 }, { "m", 4 }, { "n", 2 }, { "o", 1 }, { "p", 4 }, { "q", 10 }, { "r", 1 }, { "s", 1 }, { "t", 1 }, { "u", 2 }, { "v", 5 }, { "w", 4 }, { "x", 8 }, { "y", 3 }, { "z", 10 }, }; } else { letters = new Dictionary <string, int>() { { "a", 1 }, { "b", 3 }, { "c", 3 }, { "d", 2 }, { "e", 1 }, { "f", 4 }, { "g", 2 }, { "h", 4 }, { "i", 1 }, { "j", 8 }, { "k", 5 }, { "l", 1 }, { "m", 3 }, { "n", 1 }, { "o", 1 }, { "p", 3 }, { "q", 10 }, { "r", 1 }, { "s", 1 }, { "t", 1 }, { "u", 1 }, { "v", 4 }, { "w", 4 }, { "x", 8 }, { "y", 4 }, { "z", 10 }, }; } string[] lines = System.IO.File.ReadAllLines("WWFDictionary.txt"); List <string> dictionary = new List <string>(); foreach (string s in lines) { dictionary.Add(s); } ScrabbleBoard scrabBoard = new ScrabbleBoard(baseBoard, dictionary, letters); int x = 0; int y = 0; string[,] boardl = new string[15, 15]; while (x < 15) { y = 0; while (y < 15) { boardl[x, y] = (board[x, y].Text.Equals("") ? null : board[x, y].Text); y++; } x++; } scrabBoard.SetBoard(boardl); Solver solv = new Solver(scrabBoard); PlaceWord(solv.GetBestPlay(scrabBoard, hand), true); }