8

I have created a chess board and I didn't like the look of my switch case statement. I think there must be a way to compact it, but I cant find one. Maybe some of you can help me.

Extra explanations, the chess pieces are in a 2 dimensional array (arr2):

[
    ["R", "N", "B", "Q", "K", "B", "N", "R"],
    ["P", "P", "P", "P", "P", "P", "P", "P"],
    ["0", "0", "0", "0", "0", "0", "0", "0"],
    ["0", "0", "0", "0", "0", "0", "0", "0"],
    ["0", "0", "0", "0", "0", "0", "0", "0"],
    ["0", "0", "0", "0", "0", "0", "0", "0"],
    ["p", "p", "p", "p", "p", "p", "p", "p"],
    ["r", "n", "b", "q", "k", "b", "n", "r"]
];

And every field of the chess board has it's own id form "00" to "77" where first digit is the row and second is the column.

The innerHTML code is just the unicode for the chess pieces as seen here: https://en.wikipedia.org/wiki/Chess_symbols_in_Unicode#Unicode_code_points_and_HTML

for (let r = 0; r < arr2.length; r++) {
    for (let c = 0; c < arr2.length; c++) {
        div = document.getElementById(r + "" + c)
        switch (arr2[r][c]){
            //black piece
            case 'k':
                div.innerHTML = "&#9818";
                break;
            case 'q':
                div.innerHTML = "&#9819";
                break;
            case 'r':
                div.innerHTML = "&#9820";
                break;
            case 'b':
                div.innerHTML = "&#9821";
                break;
            case 'n':
                div.innerHTML = "&#9822";
                break;                
            case 'p':
                div.innerHTML = "&#9823";
                break;
            //white piecec
            case 'K':
                div.innerHTML = "&#9812";
                break;
            case 'Q':
                div.innerHTML = "&#9813";
                break;
            case 'R':
                div.innerHTML = "&#9814";
                break;
            case 'B':
                div.innerHTML = "&#9815";
                break;
            case 'N':
                div.innerHTML = "&#9816";
                break;                
            case 'P':
                div.innerHTML = "&#9817";
                break;
        }
    }
}
5
  • Have you thought about compacting these values into an object? Commented Dec 12, 2018 at 14:17
  • 1
    See the linked question's answers. Your best bet is probably an object or a Map mapping (for instance) "k" to "&#9818", etc. Then var html = theObject[arr2[r][c]]; if (html) { div.innerHTML = html; } (or with map: var html = theMap.get(arr2[r][c]); if (html) { div.innerHTML = html; }. Commented Dec 12, 2018 at 14:19
  • 1
    var pieces = { /* Black pieces */ 'k': "&#9818", 'q': "&#9819", 'r': "&#9820", 'b': "&#9821", 'n': "&#9822", 'p': "&#9823", /* whitepieces */ 'K': "&#9812", 'Q': "&#9813", 'R': "&#9814", 'B': "&#9815", 'N': "&#9816", 'P': "&#9817" }; for (let r = 0; r < arr2.length; r++) { for (let c = 0; c < arr2.length; c++) { div = document.getElementById(r + "" + c); div.innerHTML = pieces[arr2[r][c]]; }}} Commented Dec 12, 2018 at 14:22
  • Thanks to T.J Crowder and Mplungjan. It's looks much better now. And sorry for the duplicate question. Commented Dec 12, 2018 at 14:41
  • 1
    The above comments (at least one of them) should be proper answers. I'm guessing this question at one point had a link to some other similar (duplicate?) question, but it is no longer part of it. The concept of using a map rather than a switch statement in cases like this is powerful and not always intuitive. Commented Dec 12, 2018 at 17:21

1 Answer 1

5

Since the character codes for chess pieces are consecutive, you could do it like this:

div.innerHTML = "&#" + (9812 + "KQRBNPkqrbnp".indexOf(arr2[r][c])) + ";";

Note that HTML entities need a terminating semi-colon even though browsers are forgiving.

You don't even have to convert the character code to an HTML entity if you use textContent:

div.textContent = String.fromCharCode(9812 + "KQRBNPkqrbnp".indexOf(arr2[r][c]));

You will need to take the empty squares into account as well, at least when you start moving pieces and use the same code to update the display. That case is not dealt with in your code, but you can just isolate that case with ternary operator as in this demo:

function showBoard(arr2) {
    for (let r = 0; r < arr2.length; r++) {
        for (let c = 0; c < arr2.length; c++) {
            const div = document.getElementById(r + "" + c)
            div.textContent = arr2[r][c] === "0" ? ""
                : String.fromCharCode(9812 + "KQRBNPkqrbnp".indexOf(arr2[r][c]));
        }
    }
}

const arr2 = [
    ["R", "N", "B", "Q", "K", "B", "N", "R"],
    ["P", "P", "P", "P", "P", "P", "P", "P"],
    ["0", "0", "0", "0", "0", "0", "0", "0"],
    ["0", "0", "0", "0", "0", "0", "0", "0"],
    ["0", "0", "0", "0", "0", "0", "0", "0"],
    ["0", "0", "0", "0", "0", "0", "0", "0"],
    ["p", "p", "p", "p", "p", "p", "p", "p"],
    ["r", "n", "b", "q", "k", "b", "n", "r"]
];
showBoard(arr2);
table { border-collapse: collapse; border-spacing: 0; }

#chessboard { border: 1px solid; }
#chessboard tr td { width: 20px; height: 20px; }
#chessboard tr:nth-child(2n) td:nth-child(2n+1),
#chessboard tr:nth-child(2n+1) td:nth-child(2n) { background: silver; }
<table id="chessboard">
<tr><td id="00"></td><td id="01"></td><td id="02"></td><td id="03"></td><td id="04"></td><td id="05"></td><td id="06"></td><td id="07"></td></tr>
<tr><td id="10"></td><td id="11"></td><td id="12"></td><td id="13"></td><td id="14"></td><td id="15"></td><td id="16"></td><td id="17"></td></tr>
<tr><td id="20"></td><td id="21"></td><td id="22"></td><td id="23"></td><td id="24"></td><td id="25"></td><td id="26"></td><td id="27"></td></tr>
<tr><td id="30"></td><td id="31"></td><td id="32"></td><td id="33"></td><td id="34"></td><td id="35"></td><td id="36"></td><td id="37"></td></tr>
<tr><td id="40"></td><td id="41"></td><td id="42"></td><td id="43"></td><td id="44"></td><td id="45"></td><td id="46"></td><td id="47"></td></tr>
<tr><td id="50"></td><td id="51"></td><td id="52"></td><td id="53"></td><td id="54"></td><td id="55"></td><td id="56"></td><td id="57"></td></tr>
<tr><td id="60"></td><td id="61"></td><td id="62"></td><td id="63"></td><td id="64"></td><td id="65"></td><td id="66"></td><td id="67"></td></tr>
<tr><td id="70"></td><td id="71"></td><td id="72"></td><td id="73"></td><td id="74"></td><td id="75"></td><td id="76"></td><td id="77"></td></tr>
</table>

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.