8-bit Chess Pixel Counting

20

1

Goal

You're playing a computerised chess game. The display is in black and white only and the pixels are chunky. White pixels use a lot power compared to black pixels and you're concerned about your carbon footprint.

Given a square and a piece in chess notation, return the number of white pixels displayed in the square.

The solution may be in the form of a function or a complete program.

Input

A 4-character string defining:

  1. One of wb for a white or black piece. (Not part of normal Chess notation, but required for this puzzle.)
  2. One of KQBNRP for a King, Queen, Bishop, kNight, Rook or Pawn.
  3. One of abcdefgh for the piece's file (column).
  4. One of 12345678 for the piece's rank (row).

Output

The number of white pixels used to draw the chess piece and the underlying square.

Requirements

  • Chess squares are 8x8 pixels and are either all white or all black.
  • a1 is a black square.
  • White chess pieces are drawn as white with a black outline. Black pieces are black with a white outline. All pieces have transparent pixels which show the underlying square.
  • Input is case-sensitive.
  • Assume the input is valid.

The chess pieces have sprites as follows.
. is the piece's colour.
# is the inverse of the piece's colour.
/ is the underlying square's colour.

King        Queen       Bishop  
////////    ////////    ////////
///#.#//    /#.#.#.#    ///#.#//
//#...#/    //#...#/    //##..#/
///#.#//    ///###//    //#.#.#/
///###//    //#...#/    ///###//
//#...#/    //#...#/    //#...#/
//#...#/    //#...#/    //#...#/
//#.#.#/    //#.#.#/    //#.#.#/

kNight      Rook        Pawn    
////////    ////////    ////////
////////    /#.#.#.#    ////////
//#..#//    /#.....#    ////////
/#....#/    /##...##    ///#.#//
///#..#/    //#...#/    //#...#/
//#..#//    //#...#/    ///#.#//
//#...#/    //#...#/    //#...#/
//#...#/    //#...#/    //#...#/

The number of pixels in the piece's colour, piece's outline and underlying square for each piece is:

Piece    Fill  Outline  Square
==============================
King     13    16       35
Queen    17    18       29
Bishop   13    18       33
Knight   16    12       36
Rook     23    18       23
Pawn     11    10       43

Test Cases

Input  Output
wRa1   23
bRa1   18
wPc2   54
bKg8   51

Scoring

The shortest code in bytes by Christmas Day gets a little something extra in their stocking.

Hand-E-Food

Posted 2015-12-15T03:55:23.133

Reputation: 7 912

Answers

2

Pyth, 54 53 bytes

The code contains unprintable characters, so here is a reversible xxd hexdump:

0000000: 732a 562b 5f57 2543 687a 322c 3031 2573  s*V+_W%Chz2,01%s
0000010: 434d 7474 7a32 4063 434d 2e22 0a2b 011e  CMttz2@cCM.".+..
0000020: d699 71d0 c6dc 3db8 eeae 2233 252a 4368  ..q...=..."3%*Ch
0000030: 747a 5433 31                             tzT31

Alternatively, here's a copy-paste friendly version, which you can also try online or use the test suite:

s*V+_W%Chz2,01%sCMttz2@cCM."\n+\x01\x1e\xd6\x99q\xd0\xc6\xdc=\xb8\xee\xae"3%*ChtzT31

PurkkaKoodari

Posted 2015-12-15T03:55:23.133

Reputation: 16 699

6

C#6, 107 bytes

Here's my own answer. I don't expect any points being the one who posed the challenge.

I have taken some inspiration from user81655's answer.

long P(string a)=>(a[0]>99?12201284685:11042628752)+(a[2]+a[3])%2*46566348643>>"KQBNRP".IndexOf(a[1])*6&63;

The pixel counts are encoded in 6-bit blocks. The outline or fill is added to the square (if it's white). Finally, the 6-bit block for the appropriate piece is extracted.

Thankfully, operation precedence worked heavily in my favor.

Hand-E-Food

Posted 2015-12-15T03:55:23.133

Reputation: 7 912

5

JavaScript (ES6), 106

As an anonymous function.

x=>(o=+'137999'[p='PNKBQR'.search(x[1])],f=+'262149'[p]+p,(parseInt(x[2]+x[3],19)%2?9:55-f-o)+(x>'w'?f:o))

By now, I'm following the simplest way of find the answer with a calculation - this could be not the best way.

Over a black square, the answer is the size of fill for white pieces and the size of outline for black pieces. Over a white square, you need to add the free space. See the table below (inside the snippet)

I keep the size of fill and outline for each piece, the free space inside the square can be found subtracting from 64. To save space, the outline in stored as a single digit afer subtracing 9. The fill is trickier as the range is wider, check the code (that's way the pieces are sorted by occupied space)

Test snippet:

F=x=>(
  o=+'137999'[p='PNKBQR'.search(x[1])], // get outline - 9
  f=+'262149'[p]+p, // get fill -9
  (
    parseInt(x[2]+x[3],19) // parse with an odd base the differentiate between odd and even rows
    %2?9:55-f-o // black square if odd,, white if even so calc free space
  ) +(x>'w'?f:o) // add fill or outline based on piece color
)

// Test suite

console.log=x=>O.innerHTML+=x+'\n'

for(i=0; z='PNKBQR'[i]; i++)
{
  o = '';
  t = 'w'+z+'c2'; // white piece, white square
  o += t+' '+F(t)+', '
  t = 'b'+z+'c2'; // black piece, white square
  o += t+' '+F(t)+', '
  t = 'w'+z+'a1'; // white piece, black square
  o += t+' '+F(t)+', '
  t = 'b'+z+'a1'; // black piece, black square
  o += t+' '+F(t)
  console.log(o);
}
<pre>
Piece    Fill  Outline  Free  w/w b/w w/b b/b
=============================================
Pawn     11    10       43     54  53  11  10
Knight   16    12       36     52  48  16  12
King     13    16       35     48  51  13  16
Bishop   13    18       33     46  51  13  18
Queen    17    18       29     46  47  17  18
Rook     23    18       23     46  41  23  18
</pre>    
<pre id=O></pre>

edc65

Posted 2015-12-15T03:55:23.133

Reputation: 31 086

3

JavaScript (ES6), 135 112 bytes

s=>(c={K:`\u000a\u0010\u0023`,Q:`\u0011\u0012\u001d`,B:`\u000a\u0012\u0021`,N:`\u0010\u000c\u0024`,R:`\u0017\u0012\u0017`,P:`\u000b\u000a\u002b`}[s[1]])[f="charCodeAt"](s<"w")+((s[f](2)-s[3])%2&&c[f](2))

Every \u00xx should be a single one-byte character. They are represented here as codes because Stack Exchange automatically removes unreadable characters from posts.

Explanation

s=>

  // c = string of three (mostly unreadable) characters, the ASCII code of each character
  //     represents the number of pixels in the fill, outline and square respectively
  (c={
    K:`\u000a\u0010\u0023`,
    Q:`\u0011\u0012\u001d`,
    B:`\u000a\u0012\u0021`,
    N:`\u0010\u000c\u0024`,
    R:`\u0017\u0012\u0017`,
    P:`\u000b\u000a\u002b`
  }[s[1]])

  [f="charCodeAt"](s<"w") // if piece is black add outline pixels, else add fill pixels
  +((s[f](2)-s[3])%2      // this returns 1 if the square is white or 0 if black
    &&c[f](2))            // if the square is white add the square's pixels

Test

var solution = s=>(c={K:`\u000a\u0010\u0023`,Q:`\u0011\u0012\u001d`,B:`\u000a\u0012\u0021`,N:`\u0010\u000c\u0024`,R:`\u0017\u0012\u0017`,P:`\u000b\u000a\u002b`}[s[1]])[f="charCodeAt"](s<"w")+((s[f](2)-s[3])%2&&c[f](2))
<input type="text" id="input" value="bKg8" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

user81655

Posted 2015-12-15T03:55:23.133

Reputation: 10 181

1

Lua, 158 155 Bytes

c,p,l,n=(...):byte(1,4)m="KQBNRP"d={}d[1]={13,17,13,16,23,11}d[0]={16,18,18,12,18,10}p=m:find(string.char(p))print(d[c%2][p]+(l+n)%2*(64-d[0][p]-d[1][p]))

Could probably reduce the byte count by encoding the data, but I kinda like the current table method.

Bases color of the square on the ASCII value of 'w' or 'b' taking advantage of the fact that one is even and one is odd. Assigns integer value of the piece based on the position of the piece's symbol in the m string variable. Whether a square is dark or light is handled by (l+n)%2 taking advantage of ASCII value again.

Ungolfed

c,p,l,n=(...):byte(1,4)   --stores input of all characters into variables
m="KQBNRP"                --piece encoded string
d={}                      --data table
d[1]={13,17,13,16,23,11}  --fill
d[0]={16,18,18,12,18,10}  --outline
p=m:find(string.char(p))  --position in string for position in tables
print(d[c%2][p] +         --takes data element from corresponding table according to color of piece and type of piece
     (l+n)%2  *           --is square black or white? 0 if back, 1 if white
     (64-d[0][p]-d[1][p]) --if white, pixels not used by piece would be area (64) minus pixels used by piece, or corresponding data in the tables
     )

-3 Bytes by removing c=c%2 before the print and using d[c%2][p] instead of d[c][p].

Cyv

Posted 2015-12-15T03:55:23.133

Reputation: 211