Home > OS >  How to add a word of letters to the table for a scrabble game
How to add a word of letters to the table for a scrabble game

Time:10-19

Hello StackOverflow im trying to wrote a simple WPF C# scrabble game. What I was able to do on my own: I created a 10x10 table and randomly put letters in it

Here is the code of XAML and Randomizer

 <ItemsControl ItemsSource="{Binding Chars}">
     <ItemsControl.ItemTemplate>
         <DataTemplate>
             <ItemsControl ItemsSource="{Binding}">
                 <ItemsControl.ItemsPanel>
                     <ItemsPanelTemplate>
                         <StackPanel Orientation="Horizontal" />
                     </ItemsPanelTemplate>
                 </ItemsControl.ItemsPanel>
                 <ItemsControl.ItemTemplate>
                     <DataTemplate>
                         <Button
                             Width="30"
                             Height="30"
                             Margin="3"
                             Content="{Binding}" />
                     </DataTemplate>
                 </ItemsControl.ItemTemplate>
             </ItemsControl>
         </DataTemplate>
     </ItemsControl.ItemTemplate>
 </ItemsControl>

and randomizer

public partial class MainWindow : Window
 {
     public ObservableCollection<ObservableCollection<char>> Chars { get; set; }

     public MainWindow()
     {
         InitializeComponent();
         DataContext = this;

         Random rchar = new Random();
         Chars = new();
         for (int x = 0; x < 10; x  )
         {
             Chars.Add(new());
             for (int y = 0;  y < 10; y   )
             {
                 Chars[x].Add((char)rchar.Next(65, 91));
             }
         }

     }
 }

The next step, which I could not do, is to create a collection of words and place them in a table. I understand that we need to create a Word List; List<string[]>words = new List<string[]>();and then split each word into letters but then how do I arrange the letters vertically or horizontally in the table ?

I am a beginner and if there is a solution it should not be very complicated

CodePudding user response:

Steps:

  1. decide the direction - horizontal vs vertical
  2. decide where the word should start - as coordinates 0..9 (don't forget to perform checks if the word will fit)
  3. replace the generated characters with word characters

sample function code:

public enum WordDirection
{
    Vertical,
    Horizontal
}

public void WriteWord(ObservableCollection<ObservableCollection<char>> charTable, 
    IEnumerable<char> word, int startX, int startY, WordDirection direction)
{
    int x = startX;
    int y = startY;
    foreach(char ch in word)
    {
        charTable[x][y] = ch;
        if(direction == WordDirection.Horizontal)
        {
            x  ;
        }
        else //these two maybe need to be swapped as I'm not sure which is which (as I'm writing this without testing)
        {
            y  ;
        }
    }
}

Notes:

  • if the word won't fit, this code will most likely throw an exception
  • words written later will overwrite previous ones, unless you implement additional checks

CodePudding user response:

Like Marty's answer, but this will also check if there's space for your words. Sorry if it's too complicated this is my first StackOverflow answer.

It will: 1. Create an 2d array of chars filled with char '33'. 2. Loop through the words, check if there's space and if there's space commit the word. 3. Fill the rest of the chars up with random characters.

public ObservableCollection<ObservableCollection<char>> Chars { get; set; }

public List<string> Words { get; set; }

public enum WordDirection
{
    Vertical,
    Horizontal
}

Random rnd = new Random();

public void Main(){
    FillWithEmptyChars();
    WriteWords(Words);
    FillRestOfSpace();
}

public void FillWithEmptyChars(){
     Chars = new();
     for (int x = 0; x < 10; x  )
     {
         Chars.Add(new());
         for (int y = 0;  y < 10; y   )
         {
             Chars[x].Add((char)33); //Couldnt find a better char, chosen for ease
         }
     }
}

public void WriteWords(List<string> words){
    
    foreach(string word in words){
        var startx = rnd.Next(0, 9);
        var starty =  rnd.Next(0, 9);
        var worddir = (WordDirection) rnd.Next(0, 1);
        if WriteWord(word, startx, starty, worddir, false)
            WriteWord(word, startx, starty, worddir, true);
    }
}

public void WriteWord(IEnumerable<char> word, 
                        int startX, 
                        int startY,
                        WordDirection direction,
                        bool commit)
{
    //Start position
    int x = startX;
    int y = startY;
    
    //Clamp position
        if(direction == WordDirection.Horizontal)
            x = Math.Clamp(startX, 0, 10 - word.Count);
        if(direction == WordDirection.Vertical)
            y = Math.Clamp(startY, 0, 10 - word.Count);
    
    //Add a letter
    foreach(char ch in word)
    {
        //Only commit after checking if there's space left, to not overwrite other letters
        if (commit)
            charTable[x][y] = ch;
        
        //Check if there is space or that the letters match up
        if !(charTable[x][y] == ch || charTable[x][y] == (char)33)
            return false;
            
        if(direction == WordDirection.Horizontal)
            x  ;
        if(direction == WordDirection.Vertical)
            y  ;
    }
    
    return true;
}

public void FillRestOfSpace(){
     for (int x = 0; x < 10; x  )
     {
         for (int y = 0;  y < 10; y   )
         {
             if (Chars[x][y] == (char)33)
                Chars[x][y] = (char)rnd.Next(65, 91) //Couldnt find a better char, chosen for ease
         }
     }
}
  • Related