//Langton's ant
//details here: https://www.youtube.com/watch?v=qZRYGxF6D3w
#define SCREEN_WIDTH 320 // Largeur de l'écran TFT
#define SCREEN_HEIGHT 240 // Hauteur de l'écran TFT
#include "ioDef.h"
#define WOKWI
//#define HARDWARE
#if defined(WOKWI)
#include "wokwiDef.h"
#define CELLXY 5
#elif defined HARDWARE
#include "hardwareDef.h"
#define CELLXY 2
#else
#error “Mode non pris en charge sélection!”
#endif
#define GRIDX SCREEN_WIDTH/CELLXY
#define GRIDY SCREEN_HEIGHT/CELLXY
#define GEN_DELAY 0
bool dbg = false;
// Grille actuelle
uint8_t grid[GRIDX][GRIDY];
// Nombre de générations
#define NUMGEN 12000
uint16_t genCount = 0;
int x = GRIDX/2; // Position initiale de la fourmi
int y = GRIDY/2;
void setup() {
Serial.begin(9600);
delay(100);
Serial.print("Débogage série prêt"); Serial.println(" ");
#if defined(WOKWI)
tft.begin();
tft.setRotation(1);
#elif defined HARDWARE
tft.init();
tft.setRotation(0); // Nécessaire pour lire de gauche à droite avec l'USB à droite
tft.fillScreen(TFT_BLACK);
writeTitle(); // Effacer seulement sur le matériel, trop lent sur Wokwi
delay(1000);
#endif
}
void loop() {
initGrid();
int dirX = 0; // Direction initiale de la fourmi
int dirY = 1;
computeAnt(dirX, dirY);
while (true) {}; // Arrêter la boucle lorsque les générations sont terminées
}
// Affiche un écran de titre simple
void writeTitle(void) {
tft.setTextSize(2);
tft.setTextColor(TFT_WHITE);
tft.setCursor(10, 10);
tft.println("Fourmi de Langton");
tft.setTextSize(1);
tft.setCursor(10, 40);
tft.println("Appuyez sur n'importe quelle touche pour commencer");
}
// Initialise le tableau de la grille avec des 0
void initGrid(void) {
for (int i = 0; i < GRIDX; i++) {
for (int j = 0; j < GRIDY; j++) {
grid[i][j] = 0;
}
}
}
// Calcule le mouvement de la fourmi
void computeAnt(int dirX, int dirY) {
uint16_t color = TFT_WHITE;
int newDirX, newDirY;
for (int16_t i = 1; i < NUMGEN; i++) {
if (dbg) {Serial.print("x= "); Serial.print(x); Serial.print(" y= "); Serial.println(y);}
if (grid[x][y] == 1) { // Si la case est blanche, tourner à droite
if (dbg) {Serial.print("Case blanche, tourner à droite ");}
newDirX = dirY;
newDirY = -dirX;
grid[x][y] = 0; // Inverser la couleur
} else { // Si la case est noire, tourner à gauche
if (dbg) {Serial.print("Case noire, tourner à gauche ");}
newDirX = -dirY;
newDirY = dirX;
grid[x][y] = 1; // Inverser la couleur
}
if (grid[x][y] == 1) {color = TFT_WHITE;} else {color = TFT_BLACK;}
tft.fillRect(x * CELLXY, y * CELLXY, CELLXY, CELLXY, color);
if (dbg) {Serial.print("newDirX= "); Serial.print(newDirX); Serial.print(" newDirY= "); Serial.println(newDirY);}
dirX = newDirX;
dirY = newDirY;
x += dirX;
y += dirY;
if (x < 0 || x >= GRIDX || y < 0 || y >= GRIDY) {
break; // Arrêter la boucle lorsque les limites de l'écran sont atteintes
}
genDelay(GEN_DELAY);
}
}
// Délai entre les générations
void genDelay(uint16_t ms) {
delay(ms);
}