Shifting I2C enable bits through a chain of modules is a smart way of achieving your goal of individually addressing devices without pre-assigning different addresses to each module.
You could eliminate the register by using the microcontroller instead. It looks like you would need a device with a couple more pins on it though - for the enable and clock signals
At the expense of more software complication, you could reduce the clock and enable signals to a single signal, with special signalling. You could send a long pulse to indicate an enable=true and clock=rising-edge simultaneously and then a short pulse to indicate just a clock rising-edge with enable=low. This would require 1 signal in and 1 signal out to the next module. You would then implement the I2C enable/disable in software rather than using a hardware pin connected to the I2C peripheral.
You might just want to keep it simple though :)
Another solution, which may not be feasible using basic hardware, is to have the modules assign themselves their own address using a unique device number. Some devices have manufacture installed unique serial numbers, or you could have true random number generator (not pseudo random). However, for a random generated address to work it would have to be a large address several bytes long to give statistical reliability that addresses don't clash - and there's still the case to handle when there is a clash. Also I2C addresses are only 7-bits long so you would have to add another layer of addressing via I2C data packets to get a long enough address.
For your coursework, I think the approach you have is already a good one.