Interessante Sache, kannte ich bisher noch nicht.
Meine Idee:
Du solltest erst einmal deine Daten von allem visuellen trennen. Die Struktur der Daten würde ich wie folgt machen: Du erstellst eine Klasse (ein Quadrat deines Spielfeldes) mit vier Objekten vom Typ der erstellten Klasse - je ein Feld pro Himmelsrichtung. Dann brauchst du noch ein Objekt mit dem Typ einer Spielfigur.
Die Spielfigur erstellst du später auch als Klasse. Diese kann entweder Hai, Fisch oder Wasser sein (könnte man als String in der Klasse hinterlegen). Sie enthält Informationen zum Fressstand und alles nötige für den Spielablauf. Positionen würde ich dort nicht hinterlegen.
Jetzt weiter zu deinen Quadraten. Du baust dir dein Spielfeld einmal während der Initialisierung zusammen indem du Quadrate erzeugst und zu einem großen Feld zusammenkettest. Hierzu benötigst du deine 4 Verweise mit den Himmelsrichtungen. Wie genau du das angehst, ist egal.
Bewegung entsteht dadurch, dass du einem Verweis des Quadrates folgst, das Spielfigur-Objekt deines Quadrates auf das Zielfeld schreibst und dann das Objekt deines Ausgangsfeldes löschst. Was bei Kollisionen passiert, steht in den Regeln geschrieben. All das kannst du in einer Methode "move" umsetzen. Ich würde der Klasse Quadrat eine solche Methode bereitstellen.
Um dein Spielfeld kannst du jetzt eine weitere Klasse bauen, welche die wichtigen Aufgaben erfüllt. Sie steuert die Bewegungen und die Grafik. Für die Bewegungen würde ich wie du vorschlägst, einen Timer verwenden. Bei jedem Tick durchläuft die Klasse einfach alle Quadrate und führt "move" aus.
Das Zeichnen wird nicht stark auf die Performance gehen. Du könntest ein Schachbrett aus Labels, Panels etc. erstellen, welche die Farbe wechseln. Diese wären relativ einfach anzusteuern. Zeichnen mit Rectangles empfinde ich als sehr unangenehm, weil du dir die Positionen irgendwo merken muss. Ist aber wohl eine Glaubenssache.
Ui...viel geschrieben. Da hab ich mich etwas mitreißen lassen