LCD1602 большие цифры

А что совершенно в этом мире? Атмосфера и та давит! Тем более, осень … “выйду на улицу, солнца нема, девки молодые …

рациональное мышление зло!))) если слушать мозг постоянно, то можно стать его рабом, и только обслуживать его, нечего не делать почти, а только то что ему нужно для существования!)))

непостоянство как вариант)))

только если мы сожмем все данные во вселенных, и возможно за ее пределами… так много мы брать не будем…
оно будет зависеть от алгоритма сжатия, вообще если удобнее можно начать с алгоритма разжатия, и по аналогии написать алгоритм сжатия, тут вроде не важно с какого конца мы начнем))) из 1 цифры мы же сожем получить 2 ? а если мы знаем алгоритм по которому их получили, то мы сможем же сделать алгоритм который из этих 2 выдаст 1 цифру ? пусть и не всегда…

мы попробуем взять маленький отрезок, но достаточный что бы архимед обогнал черепаху до финиша, или по крайней мере будем фиксировать факт сокращения расстояния, пока не упремся в пределы… хоть это вроде как было и не о данных, но как вариант наверное пойдет для объяснения))

вообще жизнь скучна, и в ней мало смысла, давайте попробуем что то сломать во вселенной и обойти какие то пределы)))один миф говорит о том что когда то люди были великие, потом вмешался бог, и разрушил все, заствавив людей говорить на разных языках, что бы они друг друга не понимали!))) возможно на язык кода не имеет так много трактований, и получится объяснить более подробно на нем
// Функция кодирования четырёх чисел в хеш
uint32_t encodeNumbers(uint8_t A, uint8_t B, uint8_t C, uint8_t D) {
uint32_t combined = ((uint32_t)A << 24) | ((uint32_t)B << 16) | ((uint32_t)C << 8) | D;
// Битовое перемешивание (меняем местами соседние биты)
uint32_t mixed = 0;
for (uint8_t i = 0; i < 32; i++) {
uint8_t new_pos = (i % 2 == 0) ? i + 1 : i - 1;
if (new_pos < 32) {  // Убедимся, что не выходим за границы
mixed |= ((combined >> i) & 0x1) << new_pos;
}
}
// XOR с 32-битной маской
mixed ^= 0x5A5A5A5A;
return mixed;
}

// Функция декодирования хеша в четыре числа
void decodeNumbers(uint32_t hash, uint8_t *A, uint8_t *B, uint8_t *C, uint8_t *D) {
uint32_t mixed = hash;
mixed ^= 0x5A5A5A5A;  // Обратный XOR
// Обратное битовое перемешивание
uint32_t combined = 0;
for (uint8_t i = 0; i < 32; i++) {
uint8_t original_pos = (i % 2 == 0) ? i + 1 : i - 1;
if (original_pos < 32) {  // Убедимся, что не выходим за границы
combined |= ((mixed >> original_pos) & 0x1) << i; }
} 
*A = (combined >> 24) & 0xFF;
*B = (combined >> 16) & 0xFF;
*C = (combined >> 8)  & 0xFF;
*D = combined & 0xFF;
}

void setup() {
Serial.begin(9600);
  
// === Тест кодирования (A=12, B=97, C=45, D=200) ===
uint8_t A = 200;
uint8_t B = 200;
uint8_t C = 200;
uint8_t D = 200;
  
uint32_t hash = encodeNumbers(A, B, C, D);
Serial.print("Закодировано: A="); Serial.print(A);
Serial.print(", B="); Serial.print(B);
Serial.print(", C="); Serial.print(C);
Serial.print(", D="); Serial.print(D);
Serial.print(" → Хеш="); Serial.println(hash, HEX);  // Вывод в HEX для удобства
  
// === Тест декодирования ===
uint8_t decoded_A, decoded_B, decoded_C, decoded_D;
decodeNumbers(hash, &decoded_A, &decoded_B, &decoded_C, &decoded_D);
  
Serial.print("Декодировано: Хеш="); Serial.print(hash, HEX);
Serial.print(" → A="); Serial.print(decoded_A);
Serial.print(", B="); Serial.print(decoded_B);
Serial.print(", C="); Serial.print(decoded_C);
Serial.print(", D="); Serial.println(decoded_D);
}

void loop() {}

вот если бы компьютер умел работать только с десятичными числами, и не понимал 16ричную систему, это ли не сокращение ?))) правда тут нельзя вставить долее 255… но это уже совсем другая история))) и 0x5A5A5A5A необязательно писать, его можно запомнить!

Вот например набор кубиков для покера, 6 самописных символов и один штатный. Может придумается более оригинальный вариант отрисовки :slight_smile:

“Никогда не понимал правила бейсбола”(с)

1 лайк

Не, там всё просто…когда таблица на руках :slight_smile:

Играю очень редко, но правила не забываются. Мне она нравится невозможностью не сделать выбор.

:slight_smile:

Вот думаю сюжет как скрестить пятнашки и тетрис.

Придумал, назовём игру Тетрашки.

Задача, имея два пусто-места, собрать из разноцветных квадратиков все тетрамино.

…на чём проще собрать пока не знаю, наверное лучше напечатать фишки на 3Д принтере :slight_smile:

…Где Вы сэр Бабос?, со своим ИИ и ленью. Надо движок придумывать! :slight_smile:

lilik сделать на адресной ленте(панели) ?)))
5 кнопок, 4 для управления 1 для поднять положить…

вот про лень это верно подмечено)))
джойстик такой есть ?
https://roboshop.spb.ru/modules/klaviatury-i-knopki/ky-023

это мы в рыцарей играем ?))

#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;
int orangeX = 3;
int orangeY = 3;
int redX = 4;
int redY = 2;

bool isCarryingOrange = false;
bool isCarryingRed = false;
bool lastButtonState = HIGH;
bool buttonPressed = false;

void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(50);
pinMode(BUTTON_PIN, INPUT_PULLUP);

updateDisplay();
Serial.println("Система готова. Управление пикселями кнопкой на пине 7");
}

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 (!isCarryingOrange && !isCarryingRed && newX == orangeX && newY == orangeY) {
// Поднимаем оранжевый пиксель
isCarryingOrange = true;
Serial.println("Подняли оранжевый пиксель");
}
else if (!isCarryingOrange && !isCarryingRed && newX == redX && newY == redY) {
// Поднимаем красный пиксель
isCarryingRed = true;
Serial.println("Подняли красный пиксель");
}
else if (isCarryingOrange) {
// Отпускаем оранжевый пиксель
isCarryingOrange = false;
orangeX = currentX;
orangeY = currentY;
Serial.println("Поставили оранжевый пиксель");
}
else if (isCarryingRed) {
// Отпускаем красный пиксель
isCarryingRed = false;
redX = currentX;
redY = currentY;
Serial.println("Поставили красный пиксель");
}
}

// Обновление позиции курсора
if (newX != currentX || newY != currentY) {
currentX = newX;
currentY = newY;
updateDisplay();

Serial.print("Курсор: X:"); Serial.print(currentX);
Serial.print(" Y:"); Serial.print(currentY);
if (isCarryingOrange) {
Serial.print(" | Несу оранжевый");
} else if (isCarryingRed) {
Serial.print(" | Несу красный");
}
Serial.println();
}

delay(100);
}

void handleButton() {
bool currentButtonState = digitalRead(BUTTON_PIN);

// Обнаружение нажатия (HIGH -> LOW)
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;
}

// Отрисовка оранжевого пикселя (если не переносится)
if (!isCarryingOrange) {
setPixel(orangeX, orangeY, CRGB::Orange);
}

// Отрисовка красного пикселя (если не переносится)
if (!isCarryingRed) {
setPixel(redX, redY, CRGB::Red);
}

// Отрисовка курсора
if (isCarryingOrange) {
setPixel(currentX, currentY, CRGB::Orange); // Курсор оранжевый когда несем оранжевый
} else if (isCarryingRed) {
setPixel(currentX, currentY, CRGB::Red); // Курсор красный когда несем красный
} else {
setPixel(currentX, currentY, CRGB::Green); // Курсор зеленый когда ничего не несем
}

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;
}

ну начало положено))) чуть позже еще посижу)))
тот модуль все таки работает с нажатой кнопкой, что не удобно для меня… сделал на обычных потенциометрах, а кнопку просто проводом замыкаю)))

думаю еще сделать квадрат с анимацией, больше пикселей добавить, и логику победы в случае выстраивания в нужной последовательности, + запретить ставить пиксель на пиксель, и сменять цвет зеленого курсора, если мы подняли пиксель, пока что такие планы)))

Нужно посмотреть на эту игру по другому. В реальных пятнашках мы двигаем нумерованные фишки в пусто-место. Но у нас абстракция, матрица или сенсорный дисплей. И тут мы можем двигать пусто-место. Да, это ломает восприятие и требует времени на игровую адаптацию, но делает игру интересней, а навигацию упрощённой.

…надо два джойстика под движения двух пусто-мест одновременно или один джойстик, а кнопка для перескакивания в навигации с одного пусто-места на другое.

…удобнее иметь массив- модель игрового поля, где фишки это элементы- цифры по цветам 1,2,3…, а пусто-места это 0.

я тут ломаю голову над цветом, что бы и 8 цветов сделать, черный для пустых ячеек, и цвет для курсора, а цвета многие очень похожи друг на друга, у вас нет случайно значений ргб ? что бы цвета точно различались на матрице, не спал еще))) в голове уже туман,вот последняя версия кода, пошел я спать)))

#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;

// Массив перемещаемых пикселей
struct MovablePixel {
int x;
int y;
CRGB color;
bool isCarried;
};

MovablePixel pixels[] = {
// Красные пиксели (4 шт)
{2, 2, CRGB::Red, false},
{4, 1, CRGB::Red, false},
{1, 4, CRGB::Red, false},
{5, 3, CRGB::Red, false},

// Синие пиксели (4 шт)
{3, 1, CRGB::Blue, false},
{6, 2, CRGB::Blue, false},
{2, 5, CRGB::Blue, false},
{5, 5, CRGB::Blue, false},

// Фиолетовые пиксели (4 шт)
{1, 2, CRGB::Purple, false},
{4, 4, CRGB::Purple, false},
{6, 1, CRGB::Purple, false},
{3, 5, CRGB::Purple, false},

// Голубые пиксели (4 шт)
{2, 3, CRGB::Cyan, false},
{5, 2, CRGB::Cyan, false},
{1, 1, CRGB::Cyan, false},
{6, 5, CRGB::Cyan, false},

// Желтые пиксели (4 шт)
{3, 3, CRGB::Yellow, false},
{4, 5, CRGB::Yellow, false},
{1, 3, CRGB::Yellow, false},
{6, 3, CRGB::Yellow, false},

// Белые пиксели (4 шт)
{4, 3, CRGB::White, false},
{2, 1, CRGB::White, false},
{5, 1, CRGB::White, false},
{3, 4, CRGB::White, false},

// Розовые пиксели (4 шт) - новый цвет
{2, 4, CRGB::Pink, false},
{4, 2, CRGB::Pink, false},
{1, 5, CRGB::Pink, false},
{6, 4, CRGB::Pink, false}
};

const int NUM_PIXELS = 28;

bool lastButtonState = HIGH;
bool buttonPressed = false;
int carriedPixelIndex = -1;

void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(50);
pinMode(BUTTON_PIN, INPUT_PULLUP);

updateDisplay();
Serial.println("Система готова. Управление пикселями кнопкой на пине 7");
}

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;
Serial.print("Подняли пиксель цвета: ");
printColorName(pixels[i].color);
updateDisplay();
break;
}
}
} else {
// Проверяем, можно ли поставить пиксель на эту позицию
if (canPlacePixel(currentX, currentY)) {
// Отпускаем пиксель
pixels[carriedPixelIndex].isCarried = false;
pixels[carriedPixelIndex].x = currentX;
pixels[carriedPixelIndex].y = currentY;
Serial.print("Поставили пиксель цвета: ");
printColorName(pixels[carriedPixelIndex].color);
carriedPixelIndex = -1;
updateDisplay();
} else {
Serial.println("Нельзя поставить пиксель - ячейка занята!");
}
}
}

if (newX != currentX || newY != currentY) {
currentX = newX;
currentY = newY;
updateDisplay();

Serial.print("Курсор: X:"); Serial.print(currentX);
Serial.print(" Y:"); Serial.print(currentY);
if (carriedPixelIndex != -1) {
Serial.print(" | Несу ");
printColorName(pixels[carriedPixelIndex].color);
}
Serial.println();
}

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::Green);
}

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;
}

void printColorName(CRGB color) {
if (color == CRGB::Red) Serial.print("Красный");
else if (color == CRGB::Blue) Serial.print("Синий");
else if (color == CRGB::Purple) Serial.print("Фиолетовый");
else if (color == CRGB::Cyan) Serial.print("Голубой");
else if (color == CRGB::Yellow) Serial.print("Желтый");
else if (color == CRGB::White) Serial.print("Белый");
else if (color == CRGB::Pink) Serial.print("Розовый");
else Serial.print("Неизвестный");
} 

Утро вечера мудренее.

Ярко видимо слишком, надо бумагу белую на матрицу положить.

…решил из опилок вариант для макетирования тетрашек сделать.

Не спеши, сначала просто механика игры и сценарии:

Например уровни-задания:

  1. Собрать заданный комплект тетрамино

  2. Переставить фигуры тетрамино местами в полученном наборе

  3. Перекрасить фигуры в полученной расстановке

Только сначала предложить пройти тест!

1 лайк

В первом круге цифры не вижу.

Да и 8 спорная с тройкой :slight_smile:

Ну вооот. :grinning_face:
Не, восьмерка явная.

а пойдет если пиксели просто передвигать будем ?
ведь если пустота там, поставить можно, а как двигать пустоту, я это что то не знаю как кодом описать)))
только посмотрел что такое 15ки))) сейчас подумаю над функцией переноса пикселя только на 1 ячейку, и если там пустота(а то пока что в любое место переносится))) )

ну я пока что на потенциометрах, пока логика не готова, и сенсорного дисплея нет, а вы потом переделаете под ваш tft сенсорный ?)))

и еще вопросы, расстановку как делать рандомно ? или в форме фигур тетриса ?
алгоритм для победы какой ? условие выставить по горизонтали и вертикали 4 пикселя не надо писать ? нужен другой ? например точная последовательность фигур и цветов, заданная в программе или как ?

мне бы сначала некий код накидать, что бы понимать, а потом думать уже))) я как правило так пишу, а потом переписываю, иногда раза по 3 заново)))

Во так во, надо.