допустим сделаю, а тут l,l,l,l,l,l,l выигрышная комбинация после которой грузить одну из 5 следующих в фото ?
+ добавить раскраску в рандомные цвета…вам вообще это пригодится ?
вы же собрались делать это просто на tft дисплее, а у меня на адресной ленте)))
и если не пригодится, тогда у меня вроде теряется смысл делать)))
не знаю получилось или нет,(переход на следующий левел) так как режим читерства я еще не сделал,
а потенциометрами собирать не удобно))
#include <FastLED.h>
#define LED_PIN 6
#define NUM_LEDS 64
#define BUTTON_PIN 7
CRGB leds[NUM_LEDS];
const int MIN_X = 1;
const int MAX_X = 6;
const int MIN_Y = 1;
const int MAX_Y = 5;
const int POT_MIN = 100;
const int POT_MAX = 900;
int currentX = MIN_X;
int currentY = MIN_Y;
byte tetrawin[6][5] = {
{7,7,7,7,0},
{2,2,2,2,0},
{3,3,3,3,1},
{4,4,4,4,1},
{5,5,5,5,1},
{6,6,6,6,1}
};
byte tetra1[6][5] = {
{1,2,2,0,3},
{1,2,2,3,3},
{1,1,5,3,4},
{6,5,5,7,4},
{6,6,5,7,4},
{0,6,7,7,4}
};
byte tetra2[6][5] = {
{1,1,0,2,2},
{1,1,3,2,2},
{4,4,3,5,5},
{4,4,3,5,5},
{6,6,3,7,7},
{6,6,0,7,7}
};
byte tetra3[6][5] = {
{1,2,2,2,3},
{1,1,2,3,3},
{1,0,4,0,3},
{6,4,4,4,5},
{6,6,7,5,5},
{6,7,7,7,5}
};
byte tetra4[6][5] = {
{1,1,2,2,2},
{1,3,0,0,2},
{1,3,4,5,5},
{3,3,4,5,6},
{7,4,4,5,6},
{7,7,7,6,6}
};
byte tetra5[6][5] = {
{1,1,1,0,2},
{1,3,2,2,2},
{7,3,0,4,4},
{7,3,3,5,4},
{7,7,6,5,4},
{6,6,6,5,5}
};
byte (*currentLevel)[5] = tetra1;
int currentLevelNumber = 1;
bool isWinLevel = false;
struct MovablePixel {
int x;
int y;
CRGB color;
bool isCarried;
byte originalColorNum;
};
MovablePixel pixels[30];
int NUM_PIXELS = 0;
bool lastButtonState = HIGH;
bool buttonPressed = false;
int carriedPixelIndex = -1;
CRGB numberToColor(byte num) {
switch(num) {
case 0: return CRGB::Black;
case 1: return CRGB::Red;
case 2: return CRGB::Blue;
case 3: return CRGB::Green;
case 4: return CRGB::Yellow;
case 5: return CRGB::Purple;
case 6: return CRGB::Cyan;
case 7: return CRGB::White;
default: return CRGB::Black;
}
}
void loadLevel(byte level[6][5], bool isWinLevel = false) {
NUM_PIXELS = 0;
if (isWinLevel) {
for (int x = 0; x < 6; x++) {
for (int y = 0; y < 5; y++) {
byte colorNum = level[x][y];
if (colorNum != 0) {
pixels[NUM_PIXELS].x = x + 1;
pixels[NUM_PIXELS].y = y + 1;
pixels[NUM_PIXELS].color = numberToColor(colorNum);
pixels[NUM_PIXELS].originalColorNum = colorNum;
pixels[NUM_PIXELS].isCarried = false;
NUM_PIXELS++;
}
}
}
} else {
// Находим уникальные номера фигур в уровне
byte uniqueFigures[8] = {0};
byte figureCount = 0;
for (int x = 0; x < 6; x++) {
for (int y = 0; y < 5; y++) {
byte figNum = level[x][y];
if (figNum != 0) {
bool found = false;
for (int i = 0; i < figureCount; i++) {
if (uniqueFigures[i] == figNum) {
found = true;
break;
}
}
if (!found) {
uniqueFigures[figureCount++] = figNum;
}
}
}
}
// Перемешиваем цвета 1-7
byte colors[7] = {1,2,3,4,5,6,7};
for (int i = 0; i < 7; i++) {
int j = random(7);
byte temp = colors[i];
colors[i] = colors[j];
colors[j] = temp;
}
// Создаем карту цветов для фигур
byte colorMap[8] = {0};
for (int i = 0; i < figureCount; i++) {
colorMap[uniqueFigures[i]] = colors[i % 7];
}
// Создаем пиксели с правильными цветами
for (int x = 0; x < 6; x++) {
for (int y = 0; y < 5; y++) {
byte originalColorNum = level[x][y];
if (originalColorNum != 0) {
pixels[NUM_PIXELS].x = x + 1;
pixels[NUM_PIXELS].y = y + 1;
pixels[NUM_PIXELS].color = numberToColor(colorMap[originalColorNum]);
pixels[NUM_PIXELS].originalColorNum = originalColorNum;
pixels[NUM_PIXELS].isCarried = false;
NUM_PIXELS++;
}
}
}
}
}
bool checkWinCondition() {
bool occupied[6][5] = {false};
for (int i = 0; i < NUM_PIXELS; i++) {
if (!pixels[i].isCarried) {
int x = pixels[i].x - 1;
int y = pixels[i].y - 1;
if (x >= 0 && x < 6 && y >= 0 && y < 5) {
occupied[x][y] = true;
}
}
}
for (int x = 0; x < 6; x++) {
for (int y = 0; y < 5; y++) {
bool shouldBeOccupied = (tetrawin[x][y] != 0);
bool isOccupied = occupied[x][y];
if (shouldBeOccupied != isOccupied) { return false; }
}
}
return true;
}
void loadRandomTetraLevel() {
int randomLevel = random(1, 6);
switch(randomLevel) {
case 1: currentLevel = tetra1; break;
case 2: currentLevel = tetra2; break;
case 3: currentLevel = tetra3; break;
case 4: currentLevel = tetra4; break;
case 5: currentLevel = tetra5; break;
}
currentLevelNumber = randomLevel;
isWinLevel = false;
loadLevel(currentLevel, false);
Serial.print("Загружен уровень tetra");
Serial.print(randomLevel);
Serial.println(" - все 7 цветов распределены по фигурам");
}
void switchLevel() {
if (isWinLevel) {
loadRandomTetraLevel();
} else {
currentLevel = tetrawin;
isWinLevel = true;
loadLevel(currentLevel, true);
Serial.println("Загружен уровень tetrawin");
}
}
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(50);
pinMode(BUTTON_PIN, INPUT_PULLUP);
loadRandomTetraLevel();
updateDisplay();
Serial.println("Система готова. Соберите tetrawin для перехода на следующий уровень");
}
void loop() {
int potX = analogRead(A2);
int potY = analogRead(A1);
int newX = convertToCoordinate(potX, MIN_X, MAX_X);
int newY = convertToCoordinate(potY, MIN_Y, MAX_Y);
handleButton();
if (buttonPressed) {
if (carriedPixelIndex == -1) {
for (int i = 0; i < NUM_PIXELS; i++) {
if (!pixels[i].isCarried && newX == pixels[i].x && newY == pixels[i].y) {
carriedPixelIndex = i;
pixels[i].isCarried = true;
updateDisplay();
break;
}
}
} else {
if (canPlacePixel(currentX, currentY)) {
pixels[carriedPixelIndex].isCarried = false;
pixels[carriedPixelIndex].x = currentX;
pixels[carriedPixelIndex].y = currentY;
carriedPixelIndex = -1;
updateDisplay();
if (checkWinCondition()) {
if (isWinLevel) {
Serial.println("=== ПОБЕДА! Переход на уровень tetra ===");
} else {
Serial.println("=== ПОБЕДА! Переход на уровень tetrawin ===");
}
delay(2000);
switchLevel();
}
} else {
Serial.println("Нельзя поставить пиксель - ячейка занята!");
}
}
}
if (newX != currentX || newY != currentY) {
currentX = newX;
currentY = newY;
updateDisplay();
}
delay(100);
}
bool canPlacePixel(int x, int y) {
for (int i = 0; i < NUM_PIXELS; i++) {
if (!pixels[i].isCarried && pixels[i].x == x && pixels[i].y == y) {
return false;
}
}
return true;
}
void handleButton() {
bool currentButtonState = digitalRead(BUTTON_PIN);
if (lastButtonState == HIGH && currentButtonState == LOW) {
buttonPressed = true;
delay(50);
} else {
buttonPressed = false;
}
lastButtonState = currentButtonState;
}
void updateDisplay() {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Black;
}
for (int i = 0; i < NUM_PIXELS; i++) {
if (!pixels[i].isCarried) {
setPixel(pixels[i].x, pixels[i].y, pixels[i].color);
}
}
if (carriedPixelIndex != -1) {
setPixel(currentX, currentY, pixels[carriedPixelIndex].color);
} else {
setPixel(currentX, currentY, CRGB::Black);
}
FastLED.show();
}
int convertToCoordinate(int potValue, int minCoord, int maxCoord) {
potValue = constrain(potValue, POT_MIN, POT_MAX);
int range = maxCoord - minCoord + 1;
int scaled = (potValue - POT_MIN) * range;
int result = minCoord + scaled / (POT_MAX - POT_MIN + 1);
return constrain(result, minCoord, maxCoord);
}
void setPixel(int x, int y, CRGB color) {
leds[y * 8 + x] = color;
}