How can I avoid two trials in a row that belong to the same condition?

What I do for prospective memory tasks, where there are a small number of targets within a larger number of filler trials, is I load them into two lists and have a random gap between target trials. In your case you would need an average of about two go trials in between each no-go trial so you could shuffle a list containing 28 1s, 28 2s and 28 3s and then use pop() to select the last item from that list for the gap after each no-go trial.

Have a look at my Complex Randomisation demo as a possible way to set this up. The demo shows how to do CVC, but you might want to shuffle equal numbers of GN, GGN and GGGN.