def collisions(Sapiens: Sapiens, radius: int) -> Location:
    """Try to find a free location that is adjacent to the given Sapiens's
    location.

    The returned location will be within the bounds of the field.
    :return: A valid location within the grid area, otherwise None.
    :author: ZHENG Yannan
    """
    next_pos = Location(Sapiens.location.row + Sapiens.velocity.row,
                        Sapiens.location.col + Sapiens.velocity.col)
    next_dir = Velocity(Sapiens.velocity.row, Sapiens.velocity.col)

    if next_pos.col <= 0 or next_pos.col >= Sapiens.field.size - 1:
        next_pos.col = Sapiens.location.col - next_dir.col
        next_dir.col = -next_dir.col
    if next_pos.row <= 0 or next_pos.row >= Sapiens.field.size - 1:
        next_pos.row = Sapiens.location.row - next_dir.row
        next_dir.row = -next_dir.row

    if Sapiens.field.getObjectAt(next_pos):
        if Sapiens.colour == 'red' and Sapiens.field._field[next_pos.row][
                next_pos.col].colour == 'slate blue' and random.random(
                ) <= Virus.INFECTION_RATE:
            Sapiens.field._field[next_pos.row][next_pos.col].colour = 'red'
            Sapiens.field._field[next_pos.row][
                next_pos.col].r_or_d = Stats.step + Virus.RECOVERY_TIME
            Sapiens.numberInfected = Sapiens.numberInfected + 1
            Stats.I = Stats.I + 1
            Stats.S = Stats.S - 1
        r = Sapiens.field._field[next_pos.row][next_pos.col].velocity.row
        c = Sapiens.field._field[next_pos.row][next_pos.col].velocity.col
        Sapiens.field._field[next_pos.row][
            next_pos.col].velocity.row = next_dir.row
        Sapiens.field._field[next_pos.row][
            next_pos.col].velocity.col = next_dir.col
        next_dir.row = r
        next_dir.col = c
        next_pos.row = Sapiens.location.row + next_dir.row
        next_pos.col = Sapiens.location.col + next_dir.col
    if Sapiens.field.getObjectAt(next_pos):
        if Sapiens.colour == 'red' and Sapiens.field._field[next_pos.row][
                next_pos.col].colour == 'slate blue' and random.random(
                ) <= Virus.INFECTION_RATE:
            Sapiens.field._field[next_pos.row][next_pos.col].colour = 'red'
            Sapiens.field._field[next_pos.row][
                next_pos.col].r_or_d = Stats.step + Virus.RECOVERY_TIME
            Sapiens.numberInfected = Sapiens.numberInfected + 1
            Stats.I = Stats.I + 1
            Stats.S = Stats.S - 1
        r = Sapiens.field._field[next_pos.row][next_pos.col].velocity.row
        c = Sapiens.field._field[next_pos.row][next_pos.col].velocity.col
        Sapiens.field._field[next_pos.row][
            next_pos.col].velocity.row = next_dir.row
        Sapiens.field._field[next_pos.row][
            next_pos.col].velocity.col = next_dir.col
        next_dir.row = r
        next_dir.col = c
        next_pos.row = Sapiens.location.row + next_dir.row
        next_pos.col = Sapiens.location.col + next_dir.col
    if Sapiens.field.getObjectAt(next_pos):
        if Sapiens.colour == 'red' and Sapiens.field._field[next_pos.row][
                next_pos.col].colour == 'slate blue' and random.random(
                ) <= Virus.INFECTION_RATE:
            Sapiens.field._field[next_pos.row][next_pos.col].colour = 'red'
            Sapiens.field._field[next_pos.row][
                next_pos.col].r_or_d = Stats.step + Virus.RECOVERY_TIME
            Sapiens.numberInfected = Sapiens.numberInfected + 1
            Stats.I = Stats.I + 1
            Stats.S = Stats.S - 1
        r = Sapiens.field._field[next_pos.row][next_pos.col].velocity.row
        c = Sapiens.field._field[next_pos.row][next_pos.col].velocity.col
        Sapiens.field._field[next_pos.row][
            next_pos.col].velocity.row = next_dir.row
        Sapiens.field._field[next_pos.row][
            next_pos.col].velocity.col = next_dir.col
        next_dir.row = r
        next_dir.col = c
        next_pos.row = Sapiens.location.row + next_dir.row
        next_pos.col = Sapiens.location.col + next_dir.col
    if Sapiens.field.getObjectAt(next_pos):
        if Sapiens.colour == 'red' and Sapiens.field._field[next_pos.row][
                next_pos.col].colour == 'slate blue' and random.random(
                ) <= Virus.INFECTION_RATE:
            Sapiens.field._field[next_pos.row][next_pos.col].colour = 'red'
            Sapiens.field._field[next_pos.row][
                next_pos.col].r_or_d = Stats.step + Virus.RECOVERY_TIME
            Sapiens.numberInfected = Sapiens.numberInfected + 1
            Stats.I = Stats.I + 1
            Stats.S = Stats.S - 1
        r = Sapiens.field._field[next_pos.row][next_pos.col].velocity.row
        c = Sapiens.field._field[next_pos.row][next_pos.col].velocity.col
        Sapiens.field._field[next_pos.row][
            next_pos.col].velocity.row = next_dir.row
        Sapiens.field._field[next_pos.row][
            next_pos.col].velocity.col = next_dir.col
        next_dir.row = r
        next_dir.col = c
        next_pos.row = Sapiens.location.row + next_dir.row
        next_pos.col = Sapiens.location.col + next_dir.col

    Sapiens.velocity.row = next_dir.row
    Sapiens.velocity.col = next_dir.col
    if Sapiens.field.getObjectAt(
            next_pos
    ) or next_pos.col < 0 or next_pos.col >= Sapiens.field.size or next_pos.row < 0 or next_pos.row >= Sapiens.field.size:
        return Sapiens.location
    return next_pos