Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <OLED_I2C.h>
- #define FULL_SCREEN_HEIGHT 64
- #define FULL_SCREEN_WIDTH 128
- #define WIDTH 24 // 64 по умолчанию
- #define HEIGHT 22 // 22 по умолчанию
- #define CELL_STACK_SIZE (WIDTH*HEIGHT)/8 // Количество байт для хранения всех рисуемых ячеек
- #define DOWN_SHIFT 16 // Сдвиг вниз первой ячейки на пиксели
- #define RANDOM_START true // Рандмоные биты в начале жизни
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- OLED myOLED(A4, A5, A4);
- extern uint8_t SmallFont[];
- byte cell_stack[CELL_STACK_SIZE] = {0}; // Состояние стака из 8 ячеек (вкл/выкл)
- byte cell_point[WIDTH*HEIGHT] = {0}; // Количество очков у каждой ячейки
- int existing_cells = 0;
- byte cell_area = 0; // доступность четырёх внешних ячеек
- #define RIGHT_CELL_EXIST 0b00000001
- #define UP_CELL_EXIST 0b00000010
- #define LEFT_CELL_EXIST 0b00000100
- #define DOWN_CELL_EXIST 0b00001000
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- byte bit_check(int i) { // Проверка указанного бита по номеру
- return cell_stack[i / 8] & 128 >> (i % 8) ;
- }
- void bit_on(int i) { // Поменять бит на 1 по номеру
- cell_stack[i / 8] = cell_stack[i / 8] | ( 128 >> (i % 8) );
- }
- void bit_off(int i) { // Поенять бит на 0 по номеру
- cell_stack[i / 8] = cell_stack[i / 8] ^ ( 128 >> (i % 8) );
- }
- int bit_find(int x, int y) { // Найти номер бита по указанным координатам
- return x + (WIDTH*y);
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- void setup() {
- myOLED.begin();
- myOLED.setFont(SmallFont);
- if (RANDOM_START) {
- for (int i = 0; i < CELL_STACK_SIZE; i++) {
- cell_stack[i] = random(0,256);
- }
- }
- else {
- bit_on( bit_find(1,1) );
- bit_on( bit_find(2,1) );
- bit_on( bit_find(3,1) );
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- void loop() {
- if (millis() % 250 == 0) { // Длительность паузы перед следующим обновлением
- delay(1);
- myOLED.clrScr();
- existing_cells = 0;
- for (int i = 0; i < CELL_STACK_SIZE*8; i++) {
- if ( bit_check(i) ) {
- myOLED.drawRect( (i % WIDTH)*2, (2*i)/WIDTH + DOWN_SHIFT,
- ( (i % WIDTH)*2) + 1, (2*i)/WIDTH + 1 + DOWN_SHIFT );
- existing_cells++;
- }
- cell_point[i] = 0; // Обнуление поинтов каждой ячейки в начале каждого шага
- cell_area = 0b00000000;
- ///////////////////////////// Поиск существующих ячеек
- if ( i/WIDTH != HEIGHT - 1) {
- cell_area = cell_area | DOWN_CELL_EXIST;
- }
- if ( i/WIDTH != 0) {
- cell_area = cell_area | UP_CELL_EXIST;
- }
- if ( i % WIDTH != WIDTH - 1) {
- cell_area = cell_area | RIGHT_CELL_EXIST;
- }
- if ( i % WIDTH != 0) {
- cell_area = cell_area | LEFT_CELL_EXIST;
- }
- ////////////////////////////// Поиск живых ячеек
- if (cell_area & DOWN_CELL_EXIST) {
- if ( bit_check(i+WIDTH) ) {
- cell_point[i]++;
- }
- if ( (cell_area & LEFT_CELL_EXIST) && ( bit_check(i+WIDTH-1) ) ) {
- cell_point[i]++;
- }
- if ( (cell_area & RIGHT_CELL_EXIST) && ( bit_check(i+WIDTH+1) ) ) {
- cell_point[i]++;
- }
- }
- if (cell_area & UP_CELL_EXIST) {
- if ( bit_check(i-WIDTH) ) {
- cell_point[i]++;
- }
- if ( (cell_area & LEFT_CELL_EXIST) && ( bit_check(i-WIDTH-1) ) ) {
- cell_point[i]++;
- }
- if ( (cell_area & RIGHT_CELL_EXIST) && ( bit_check(i-WIDTH+1) ) ) {
- cell_point[i]++;
- }
- }
- if (cell_area & LEFT_CELL_EXIST) {
- if ( bit_check(i-1) ) {
- cell_point[i]++;
- }
- }
- if (cell_area & RIGHT_CELL_EXIST) {
- if ( bit_check(i+1) ) {
- cell_point[i]++;
- }
- }
- } // Конец цикла
- for (int i = 0; i < CELL_STACK_SIZE*8; i++) {
- if (!bit_check(i) && cell_point[i] == 3) { // Правило рождения
- bit_on(i);
- }
- else if ( bit_check(i) && (cell_point[i] != 2 && cell_point[i] != 3) ) { // Правило смерти
- bit_off(i);
- }
- }
- myOLED.print("EXISTING CELLS: ",1,4);
- myOLED.printNumI(existing_cells,95,4);
- myOLED.drawLine(0,DOWN_SHIFT-1,FULL_SCREEN_WIDTH-1,DOWN_SHIFT-1);
- myOLED.update();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment