0

I have created a scrabble game with a computer opponent. If a blank tile is found in the computer's rack during the word generation if needs to be swapped out for every letter in the alphabet. I have my current solution to solve this problem below, but was wondering if there is a better more efficient way to accomplish this task.

if (str.Contains("*")) { char c = 'A'; String made = ""; while(c < 'Z') { made = str.ReplaceFirst("*", c.ToString()); if (!made.Contains("*")) { wordsMade.Add(made); if (theGame.theTrie.Search(made) == Trie.SearchResults.Found) { validWords.Add(made); } } else { char ch = 'A'; String made2 = ""; while (ch < 'Z') { made2 = made.ReplaceFirst("*", c.ToString()); wordsMade.Add(made2); if (theGame.theTrie.Search(made2) == Trie.SearchResults.Found) { validWords.Add(made2); } ch++; } } c++; } 
2
  • You need to provide more information about your "word generation" process. For example, from your code, it looks like you are fixing the location of blank tiles (within the generated words). Is this something you intend to do? Coding a computer scrabble opponent can be pretty challenging depending on how good you want it to be. There has been a lot of work in this area. You can read this paper titled "Opponent Modeling in Scrabble" for a nice summary: reason.cs.uiuc.edu/eyal/papers/scrabble-ijcai07.pdf . Commented Nov 27, 2011 at 17:59
  • This is a typical CodeReview question. Commented Nov 27, 2011 at 19:44

2 Answers 2

2

Adam is right that the code could be refactored to make it notationally smaller (a lot smaller, in fact), but fundamentally, you have to examine all 26*26 combinations of wildcard characters. So while it is possible to make the code syntactically more efficient, I don't think you can make it algorithmically more efficient.

Sign up to request clarification or add additional context in comments.

1 Comment

+1 for bringing up algorithmic complexity. You never said otherwise, this is more for OP, but that's only 676 combinations. An O(n^2) algorithm is usually bad, but if n will never ever get above 26, I'd say it probably doesn't matter.
1

There's a lot of duplicated code here that can be refactored.

This routine is duplicated, and can be put into a separate method:

wordsMade.Add(made2); if (theGame.theTrie.Search(made2) == Trie.SearchResults.Found) { validWords.Add(made2); } 

To something like this

void addWord(string newWordMade){ wordsMade.Add(newWordMade); if (theGame.theTrie.Search(newWordMade) == Trie.SearchResults.Found) { validWords.Add(newWordMade); } } 

This loop construct is also duplicated:

char ch = 'A'; String made2 = ""; while (ch < 'Z') { made2 = made.ReplaceFirst("*", c.ToString()); wordsMade.Add(made2); if (theGame.theTrie.Search(made2) == Trie.SearchResults.Found) { validWords.Add(made2); } ch++; } 

Combining the previous refactor with this one, with a slick lambda, would yield something like this:

void loopCharactersAndDoThis(Action<char> DoThis) { char ch = 'A'; while (ch < 'Z') { DoThis(ch); ch++; } } else { loopCharactersAndDoThis(ch => { string made2 = made.ReplaceFirst("*", c.ToString()); addWord(made2); }); } 

Or even just:

else { loopCharactersAndDoThis(ch => addWord(made.ReplaceFirst("*", c.ToString()))); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.