3

I'm using just normal python to make a checkerboard grids out of alternating 1s and 0s. I know that I can use a nested for loop with the modulus operator but I don't know exactly what to do with the modulus inside the for loop.

def print_board(board):
    for i in range(len(board)):

        print " ".join([str(x) for x in board[i]])



    my_grid = []

    for i in range(8):
        my_grid.append([0] * 8)
        for j in range(8):
            #This is where I'm stuck.


print_board(my_grid)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555

5 Answers5

3

Here's my solution, using nested for loops. Note that whether i+j is even or odd is a good way to determine where it should be 1 and where it should be 0, as it always alternates between adjacent 'cells'.

def checkerboard(n):
    board = []
    for i in range(n):
        board.append([])
        for j in range(n):
            board[i].append((i+j) % 2)
    return board

for row in checkerboard(8):
    print(row)

Prints

[1, 0, 1, 0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 1]
couragewolf
  • 111
  • 2
  • 9
2

Perhaps we should first aim to solve a different problem: how to generate a list with checkboard patterns.

Such list thus has interleaved a [0,1,0,...] row, and an [1,0,1,...] row.

Let us first construct the first row with length n. We can do this like:

[i%2 for i in range(n)]

Now the next row should be:

[(i+1)%2 for i in range(n)]

the next one can be:

[(i+2)%2 for i in range(n)]

Do you see a pattern emerge? We can construct such a pattern like:

[[(i+j)%2 for i in range(n)] for j in range(m)]

Now the only thing that is left is producing it as a string. We can do this by converting the data in the list to strings, join them together (and optionally use generators instead of list comprehension). So:

'\n'.join(''.join(str((i+j)%2) for i in range(n)) for j in range(m))

So we can construct an m×n grid like:

def print_board(m,n):
    print('\n'.join(''.join(str((i+j)%2) for i in range(n)) for j in range(m)))

A 10x15 board then is:

>>> print_board(10,15)
010101010101010
101010101010101
010101010101010
101010101010101
010101010101010
101010101010101
010101010101010
101010101010101
010101010101010
101010101010101

N.B.: we can make the code a bit more efficient, by using &1 instead of %2:

def print_board(m,n):
    print('\n'.join(''.join(str((i+j)&1) for i in range(n)) for j in range(m)))
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • I've put that into use, but I'm not sure if I'm using it right. I've used a for loop that appends the grid, and then I use (i + j) % 2 but it doesn't affect it at all. –  Sep 28 '17 at 18:53
2

A simple approach

# Function to draw checkerboard
def drawBoard(length):

    for row in xrange(0, length):
        for col in xrange(0, length):

            # Even rows will start with a 0 (No offset)
            # Odd rows will start with a 1 (1 offset)
            offset = 0
            if row % 2 == 0:
                offset = 1

            # alterate each column in a row by 1 and 0
            if (col + offset) % 2 == 0:
                print '1',
            else:
                print '0',

        # print new line at the end of a row
        print ""


drawBoard(8)
LoganHenderson
  • 1,222
  • 4
  • 12
  • 24
1

For even widths, you could avoid loops all together and just multiply some strings:

def print_board(width):
    print ('0 1 ' * (width // 2) + '\n' + '1 0 ' * (width // 2) + '\n') * (width // 2)

print_board(10)

Giving:

0 1 0 1 0 1 0 1 0 1 
1 0 1 0 1 0 1 0 1 0 
0 1 0 1 0 1 0 1 0 1 
1 0 1 0 1 0 1 0 1 0 
0 1 0 1 0 1 0 1 0 1 
1 0 1 0 1 0 1 0 1 0 
0 1 0 1 0 1 0 1 0 1 
1 0 1 0 1 0 1 0 1 0 
0 1 0 1 0 1 0 1 0 1 
1 0 1 0 1 0 1 0 1 0

This works as follows for a 10 x 10 grid:

  1. Take the string
    1 0

  2. Multiply the string by 5 giving
    1 0 1 0 1 0 1 0 1 0

  3. Do the same with 0 1 giving:
    0 1 0 1 0 1 0 1 0 1

  4. Add a newline to the end of each and join them together:
    1 0 1 0 1 0 1 0 1 0 \n0 1 0 1 0 1 0 1 0 1 \n

  5. Now multiply this whole string by 5 to get the grid.

Martin Evans
  • 45,791
  • 17
  • 81
  • 97
0

You can use list comprehension and a modulo:

new_board = [[0 if b%2 == 0 else 1 for b in range(8)] if i%2 == 0 else [1 if b%2 == 0 else 0 for b in range(8)] for i in range(8)]
for row in new_board:
   print(row)

Output:

[0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 0, 1, 0]
[0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 0, 1, 0]

For a more custom finish:

for row in new_board:
   print(' '.join(map(str, row)))

Output:

0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
  • 3
    Nested list comprehensions often hurt readability more than they help performance. Do you really *need* to do that all in one line? – trent Sep 26 '17 at 15:43
  • @trentcl I find that for smaller, simpler problems list comprehension works best because it is shorter and more concise. – Ajax1234 Sep 26 '17 at 15:44
  • 3
    You're telling me `[[0 if b%2 == 0 else 1 for b in range(8)] if i%2 == 0 else [1 if b%2 == 0 else 0 for b in range(8)] for i in range(8)]` is "short and concise"? *shrugs* Suit yourself, I guess. – trent Sep 26 '17 at 15:47
  • 2
    Some statements from the Zen of Python: 'Beautiful is better than ugly. Simple is better than complex. Sparse is better than dense. Readability counts.' – couragewolf Sep 26 '17 at 15:48