import string
import random


def fill_crossword(grid, seed = None, alphabet = string.ascii_uppercase, gap = "."):
    """Replace gaps in grid with random character from alphabet
    :param grid: list of list of characters, base for crossword
    :param seed: number used as seed in RNG
    :param alphabet: string of characters used to generate crossword
    :param gap: character used to indicate space to fill
    :raise ValueError: if arguments have incorrect value
    :raise TypeError: if arguments have incorrect type
    :returns: filled crossword
    """
    if (type(grid) is not list) or (False in [type(row) is list for row in grid]):
        raise TypeError("Incorrect type of crossword")
    if not alphabet.isascii():
        raise TypeError("Alphabet has to be ASCII string")
    if gap in alphabet:
        raise TypeError("Alphabet cannot contain gap")
    if not (gap.isascii() and len(gap)==1):
        raise TypeError("Gap has to be single character")
        
    random.seed(seed)

    crossword = [[(char if gap != char else alphabet[random.randrange(len(alphabet))]) for char in row] for row in grid]
    
    return crossword