I am filling a bag full of scrabble tiles.  There should be 100 tiles in the bag of these letters:A-9, B-2, C-2, D-4, E-12, F-2, G-3, H-2, I-9, J-1, K-1, L-4, M-2, N-6, O-8, P-2, Q-1, R-6, S-4, T-6, U-4, V-2, W-2, X-1, Y-2, Z-1 and Blanks-2.These numbers/letters should never change.  I have a working solution, but it is horrible.  There is a lot of duplicate code, a lot of room for errors, and it has very poor readability.  I am stumped on how I can make this code more readable and less error-prone.  Any suggestions?  I am not opposed to scratching this class altogether, if anyone knows of a better approach.Bag.cspublic class Bag{    private Tile[] tiles = new Tile[100];    private const int numA = 9;    private const int numB = 2;    private const int numC = 2;    private const int numD = 4;    private const int numE = 12;    private const int numF = 2;    private const int numG = 3;    private const int numH = 2;    private const int numI = 9;    private const int numJ = 1;    private const int numK = 1;    private const int numL = 4;    private const int numM = 2;    private const int numN = 6;    private const int numO = 8;    private const int numP = 2;    private const int numQ = 1;    private const int numR = 6;    private const int numS = 4;    private const int numT = 6;    private const int numU = 4;    private const int numV = 2;    private const int numW = 2;    private const int numX = 1;    private const int numY = 2;    private const int numZ = 1;    private const int numBlank = 2;    public void populateTiles()    {        int i = 0;        for (int j = 0; j < numA; j++)        {            tiles[i] = new Tile('A');            i++;        }        for (int j = 0; j < numB; j++)        {            tiles[i] = new Tile('B');            i++;        }        for (int j = 0; j < numC; j++)        {            tiles[i] = new Tile('C');            i++;        }        for (int j = 0; j < numD; j++)        {            tiles[i] = new Tile('D');            i++;        }        for (int j = 0; j < numE; j++)        {            tiles[i] = new Tile('E');            i++;        }        for (int j = 0; j < numF; j++)        {            tiles[i] = new Tile('F');            i++;        }        for (int j = 0; j < numG; j++)        {            tiles[i] = new Tile('G');            i++;        }        for (int j = 0; j < numH; j++)        {            tiles[i] = new Tile('H');            i++;        }        for (int j = 0; j < numI; j++)        {            tiles[i] = new Tile('I');            i++;        }        for (int j = 0; j < numJ; j++)        {            tiles[i] = new Tile('J');            i++;        }        for (int j = 0; j < numK; j++)        {            tiles[i] = new Tile('K');            i++;        }        for (int j = 0; j < numL; j++)        {            tiles[i] = new Tile('L');            i++;        }        for (int j = 0; j < numM; j++)        {            tiles[i] = new Tile('M');            i++;        }        for (int j = 0; j < numN; j++)        {            tiles[i] = new Tile('N');            i++;        }        for (int j = 0; j < numO; j++)        {            tiles[i] = new Tile('O');            i++;        }        for (int j = 0; j < numP; j++)        {            tiles[i] = new Tile('P');            i++;        }        for (int j = 0; j < numQ; j++)        {            tiles[i] = new Tile('Q');            i++;        }        for (int j = 0; j < numR; j++)        {            tiles[i] = new Tile('R');            i++;        }        for (int j = 0; j < numS; j++)        {            tiles[i] = new Tile('S');            i++;        }        for (int j = 0; j < numT; j++)        {            tiles[i] = new Tile('T');            i++;        }        for (int j = 0; j < numU; j++)        {            tiles[i] = new Tile('U');            i++;        }        for (int j = 0; j < numV; j++)        {            tiles[i] = new Tile('V');            i++;        }        for (int j = 0; j < numW; j++)        {            tiles[i] = new Tile('W');            i++;        }        for (int j = 0; j < numX; j++)        {            tiles[i] = new Tile('X');            i++;        }        for (int j = 0; j < numY; j++)        {            tiles[i] = new Tile('Y');            i++;        }        for (int j = 0; j < numZ; j++)        {            tiles[i] = new Tile('Z');            i++;        }        for (int j = 0; j < numBlank; j++)        {            tiles[i] = new Tile(' ');            i++;        }    }}Tile.cspublic class Tile{    private char letter;    private int value;    public Tile(char letter)    {        switch (letter)        {            case ' ':                value = 0;                break;            case 'A':            case 'E':            case 'I':            case 'O':            case 'U':            case 'L':            case 'N':            case 'S':            case 'T':            case 'R':                value = 1;                break;            case 'D':            case 'G':                value = 2;                break;            case 'B':            case 'C':            case 'M':            case 'P':                value = 3;                break;            case 'F':            case 'H':            case 'V':            case 'W':            case 'Y':                value = 4;                break;            case 'K':                value = 5;                break;            case 'J':            case 'X':                value = 8;                break;            case 'Q':            case 'Z':                value = 10;                break;            default:                Console.Error(Invalid Tile created!);                break;        }    }}
Populating a bag of Scrabble tiles
c#;game
I'm sorry, I just love to make things flexible so much that I have to take it one step further...I will use a mix between @EthanBierlein's version and your original, and improve on that, making the following changes:Extracting a method for adding a specific amount of a tileBeing able to specify the points you get from a tile here as wellThere is really no reason in my opinion to separate the configuration of how many tiles of a certain letter there should be, and how many points that tile should be worth. It is more reasonable, and more maintainable to keep them all at one place (consider the places you would need to change if you wanted to make Scrabble for other languages, different languages have different amount of letters and different score for them, not to mention different alphabets...)This will lead to the Scrabble setup being much more changable, you can have A tiles have different point values, you can easily change the number of E tiles you have in your board, etc. You could even extend on this idea and read from a configuration file to determine how many tiles you should have for each square.I'm not saying that you should do all this, I'm just saying that by changing your code a bit, you can do this.using System.Collections.Generic;class Bag{    public List<Tile> tiles = new List<Tile>();    /// <summary>    /// Populate the list tiles with scrabble tiles.    /// </summary>    public void PopulateTiles()    {        AddTile(9, 'A', 1);        AddTile(2, 'B', 42);        AddTile(2, 'C', 42);        AddTile(4, 'D', 42);        // ...    }    public void AddTile(int count, char letter, int score)    {        for (int i = 0; i < count; i++)        {            Tile tile = new Tile(letter, score); // Pass the score along to the tile as well            tiles.Add(tile);        }    }}Small note: Method names should use PascalCase naming conventions, not camelCase. As can be seen in my code, populateTiles should be PopulateTiles.