keymap.c (3497B)
1 /* Copyright 2023 Tom Parker-Shemilt <palfrey@tevp.net> 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, version 3 of the License. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 */ 15 16 #include <stdlib.h> 17 18 #include QMK_KEYBOARD_H 19 20 // clang-format off 21 22 // Exact keymap is irrelevant as we're using rows/cols 23 // but we need _something_ set so we're using no-ops 24 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 25 [0] = LAYOUT( 26 KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, 27 KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, 28 KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, 29 KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, 30 KC_NO, KC_NO, KC_NO, KC_NO, KC_NO 31 )}; 32 33 bool tiles[5][5] = { 34 {false, false, false, false, false}, 35 {false, false, false, false, false}, 36 {false, false, false, false, false}, 37 {false, false, false, false, false}, 38 {false, false, false, false, false}, 39 }; 40 41 /* Because snake pattern of leds */ 42 const uint8_t remap[25] = { 43 20,21,22,23,24, 44 19,6,7,8,9, 45 18,5,0,1,10, 46 17,4,3,2,11, 47 16,15,14,13,12, 48 }; 49 50 // clang-format on 51 52 bool is_blank(void) { 53 for (uint8_t y = 0; y < 5; y++) { 54 for (uint8_t x = 0; x < 5; x++) { 55 if (tiles[x][y]) { 56 return false; 57 } 58 } 59 } 60 return true; 61 } 62 63 void do_move(uint8_t x, uint8_t y) { 64 tiles[x][y] ^= true; 65 if (x > 0) { 66 tiles[x - 1][y] ^= true; 67 } 68 if (y > 0) { 69 tiles[x][y - 1] ^= true; 70 } 71 if (x < 4) { 72 tiles[x + 1][y] ^= true; 73 } 74 if (y < 4) { 75 tiles[x][y + 1] ^= true; 76 } 77 } 78 79 void refresh_leds(void) { 80 for (uint8_t y = 0; y < 5; y++) { 81 for (uint8_t x = 0; x < 5; x++) { 82 uint8_t tile = tiles[x][y]; 83 uint8_t index = (y * 5) + x; 84 if (tile) { 85 rgblight_setrgb_at(RGB_RED, remap[index]); 86 } else { 87 rgblight_setrgb_at(RGB_WHITE, remap[index]); 88 } 89 } 90 } 91 rgblight_set(); 92 } 93 94 uint8_t initial_moves = 1; 95 96 void start_game(void) { 97 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); 98 srand(timer_read32()); 99 while (true) { 100 for (uint8_t i = 0; i < initial_moves; i++) { 101 do_move(rand() % 5, rand() % 5); 102 } 103 if (!is_blank()) { 104 // Catch the "we picked the same location 2*N times" case 105 break; 106 } 107 } 108 refresh_leds(); 109 } 110 111 void keyboard_post_init_user(void) { 112 rgblight_enable_noeeprom(); 113 start_game(); 114 } 115 116 bool won = false; 117 118 bool process_record_user(uint16_t keycode, keyrecord_t *record) { 119 if (record->event.pressed) { 120 if (won) { 121 initial_moves++; 122 won = false; 123 start_game(); 124 } else { 125 uint8_t x = record->event.key.col; 126 uint8_t y = record->event.key.row; 127 do_move(x, y); 128 if (is_blank()) { 129 rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL); 130 won = true; 131 } 132 } 133 } 134 refresh_leds(); 135 return true; 136 }