I'm learning Blazor to create a web app in C#. One of the pages in the app is the game of Scrabble. Details of my implementation are as following:
The problem:
Click #1: (before) red (after) blue. Click #2: (before) red (after) blue click #2 's before should be blueThe work-around:
List<string>, it works. So I'm sticking to a List for now, but still I prefer array since the 2D index access syntax is neater than using list[15 * row + col] or list[row][col] (nested list)The question: WHY? Why doens't the array work as intended? Clearly it updated before exiting the method but is reverted afterward
The code:
Board.cs
public class Board
{
public enum SquareKind
{
White,
DL,
TL,
DW,
TW,
Start
}
public const int SIZE = 15;
public readonly (int row, int col) StartPos = (7, 7);
public SquareKind[,] Squares = new SquareKind[SIZE, SIZE];
public Board()
{
// Initialize premium squares (including starting one)
Squares[0, 0] = SquareKind.TW;
Squares[1, 5] = SquareKind.TL;
Squares[5, 1] = SquareKind.TL;
Squares[5, 5] = SquareKind.TL;
Squares[1, 1] = SquareKind.DW;
Squares[2, 2] = SquareKind.DW;
Squares[3, 3] = SquareKind.DW;
Squares[4, 4] = SquareKind.DW;
Squares[0, 3] = SquareKind.DL;
Squares[3, 0] = SquareKind.DL;
Squares[2, 6] = SquareKind.DL;
Squares[6, 2] = SquareKind.DL;
Squares[6, 6] = SquareKind.DL;
Squares[0, 14] = SquareKind.TW;
Squares[1, 9] = SquareKind.TL;
Squares[5, 13] = SquareKind.TL;
Squares[5, 9] = SquareKind.TL;
Squares[1, 13] = SquareKind.DW;
Squares[2, 12] = SquareKind.DW;
Squares[3, 11] = SquareKind.DW;
Squares[4, 10] = SquareKind.DW;
Squares[0, 11] = SquareKind.DL;
Squares[3, 14] = SquareKind.DL;
Squares[2, 8] = SquareKind.DL;
Squares[6, 12] = SquareKind.DL;
Squares[6, 8] = SquareKind.DL;
Squares[14, 14] = SquareKind.TW;
Squares[13, 9] = SquareKind.TL;
Squares[9, 13] = SquareKind.TL;
Squares[9, 9] = SquareKind.TL;
Squares[13, 13] = SquareKind.DW;
Squares[12, 12] = SquareKind.DW;
Squares[11, 11] = SquareKind.DW;
Squares[10, 10] = SquareKind.DW;
Squares[14, 11] = SquareKind.DL;
Squares[11, 14] = SquareKind.DL;
Squares[12, 8] = SquareKind.DL;
Squares[8, 12] = SquareKind.DL;
Squares[8, 8] = SquareKind.DL;
Squares[14, 0] = SquareKind.TW;
Squares[13, 5] = SquareKind.TL;
Squares[9, 1] = SquareKind.TL;
Squares[9, 5] = SquareKind.TL;
Squares[13, 1] = SquareKind.DW;
Squares[12, 2] = SquareKind.DW;
Squares[11, 3] = SquareKind.DW;
Squares[10, 4] = SquareKind.DW;
Squares[14, 3] = SquareKind.DL;
Squares[11, 0] = SquareKind.DL;
Squares[12, 6] = SquareKind.DL;
Squares[8, 2] = SquareKind.DL;
Squares[8, 6] = SquareKind.DL;
Squares[7, 0] = SquareKind.TW;
Squares[0, 7] = SquareKind.TW;
Squares[14, 7] = SquareKind.TW;
Squares[7, 14] = SquareKind.TW;
Squares[3, 7] = SquareKind.DL;
Squares[7, 3] = SquareKind.DL;
Squares[7, 11] = SquareKind.DL;
Squares[11, 7] = SquareKind.DL;
Squares[StartPos.row, StartPos.col] = SquareKind.Start;
}
}
Scrabble.razor
@page "/scrabble"
@Init()
<table class="scrabble-board">
<tbody>
@for (int i = 0; i < 15; i++)
{
<tr>
@for (int j = 0; j < 15; j++)
{
var (row, col) = (i, j); // Must store i, j here as row, col for callback with parameter using i and j
<td class="scrabble-board"
style="background-color: @squareColors[row, col]"
@onclick="@(() => SquareOnClick(row, col))" />
}
</tr>
}
</tbody>
</table>
Scrabble.razor.cs
public partial class Scrabble
{
string[,] squareColors = new string[Board.SIZE, Board.SIZE];
readonly Dictionary<Board.SquareKind, string> colors = new Dictionary<Board.SquareKind, string>
{
[Board.SquareKind.White] = "#DDE0DE",
[Board.SquareKind.DL] = "#87D7F6",
[Board.SquareKind.TL] = "#25A9DC",
[Board.SquareKind.DW] = "#F68787",
[Board.SquareKind.TW] = "#DB1B1B",
[Board.SquareKind.Start] = "#25DC88"
};
Board board = new Board();
string Init() // Method returns a null string to be able to run directly on the Blazor page without compiling error
{
for (int i = 0; i < Board.SIZE; i++)
for (int j = 0; j < Board.SIZE; j++)
{
var kind = board.Squares[i, j];
squareColors[i, j] =colors[kind];
}
return null;
}
void SquareOnClick(int row, int col)
{
Console.Write("(before) {0} ", squareColors[0, 0]);
squareColors[0, 0] = squareColors[row, col];
Console.WriteLine("(after) {0}", squareColors[0, 0]);
}
}
For a nicer look, I also used the following CSS (referenced in wwwroot/index.html)
.scrabble-board table {
width: 100%;
padding-top: 100%
}
.scrabble-board td {
border: 1px solid black;
border-radius: 5px;
width: 50px;
height: 50px;
background-size: contain;
}
Remove @Init() and initialize by overriding OnInitialized()
using Microsoft.AspNetCore.Components;
public partial class Scrabble : ComponentBase
{
...
protected override void OnInitialized()
{
for (int i = 0; i < Board.SIZE; i++)
for (int j = 0; j < Board.SIZE; j++)
{
var kind = board.Squares[i, j];
squareColors[i, j] = colors[kind];
}
}
...
Every time the render fragment was redrawn you initialized the board. Setting 0,0 to its default red.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With