In your simulation, I suggest you don't use any of those formulas, and just model mining as though it really is at the base level. Randomly generate a number between 1 and 100000, and if it's below 1000, it's a share. If it's below 10, it's a block.
I thought about doing this. The problem is then I need to process the workers in a parallell fashion. Meaning run multiple threads/processes. This is because now both miners are racing each other. ...
I think you can still simulate their race in sequence by seeing how long each one takes to get something, and compare their "times" to see who won.