DEV Community

Simon Green
Simon Green

Posted on

The one about a chess board

Weekly Challenge 281

Sorry for being MIA over the last few weeks. I've moved house and a new job, so haven't had a chance to partake in the challenges over this time.

Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.

Challenge, My solutions

Task 1: Check Color

Task

You are given coordinates, a string that represents the coordinates of a square of the chessboard as shown below:

Image of chess board

Write a script to return true if the square is light, and false if the square is dark.

My solution

This is relatively straight forward. The first thing I do is check that the provided position is valid (first character is a-h and the second character is between 1 and 8).

I then check if the first letter is a, c, e or g and the number is even, or the first letter is b, d, f or h and the number is odd, return true. Otherwise return false.

def check_color(coords: str) -> bool:
    if not re.search('^[a-h][1-8]$', coords):
        raise ValueError('Not a valid chess coordinate!')

    if coords[0] in ('a', 'c', 'e', 'g') and int(coords[1]) % 2 == 0:
        return True
    if coords[0] in ('b', 'd', 'f', 'h') and int(coords[1]) % 2 == 1:
        return True
    return False
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-1.py d3
true

$ ./ch-1.py g5
false

$ ./ch-1.py e6
true
Enter fullscreen mode Exit fullscreen mode

Task 2: Knight’s Move

Task

A Knight in chess can move from its current position to any square two rows or columns plus one column or row away. So in the diagram below, if it starts a S, it can move to any of the squares marked E.

Knight's move

Write a script which takes a starting position and an ending position and calculates the least number of moves required.

My solution

This one is more detailed. I start with the follow variables:

  • deltas is a tuples of lists (array of arrays in Perl) with the eight ways the knight can move from its current position.
  • target is the cell that we want to reach. For this I convert the first letter to a number from one to 8. It's stored as a tuple, the first value is the column and the second value is the row.
  • moves is the number of moves made and starts at one.
  • seen is a list of cells we have already visited.
  • coords is a list of current positions of a knight. It starts with the starting coordinate.
def knights_move(start_coord: str, end_coord: str) -> int:
    for coord in (start_coord, end_coord):
        if not re.search('^[a-h][1-8]$', coord):
            raise ValueError(
                f'The position {coord} is not a valid chess coordinate!')

    deltas = ([2, 1], [2, -1], [-2, 1], [-2, -1],
              [1, 2], [1, -2], [-1, 2], [-1, -2])
    coords = [convert_coord_to_list(start_coord)]
    target = convert_coord_to_list(end_coord)
    moves = 1
    seen = []
Enter fullscreen mode Exit fullscreen mode

I then have a double loop of the current coords list and the deltas list. A set a variable new_pos that represents the new coordinates for the knight. If this leads to a position outside the board or a coordinate we've already been to, I skip it. If it lands on the target, I return the moves value.

After the loop, I reset the coords list to the coordinates collected through the iterations, and increment the moves value by one. This continues until we hit the target coordinate.

    while True:
        new_coords = []

        for coord in coords:
            for delta in deltas:
                new_pos = (coord[0] + delta[0], coord[1] + delta[1])

                if not 0 < new_pos[0] < 9 or not 0 < new_pos[1] < 9 or new_pos in seen:
                    continue

                if new_pos == target:
                    return moves

                new_coords.append(new_pos)
                seen.append(new_pos)

        coords = new_coords
        moves += 1
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-2.py g2 a8
4

$ ./ch-2.py g2 h2
3
Enter fullscreen mode Exit fullscreen mode

Top comments (0)