A Simulation Framework for the Teaching and Learning of Distributed Algorithms