from typing import List
from typing import Tuple
from typing import Optional


def has_winner(field: List[List[int]]) -> Tuple[bool, Optional[Tuple[int, int]], Optional[Tuple[int, int]]]:
    """
    Checks game for winning (or tie) positions
    :param field: playing field matrix
    :return: Overall answer & position, from where the winning position starts ((0, 0) when tied) &
    winning direction ((0, 0) when tied)
    """
    # directions in which to check winning positions
    dirs = [(0, 1), (1, 0), (1, 1), (1, -1)]

    for i in range(len(field)):
        for j in range(len(field[i])):
            if field[i][j] == 0:
                continue
            for dr in dirs:
                # simply checking an equality of 4 contiguous elements on field
                try:
                    if field[i][j] == field[i + dr[0]][j + dr[1]] == \
                            field[i + 2 * dr[0]][j + 2 * dr[1]] == \
                            field[i + 3 * dr[0]][j + 3 * dr[1]] :
                        return True, (i, j), dr
                # to skip border cases without making some stupidly clever algorithm
                except IndexError:
                    continue

    # checking if any empty cells left after checking winning positions as
    # last move can cause it as well
    draw = True
    for row in field:
        for el in row:
            if not el:
                draw = False
    if draw:
        return True, (0, 0), (0, 0)

    return False, None, None