'duplicate words in memory game

I have a problem with duplicates words in memory game.

I have a code (bellow) and what I want to duplicate labels and pass it (in random position every time when app is open) to bellow row e.g

Open app first time


| label1 | label2 | label3 | <= first row


| label3 | label2 | label1 | <= second row


Open app second time


| label1 | label2 | label3 | <= first row


| label1 | label3 | label2 | <= second row



private void AssingWordsToSquares()
        {
            Label label;
            int randomNumber;
            string path = $"{_currentPath}\\Resources\\Words.txt";
            _loadWordsList = File.ReadAllLines(path).ToList();

            for (int i = 0; i < tableLayoutPanel1.Controls.Count; i++)
            {
               
                if (tableLayoutPanel1.Controls[i] is Label)
                {
                    label = (Label)tableLayoutPanel1.Controls[i];                  
                }
                else
                    continue;
                
                randomNumber = random.Next(0, _loadWordsList.Count);
                label.Text = _loadWordsList[randomNumber];

                _loadWordsList.RemoveAt(randomNumber);
            }

``


Solution 1:[1]

So, at the moment, the function you shared is doing 2 things.

  • 1 is to find random words from a dictionary in a file
  • 2 is to place the words in a random order on screen

So you have 2 random operations happening. Remember the golden rule which is 1 function should try and do just 1 thing. It should have just 1 purpose.

So, you could seperate out that functionality to make it clearer.

We could start by creating a function that will generate a random list of words from your dictionary file. Something like this:

List<string> GenerateRandomWords(int numWords)
{
    var randomWordList = new List<string>();

    var wordList = System.IO.File.ReadAllLines("RandomWords.txt").ToList();

    for (int nLoopCnt = 0; nLoopCnt < numWords; nLoopCnt++)
    {
        var randomNumber = random.Next(0, wordList.Count);
        randomWordList.Add(wordList[randomNumber]);
    }

    return randomWordList;
}

Now you have your random words extracted from the file we need to put them on the screen in a random order. So, we could create another function GenerateRandomPosOrder that takes a TableLayoutPanel and generates a list of columns in a random order. So, each time you run this function is could return 1,2,3 or 1,3,2 or 3,2,1.

private HashSet<int> GenerateRandomPosOrder(TableLayoutPanel table)
{
    Thread.Sleep(500);
    Random rnd = new Random();

    var result = new HashSet<int>();

    while (result.Count < table.ColumnCount)
    {
        var randomNumber = rnd.Next(0, table.ColumnCount);

        result.Add(randomNumber);
    }

    return result;
}

Now we can put these 2 functions together in your AssignWordsToSquares like so.

private void AssignWordsToSquares(TableLayoutPanel table)
{
    var wordList = GenerateRandomWords(table.ColumnCount);

    // loop around every row in the table
    for (int rowCount = 0; rowCount < table.RowCount; rowCount++)
    {
        // this could return 0,2,1 or 1,0,2 or 1,2,0
        var order = GenerateRandomPosOrder(table);

        int pos = 0;
        foreach (var randomPosition in order)
        {
            var tableCell = (Label)table.GetControlFromPosition(column: randomPosition, row: rowCount);

            tableCell.Text = wordList[pos++];
        }
    }
}

The above function first gets a list of random words from the dictionary, then for ever row of the TableLayoutPanel it puts the words in a random order.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ocean Airdrop