def game_moves(board):
    """
    Returns the list of all legal moves available from the current position.

    Moves are represented directly as the resulting game positions.

    If the game is over, it returns an empty list.

    """

    LINES = ((0,1,2),(1,2,3),(4,5,6),(5,6,7),(8,9,10),(9,10,11),(0,4,8),
             (1,5,9),(2,6,10),(3,7,11),(0,5,10),(1,6,11),(2,5,8),(3,6,9))

    # If the game is over: return an empty list
    if any(0 < board[x] == board[y] == board[z] for x,y,z in LINES): return []

    # Otherwise: compute and return a list with all the legal moves
    moves = []
    for i in range(12):
        if board[i] < 3:
            moves.append(tuple(b+1 if i==j else b for j,b in enumerate(board)))
    return moves