# Checkered grid with X mark

## Challenge

Given two integer values $$\a \ge 2\$$ and $$\0 \le b < a\$$, generate a $$\(2a-1) \times (2a-1)\$$ matrix consisting of the integers 0, 1, and 2 as follows:

1. Create a checkerboard of 0s and 1s of the given size, corners being 0.
2. If $$\b > 0\$$, overwrite the checkerboard with 2s in the X shape at the center, each leg being of length $$\b\$$ (not counting the center).

This pattern is directly modeled from Art Puzzle event grids (where $$\a\$$ is fixed at 3, $$\b=0,1,2\$$ represent easy/normal/hard grids, and the 0, 1, 2s in the output represent easy/normal/hard minipuzzles respectively). Blame it if you don't like the edge case of $$\b=0\$$ :P

Standard rules apply. The shortest code in bytes wins.

## Test cases

a = 2, b = 0
[[0, 1, 0],
[1, 0, 1],
[0, 1, 0]]

a = 2, b = 1
[[2, 1, 2],
[1, 2, 1],
[2, 1, 2]]

a = 3, b = 0
[[0, 1, 0, 1, 0],
[1, 0, 1, 0, 1],
[0, 1, 0, 1, 0],
[1, 0, 1, 0, 1],
[0, 1, 0, 1, 0]]

a = 3, b = 1
[[0, 1, 0, 1, 0],
[1, 2, 1, 2, 1],
[0, 1, 2, 1, 0],
[1, 2, 1, 2, 1],
[0, 1, 0, 1, 0]]

a = 3, b = 2
[[2, 1, 0, 1, 2],
[1, 2, 1, 2, 1],
[0, 1, 2, 1, 0],
[1, 2, 1, 2, 1],
[2, 1, 0, 1, 2]]

a = 4, b = 0
[[0, 1, 0, 1, 0, 1, 0],
[1, 0, 1, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 1, 0],
[1, 0, 1, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 1, 0],
[1, 0, 1, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 1, 0]]

a = 4, b = 1
[[0, 1, 0, 1, 0, 1, 0],
[1, 0, 1, 0, 1, 0, 1],
[0, 1, 2, 1, 2, 1, 0],
[1, 0, 1, 2, 1, 0, 1],
[0, 1, 2, 1, 2, 1, 0],
[1, 0, 1, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 1, 0]]

a = 4, b = 2
[[0, 1, 0, 1, 0, 1, 0],
[1, 2, 1, 0, 1, 2, 1],
[0, 1, 2, 1, 2, 1, 0],
[1, 0, 1, 2, 1, 0, 1],
[0, 1, 2, 1, 2, 1, 0],
[1, 2, 1, 0, 1, 2, 1],
[0, 1, 0, 1, 0, 1, 0]]

a = 4, b = 3
[[2, 1, 0, 1, 0, 1, 2],
[1, 2, 1, 0, 1, 2, 1],
[0, 1, 2, 1, 2, 1, 0],
[1, 0, 1, 2, 1, 0, 1],
[0, 1, 2, 1, 2, 1, 0],
[1, 2, 1, 0, 1, 2, 1],
[2, 1, 0, 1, 0, 1, 2]]

• Can we output the matrix flattened? Oct 29, 2021 at 8:51
• @emanresuA No, the grid structure must be identifiable. Oct 29, 2021 at 9:31

# R, 72 68 bytes

function(a,b)[<-(diag(2*a-1)*0+0:1,cbind(c(x<--b:b,-x),x)+a,2*!!b)


Try it online!

Thanks to Robin Ryder for -4 bytes.

• 71 bytes by avoiding the if. Oct 29, 2021 at 8:25
• I think this works for 68 bytes. Oct 29, 2021 at 8:30
• @RobinRyder - Nice trick with [<-! Is that already in the R tips? I need to go back over some older answers to see if I can save some more bytes using that trick... Oct 29, 2021 at 14:46
• @DominicvanEssen I think it's buried in vlo's list of tips so it's tough to find, but it's also not super apparent how to use it from that description Oct 29, 2021 at 14:52

# Charcoal, 22 21 bytes

ＵＯ±Ｎ01¶10‖Ｏ⌈¿ＩηＰX×2⊕η


Try it online! Link is to verbose version of code. Explanation:

ＵＯ±Ｎ01¶10


Draw a chequerboard of size a with 0s on its major diagonals above and to the left of the current position.

‖Ｏ⌈


Reflect it to produce a chequerboard of size 2a-1, leaving the current position in the middle of the chequerboard. (Note that while drawing the chequerboard below and right would save a byte, there is no single byte to reflect up and left, and Charcoal's up reflect is buggy and moves the current position incorrectly anyway.)

¿Ｉη


Test whether b is zero.

ＰX×2⊕η


If not then draw arms of 2s of length b+1 (including the centre).

# Python 3.8 (pre-release), 82, 80 bytes (@ovs)

lambda a,b:(R:=range(1-a,a))and[[1&x+y|(x*x==y*y<=b*b>0)*2for x in R]for y in R]


Try it online!

Old version

Nothing too fancy, still learning the ropes. Should run on older python3s, too.

• A normal function is a byte shorter because you can reuse the range: tio.run/##TY/LCsIwEEX3/…
– ovs
Oct 29, 2021 at 8:37
• @ovs Wow, I genuinely didn't know ranges can be used multiple times, thought they're single shot like generators. This being python3.8 we can walruss it instead of making a proper function, saves another byte. Oct 29, 2021 at 8:48
• Could be 74 bytes, if this is valid ? : a=5 b=2 r=range(1-a,a) [[2*(ll==cc<=b*b>0)|(1&l+c)for c in r]for l in r]
– Malo
Nov 3, 2021 at 13:18
• @Malo thanks for the suggestion. I'm rather new to this site myself, but as I understand it it is required to provide a proper interface for the inputs. Your snippet appears to hard code them? Nov 3, 2021 at 21:21

# 05AB1E, 25 24 bytes

Dи2.ý01ŽNœSΛĀ+Y87S.Λ.º.∊


Can probably be shortened with a different approach, but I wanted to try and use the Canvas builtin for this challenge.

-1 byte thanks to @ovs.

Try it online.

Explanation:

D            # Duplicate the first (implicit) input-integer a
и           # Create a list with a amount of as
2.ý        # Intersperse it with 2: [a,2,a,2,a,2,...,a]
01      # Push "01"
ŽNœ   # Push compressed integer 6020
S  # Convert it to a list of digits: [6,0,2,0]
Λ # Use the Canvas builtin with these three options:
#  Length: [a,2,a,2,a,2,...,a]
#  Characters to draw: "01"
#  Directions: [6,0,2,0]
Ā            # Check if the (implicit) second input-integer b is NOT 0
+           # Add this check to the (implicit) second input-integer b
# (b=0 will remain 0; b≥1 is now b+1)
Y          # Push "2"
87S       # Push list [8,7]
.Λ     # Use the modifiable Canvas builtin with these three options:
#  Length: b+1 (or 0 if b=0)
#  Characters to draw: "2"
#  Directions: [8,7]
.º           # Intersected mirror the result towards the left
.∊         # Intersected mirror the result downwards
# (after which the result is output implicitly)


See this 05AB1E tip of mine (section How to compress large integers?) to understand why ŽNœ is 6020.

The Canvas Builtin uses three arguments to draw a shape:

• Length of the lines we want to draw
• Character/string to draw
• The direction to draw in, where each digit represents a certain direction:
7   0   1
↖ ↑ ↗
6 ← X → 2
↙ ↓ ↘
5   4   3


Here a step-by-step explanation of how it draws for example inputs $$\a=5,b=2\$$ with these steps:

Preparation: Dи2.ý makes the list [5,2,5,2,5,2,5,2,5].

Dи2.ý01ŽNœSΛ for this input will have the following Canvas arguments:

• Length: [5,2,5,2,5,2,5,2,5]
• Characters: "01"
• Directions: [6,0,6,2], which translate to $$\[←,↑,→,↑]\$$

Step 1: Draw 5 characters ("01010") in direction 6←:

01010


Step 2: Draw 2-1 characters ("1") in direction 0↑:

1
01010


Step 3: Draw 5-1 characters ("0101") in direction 2→:

10101
01010


Step 4: Draw 2-1 characters ("0") in direction 0↑:

    0
10101
01010


Step 5: Draw 5-1 characters ("1010") in direction 6←:

01010
10101
01010


Step 6: Draw 2-1 characters ("1") in direction 0↑:

1
01010
10101
01010


Step 7: Draw 5-1 characters ("0101") in direction 2→:

10101
01010
10101
01010


Step 8: Draw 2-1 characters ("0") in direction 0↑:

    0
10101
01010
10101
01010


Step 9: Draw 5-1 characters ("1010") in direction 6←:

01010
10101
01010
10101
01010


We then use the Canvas builtin again with three new arguments: Ā+Y87S.Λ

• Length: $$\b+1\$$ (or $$\0\$$ if $$\b=0\$$, because with length 1, direction 8 will draw a "2" at the position it was at before the reset unfortunately)
• Characters to draw: "2"
• Direction: [8,7], where the 8 is a special direction that resets the starting position (to the bottom-left we started at) and 7 translates to $$\↖\$$

Draw $$\3\$$ ($$\b=2\$$) characters ("222") in direction 7↖:

01010
10101
01210
10121
01012


After which we mirror this multi-line string both horizontally and vertically, after which it is output implicitly as our result.

See this 05AB1E tip of mine for an in-depth explanation of the Canvas builtin.

• _-> can be shortened to Ā+
– ovs
Oct 29, 2021 at 13:55
• @ovs Ah, of course. The _- was a leftover when I thought I needed -1 instead of 0 when I doubled the _ before subtracting, but apparently only 1 is giving the wrong result, <=0 and >1 is fine. Thanks. Oct 29, 2021 at 14:45

# MATL, 22 21 bytes

_Zvt&+oy&=bitg+>&+>E+


Inputs are a, then b.

Try it online!

### Explanation

This uses inputs 3, 1 as an example. The stack contents are shown in each step. The stack is shown upside down, with the top (i.e. most recent) element down.

_Zvt % Implicit input: a. Symmetric range [a a-1 ... 2 1 2 ... a-1 a]. Duplicate
% STACK: [3 2 1 2 3],
[3 2 1 2 3]
% STACK  [3 2 1 2 3],
[6 5 4 5 6
5 4 3 4 5
4 3 2 3 4
5 4 3 4 5
6 5 4 5 6]
o    % Modulo 2, elementwise. Gives checkered matrix
% STACK: [3 2 1 2 3],
[0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
y    % Duplicate second-top element
% STACK: [3 2 1 2 3],
[0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0],
[3 2 1 2 3]
&=   % Equal? to itself transposed, elementwise with broadcast. Gives "X" matrix
% STACK: [3 2 1 2 3],
[0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0],
[1 0 0 0 1]
0 1 0 1 0
0 0 1 0 0
0 1 0 1 0
1 0 0 0 1]
b    % Bubble up third-top element
% STACK: [0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0],
[1 0 0 0 1]
0 1 0 1 0
0 0 1 0 0
0 1 0 1 0
1 0 0 0 1],
[3 2 1 2 3]
i    % Input: b
% STACK: [0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0],
[1 0 0 0 1]
0 1 0 1 0
0 0 1 0 0
0 1 0 1 0
1 0 0 0 1],
[3 2 1 2 3],
1
tg+  % Duplicate, convert to logical, add. This converts positive b into b+1
% STACK: [0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0],
[1 0 0 0 1]
0 1 0 1 0
0 0 1 0 0
0 1 0 1 0
1 0 0 0 1],
[3 2 1 2 3],
2
>    % Greater than?, elementwise
% STACK: [0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0],
[1 0 0 0 1]
0 1 0 1 0
0 0 1 0 0
0 1 0 1 0
1 0 0 0 1],
[1 0 0 0 1]
% STACK: [0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0],
[1 0 0 0 1]
0 1 0 1 0
0 0 1 0 0
0 1 0 1 0
1 0 0 0 1],
[2 1 1 1 2
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
2 1 1 1 2]
>    % Greater than?, elementwise. Equivalent to "and not". This trims the "X" matrix
% STACK: [0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0],
[0 0 0 0 0]
0 1 0 1 0
0 0 1 0 0
0 1 0 1 0
0 0 0 0 0],
E+   % Multiply by 2, element-wise. Add, element-wise. Implicit display
% STACK: [0 1 0 1 0
1 2 1 2 1
0 1 2 1 0
1 2 1 2 1
0 1 0 1 0]

• Also 22 bytes: :Ptqitg+<XdEw&+o+2:&Zv Oct 29, 2021 at 14:51
• Just when I was about to lament that I broke the tie! Oct 29, 2021 at 16:34
• @UnrelatedString Ha! I was a few minutes faster :-P Oct 29, 2021 at 17:34
• @UnrelatedString Sadly I forgot to put my dinner in the oven so I've only just got around to restoring the tie.
– Neil
Oct 29, 2021 at 18:32
• @Neil Nice to see three very different languages with the same score! Oct 29, 2021 at 19:53

# Jelly, 19 bytes

^þ
ÇḂ+UṚŒḄŒBɓa‘{Ç¬Ḥ


Try it online!

With some inspiration from hyper-neutrino's Vyxal solution.

^þ     Monadic helper link:
þ     Table the (range from 1 to the) argument with itself by
^      XOR.
Ḃ    The parities of the cells form a checkerboard,
¬    and the diagonal consists of zeroes while the rest is truthy.

Ç¬     Generate an identity matrix of size
ɓ          b
‘        + 1
a {       or 0 if b is 0,
Ḥ    then double it.
+                 Add that to (the top left corner of)
ÇḂ                  an a by a checkerboard,
UṚ               rotate the result 180 degrees,
ŒḄŒB           and palindromize it in both dimensions.


# Jelly, 25242322 21 bytes

^þ
ÇḂ+ŒḄŒBðÇUoḶ>¥*¬ḤU


Try it online!

That feels better. $$\a\$$ on the left, $$\b\$$ on the right.

^þ     Monadic helper link:
þ     Table the (range from 1 to the) argument with itself by
^      XOR.
Ḃ    The parities of the cells form a checkerboard,
¬    and the diagonal consists of zeroes while the rest is truthy.

Ç             Generate an a by a matrix of zeroes on the diagonal and nonzeroes elsewhere.
U            Mirror it,
o           and replace zeroes with corresponding elements from:
Ḷ ¥        for each 0 .. a-1,
>         is it greater than b?
*       Raise each to the bth power,
¬      logically negate,
Ḥ     double,
U    and mirror back.
ÇḂ                    an a by a checkerboard,
ŒḄŒB               then palindromize in both dimensions.


# J, 40 bytes

((2|+/~)@]+2**@[*=/~@]*(>:]*=/~))|@i:@<:


Try it online!

• Your a is off by one and the shape of 2's is incorrect. Oct 31, 2021 at 7:53

# Jelly, 18 bytes

_þµṂ>Ɠa~¤×¬Ḥ+ḂŒBŒḄ


Try it online!

-1 from caird, who noted that I could get rid of a backtick by reading b from stdin.

                For inputs (a, b):
_þµ              Make a subtraction table over [1..a], and operate on that.
Ṃ             Get the minimum row: this is always [1-a, 2-a ... 0].
>Ɠa~¤        Which elements are greater than (b and ~b)?
For example for (5, 2): Ṃ    → [-4, -3, -2, -1,  0]
Ṃ>-3 → [ 0,  0,  1,  1,  1]
×¬      Multiply this vector by the a×a identity matrix "¬table"
Ḥ     and double the result (generating the 2s)
+Ḃ   then add to an a×a checkerboard of 1s "table % 2":

0 0 0 0 0   0 1 0 1 0   0 1 0 1 0
0 0 0 0 0   1 0 1 0 1   1 0 1 0 1
0 0 2 0 0 + 0 1 0 1 0 → 0 1 2 1 0
0 0 0 2 0   1 0 1 0 1   1 0 1 2 1
0 0 0 0 2   0 1 0 1 0   0 1 0 1 2

ŒBŒḄ              Finally, palindromize both ways to make the full output.

• 18 bytes as a full program taking b on STDIN Oct 31, 2021 at 19:12

# Ruby, 70 bytes

->a,b{(r=1-a...a).map{|x|r.map{|y|x*x==y*y&&x*x<=b*b&&b>0?2:(x+y)%2}}}


Try it online!

# Zsh, 127116 112 bytes

R=({1..$[c=2*$1-1]})
for i ($R)(for j ($R)S+=$[(i==j)|(j+i==c+1)?$2==0?0:${$((i-$1))/\-/}>$2?0:2:(i+j)%2]
<<<$S)  I used bits of the X without Y problem. @pxeger saved 4 bytes! Description Using a =$1 and b = $2 as defined in the question... R=({1..X}) define array R as a sequence from 1 to expression X c=$2*$1-1 size of matrix for i.. for j.. iterate rows, columns S+=$[...]                add a digit to S, per the logic in [...]
(i==j)|(j+i==c+1)?...    are we on a diagonal? if so, do ...
:(i+j)%2                 otherwise, fill the matrix with 1s and 0s
$2==0?0 if b is 0, then default to 0 on the diagonal :${$((i-$1))/\-/}>$2?0:2 if abs(i-a) > b then put 0 on the diagonal, otherwise 2  • -4 bytes by (a): appending characters to a variable instead of printfing, and then printing the whole variable per line, and implicitly resetting it for each iteration of i using a (subshell); and (b): extracting {1..$c} into an array variable Oct 29, 2021 at 10:08

# C (gcc), 118 $$\\cdots\$$ 106 103 bytes

i;f(a,b){for(a*=2,i=--a*a;i--;)printf("%d%c",!b|b<abs(a/2-i/a)||i/a-i%a&&i/a+1+i%a-a?i%2:2,i%a?32:10);}


Try it online!

Saved 3 bytes thanks to ceilingcat!!!

# Vyxal, 24 bytes

:±+ʁ:±†vǔd$ʁ:v+∷+2(ṘømÞT  Try It Online! -3 bytes thanks to lyxal -1 byte thanks to Unrelated String :±+ʁ:±†vǔd$ʁ:v+∷+2(ṘømÞT     Full Program; take in order b, a
:                            duplicate b
±                           sign
+                          add (0 if b is 0, otherwise b+1)
ʁ                         range (0..x-1)
:                        duplicate
±                       sign ([0, 1, 1, ..., 1] of length 0 / b+1)
†                      logical NOT - [1, 0, 0, ..., 0]
vǔ                    vectorized rotate; identity matrix of size 0 / b+1
d                   double; [2, 0, 0], [0, 2, 0], [0, 0, 2]
\$                  swap a to TOS
ʁ                 range; 0..a-1
:                duplicate
v+              add each; addition table; [2, 3, 4], [3, 4, 5], [4, 5, 6]
∷             parity; checkerboard of size a with 0 in top-left
+            add the two matrices together
2(....)    repeat twice
Ṙ        reverse (flip vertical)
øm      palindromize (reflect vertical; do not copy middle)
ÞT    transpose


# Excel, 97 bytes

=LET(x,SEQUENCE(A1*2-1)-A1,y,TRANSPOSE(x),IF(MOD(x+y,2),1,IF((x-y)*(x+y)+(B1=0)+(ABS(x)>B1),,2)))


## Explanation

=LET(x,SEQUENCE(A1*2-1)-A1, # [-a..a] vertical
y,TRANSPOSE(x),             # [-a..a] horizontal
IF(MOD(x+y,2),1,            # if x+y mod 2 <> 0 then 1
IF((x-y)*(x+y)+(B1=0)+(ABS(x)>B1),,2)))
# else if (x<>y and x<>-y) or b = 0 or abs(x) > b then 0 else 2


# Julia, 336271195 187 Bytes

v4, and thanks for the help!

function x(a,b)
s=(2*a-1)
h = zeros(Int8,(s,s))
h[2:2:s^2].=1
if b!=0;h[a,a]=2end
for i in range(1,stop=min(b,a-1))
h[a+i,a+i]=2
h[a-i,a-i]=2
h[a-i,a+i]=2
h[a+i,a-i]=2
end
return(h)
end



old:

function cross(a,b)
h = zeros(Int8,((2*a-1),(2*a-1)))
h[2:2:(2*a-1)^2] .= 1
c = (Int8((2*a-1)/2+0.5), Int8((2*a-1)/2+0.5))
h[c[1],c[2]] = 2
for i in range(1,stop=min(b,a-1))
h[c[1]+i,c[2]+i] = 2
h[c[1]-i,c[2]-i] = 2
h[c[1]-i,c[2]+i] = 2
h[c[1]+i,c[2]-i] = 2
end
return(h)
end

• Welcome to Code Golf, and nice first answer! Is it possible to golf this by changing the name of the function (cross $\to$ x, perhaps), and removing a lot of the whitespace (e.g. spaces around =, indentation, etc.)? Be sure to check out our Tips for golfing in Julia page for ways you can golf your program Oct 31, 2021 at 22:58
• Also, guessing from the code, h[c[1],c[2]] = 2 should be run only when b is nonzero. Oct 31, 2021 at 23:39
• You could use a variable for (2*a-1). And Int8((2*a-1)/2+0.5) is simply a, so you can erase c and just use a for all those c[1] and c[2] :) Nov 1, 2021 at 6:32
• 135 bytes Nov 8, 2021 at 9:58

# JavaScript (ES6),  87  84 bytes

Expects (a)(b).

a=>b=>[...Array(a+--a)].map((_,y,A)=>A.map(_=>x+y&1|(x*x/b<=b&x*x--==y*y)*2,y-=x=a))


Try it online!

### Note

We do x*x/b<=b rather than x*x<=b*b so that x*x/b evaluates to NaN when both $$\x\$$ and $$\b\$$ are $$\0\$$. This makes the condition fail as expected for this edge case without the need for an explicit test on $$\b\$$.

# TI-Basic, 80 bytes

Prompt A,B
identity(2A-1→[A]
For(I,1,2A-1
For(J,1,2A-1
remainder(I+J,2)+2max(abs({I,J}-A)≤B and B)max(I={J,2A-J→[A](I,J
End
End


+1 byte if not ran on a TI-84+/SE with the 2.53 MP OS or above by replacing remainder(I+J,2) with 2fPart(.5(I+J)).

Output is stored in [A].

# APL+WIN, 72 bytes

Prompts for a then b:

(s⊖(s←.5×b-a)⌽z↑(b≠1)×2×m∨⌽m←n∘.=(n←⍳b←(2×b←⎕)+1))+(z←a,(a←(2×⎕)-1))⍴0 1


Explanation:

(z←a,(a←(2×⎕)-1))⍴0 1 create the 0 1 checkerboard matrix defined by a

2×m∨⌽m←n∘.=(n←⍳b←(2×b←⎕)+1)) create the 2s diagonals defined by b

(b≠1)× filter the case where b=0

z↑ pad the diagonals matrix to the same size as the checkerboard matrix

s⊖(s←.5×b-a)⌽ centre the diagonals in the padded diagonals matrix.

The two matrices are then summed together.


Try it online! Thanks to Dyalog Classic

# C (clang), 92 bytes

z,i;f(a,b){for(i*=z=i=2*a-1;i;)printf("\n%d"+!!(i--%z),i%~z&&i%~-z||(i/z-~-a)/~b|!b?i%2:2);}


Try it online!

Function printing to stdout.
Leading line can be removed at the cost of 1 Byte.

z : side length
i : characters counter(backwards)
f(a,b){
for(i*=z=i=2*a-1;i;)    - initialize variables and itetate backwards until 0
printf("\n%d"+!!(i--%z) - prints:
> a newline if i%z == 0
> the number obtained by expression below at each iteration (decrements i)

i%~z&&i%~-z        - false on diagonals
||(i/z-~-a)/~b|!b  -  false on horizontal window
* for example f(3,1)

01110    11111   11111
10101    00000   10101
11011 || 00000 = 11011
10101    00000   10101
01110    11111   11111

?i%2:2    - draw board on 1's
2's on zeros


# Matlab, 79 bytes

m=zeros(2*a-1);
m(2:2:end)=1;
for i=a-b:a+b
m(i,i)=2*(b>0);end
max(m,flipud(m))


Only make one diagonal of twos and generate the antidiagonal by maxing with the flipped matrix. The 2*(b>0) was my shortest way to take care of the b=0 edge case.