Skip to content

Instantly share code, notes, and snippets.

@thata
Created January 27, 2017 01:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thata/eb4b30047845a961afee4a64d72cae85 to your computer and use it in GitHub Desktop.
Save thata/eb4b30047845a961afee4a64d72cae85 to your computer and use it in GitHub Desktop.
Arduinoと8x8マトリクスLEDでライフゲーム
#include <avr/io.h>
#include <avr/interrupt.h>
const static int rows[8] = { 2, 3, 4, 5, 6, 7, 8, 9 };
const static int cols[8] = { 10, 11, 12, 13, 14, 15, 16, 17 };
// LifeGame
boolean cells[8][8] = {
{ 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 1, 0, 0, 0, 0 },
{ 0, 1, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
};
void next_generation() {
boolean new_cells[8][8] = {
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
};
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
new_cells[y][x] = next_generation_cell(x, y);
}
}
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
cells[y][x] = new_cells[y][x];
}
}
}
int neighbors(int x, int y) {
int n = 0;
int _x = 0;
int _y = 0;
// left
_x = (x == 0) ? 7: (x - 1);
_y = y;
if (is_alive(_x, _y)) {
n += 1;
}
// right
_x = (x == 7) ? 0: (x + 1);
_y = y;
if (is_alive(_x, _y)) {
n += 1;
}
// up
_x = x;
_y = (y == 0) ? 7: y - 1;
if (is_alive(_x, _y)) {
n += 1;
}
// down
_x = x;
_y = (y == 7) ? 0: y + 1;
if (is_alive(_x, _y)) {
n += 1;
}
// upleft
_x = (x == 0) ? 7: (x - 1);
_y = (y == 0) ? 7: y - 1;
if (is_alive(_x, _y)) {
n += 1;
}
// upright
_x = (x == 7) ? 0: (x + 1);
_y = (y == 0) ? 7: y - 1;
if (is_alive(_x, _y)) {
n += 1;
}
// downleft
_x = (x == 0) ? 7: (x - 1);
_y = (y == 7) ? 0: y + 1;
if (is_alive(_x, _y)) {
n += 1;
}
// downright
_x = (x == 7) ? 0: (x + 1);
_y = (y == 7) ? 0: y + 1;
if (is_alive(_x, _y)) {
n += 1;
}
return n;
}
boolean is_alive(int x, int y) {
return cells[y][x];
}
boolean next_generation_cell(int x, int y) {
if (is_alive(x, y)) {
if (neighbors(x, y) < 2 || neighbors(x, y) >= 4) {
// 2未満、4以上は死
return false;
} else {
// それ以外はそのまま
return true;
}
} else {
if (neighbors(x, y) == 3) {
// 3の場合は誕生
return true;
} else {
// それ以外はそのまま
return false;
}
}
}
void randomCell() {
// ランダムで初期化
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
cells[y][x] = random(2) == 0;
}
}
}
// Arduino
void setup() {
for (int i = 0; i < 8; i++) {
pinMode(rows[i], OUTPUT);
digitalWrite(rows[i], LOW);
pinMode(cols[i], OUTPUT);
digitalWrite(cols[i], HIGH);
}
// randomize cell
randomSeed(analogRead(18));
// randomCell();
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count:
// OCR1A = 15624; // 1sec
OCR1A = 15624 / 2; // 0.5sec
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
sei(); // enable global interrupts
}
void loop() {
// 1行ごとに表示を行う
for (int i = 0; i < 8; i++) {
// ひとつ前の行を消灯する
int last = (i == 0) ? 7 : i - 1;
digitalWrite(rows[last], LOW);
// 点灯する列を指定する
for (int j = 0; j < 8; j++) {
// digitalWrite(cols[j], !matrix[i][j]);
digitalWrite(cols[j], !cells[i][j]);
}
// 現在の行を点灯する
digitalWrite(rows[i], HIGH);
delayMicroseconds(300);
}
}
ISR(TIMER1_COMPA_vect)
{
// cells[1][1] = !cells[1][1];
next_generation();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment