def pretty_world(W, goal_list=[], init_list=[], env_init_list=[],
                 simresult=None,
                 show_grid=False):
    """Given world matrix W, return pretty-for-printing string.

    If simresult is not None, it should be a pair consisting of a list
    of locations (signifying a path) and a failed-but-desired end
    location.  These are exactly returned by the function dsim.  If
    simresult contains a third element, it is regarded as a list of
    obstacle locations.  Also, if the second element is True, then we
    assume a failure did not occur and print the last vehicle location
    as a "O".

    If goal_list or init_list are nonempty, "G" and "I" symbols are
    inserted into the pretty map as appropriate.

    If env_init_list is nonempty, "E" is inserted where appropriate.
    
    If show_grid is True, then grid the pretty world and show row and
    column labels along the outer edges.

    Return None on failure (or lame arguments).
    """
    if W is None:
        return None
    W = W.copy()  # Think globally, act locally.
    # Fill in W with magic values if simresult is given.
    # LEGEND:
    #    1 - "*" wall (as used in original world matrix definition);
    #    2 - "." regularly visited location;
    #    3 - "X" desired but failed location, was occupied;
    #    4 - "?" desired but failed location, was not occupied;
    #    5 - "O" last location, no failure;
    #    6 - "!" obstacle (dynamic, adversarial);
    #   10 - "G" goal location;
    #   11 - "I" possible initial location.
    #   12 - "E" possible initial location.
    if simresult is not None:
        for loc in simresult[0]:
            if W[loc[0]][loc[1]] != 0 and W[loc[0]][loc[1]] != 2:
                raise ValueError("Mismatch between given simresult and world at " \
                                     + "("+str(loc[0])+", "+str(loc[1])+")")
            W[loc[0]][loc[1]] = 2
        if simresult[1] is True:
            W[simresult[0][-1][0]][simresult[0][-1][1]] = 5
        else:
            if W[simresult[1][0]][simresult[1][1]] == 0:
                W[simresult[1][0]][simresult[1][1]] = 4
            else:
                W[simresult[1][0]][simresult[1][1]] = 3
        if len(simresult) > 2:
            for loc in simresult[2]:
                W[loc[0]][loc[1]] = 6
    if show_grid:
        out_str = "  " + "".join([str(k).rjust(2) for k in range(W.shape[1])]) + "\n"
    else:
        out_str = "-"*(W.shape[1]+2) + "\n"
    if (goal_list is not None) and len(goal_list) > 0:
        for loc in goal_list:
            W[loc[0]][loc[1]] = 10
    if (init_list is not None) and len(init_list) > 0:
        for loc in init_list:
            W[loc[0]][loc[1]] = 11
    if (env_init_list is not None) and len(env_init_list) > 0:
        for loc in env_init_list:
            W[loc[0]][loc[1]] = 12
    for i in range(W.shape[0]):
        if show_grid:
            out_str += "  " + "-"*(W.shape[1]*2+1) + "\n"
            out_str += str(i).rjust(2)
        else:
            out_str += "|"
        for j in range(W.shape[1]):
            if show_grid:
                out_str += "|"
            if W[i][j] == 0:
                out_str += " "
            elif W[i][j] == 1:
                out_str += "*"
            elif W[i][j] == 2:
                out_str += "."
            elif W[i][j] == 3:
                out_str += "X"
            elif W[i][j] == 4:
                out_str += "?"
            elif W[i][j] == 5:
                out_str += "O"
            elif W[i][j] == 6:
                out_str += "!"
            elif W[i][j] == 10:
                out_str += "G"
            elif W[i][j] == 11:
                out_str += "I"
            elif W[i][j] == 12:
                out_str += "E"
            else:
                raise ValueError("Unrecognized world W encoding.")
        out_str += "|\n"
    if show_grid:
        out_str += "  " + "-"*(W.shape[1]*2+1) + "\n"
    else:
        out_str += "-"*(W.shape[1]+2) + "\n"
    return out_str