初始化提交

This commit is contained in:
王立帮
2024-07-20 22:09:06 +08:00
commit c247dd07a6
6876 changed files with 2743096 additions and 0 deletions

View File

@@ -0,0 +1,217 @@
// Implements Conway's Game of Life using MD_MAXPanel library
//
// Hardware used
// =============
// Momentary On push switch on SWITCH_PIN to start a new game. The digital I/O
// will be initialize INPUT_PULLUP
//
// Libraries used
// ==============
// MD_MAX72XX available from https://github.com/MajicDesigns/MD_MAX72XX
//
// Rules of the Game
// =================
// The universe of the Game of Life is an infinite, two-dimensional orthogonal
// grid of square cells, each of which is in one of two possible states,
// alive or dead (or populated and unpopulated). Every cell interacts with
// its eight neighbors, which are the cells that are horizontally, vertically,
// or diagonally adjacent. At each step in time, the following transitions occur:
//
// 1. Any live cell with fewer than two live neighbors dies, as if by under population.
// 2. Any live cell with two or three live neighbors lives on to the next generation.
// 3. Any live cell with more than three live neighbors dies, as if by overpopulation.
// 4. Any dead cell with exactly three live neighbors becomes a live cell, as if
// by reproduction.
//
// The initial pattern constitutes the seed of the system. The first generation is
// created by applying the above rules simultaneously to every cell in the seed;
// births and deaths occur simultaneously, and the discrete moment at which this
// happens is sometimes called a tick. Each generation is a pure function of the
// preceding one. The rules continue to be applied repeatedly to create further
// generations.
//
#include <MD_MAXPanel.h>
#include "randomseed.h"
// Turn on debug statements to the serial output
#define DEBUG 0
#if DEBUG
#define PRINT(s, x) { Serial.print(F(s)); Serial.print(x); }
#define PRINTS(x) { Serial.print(F(x)); }
#define PRINTD(x) { Serial.print(x, DEC); }
#define PRINTXY(s, x, y) { Serial.print(s); Serial.print(F("(")); Serial.print(x); Serial.print(F(",")); Serial.print(y); Serial.print(F(")")); }
#else
#define PRINT(s, x)
#define PRINTS(x)
#define PRINTD(x)
#define PRINTXY(s, x, y)
#endif
// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
const MD_MAX72XX::moduleType_t HARDWARE_TYPE = MD_MAX72XX::FC16_HW;
const uint8_t X_DEVICES = 4;
const uint8_t Y_DEVICES = 5;
const uint8_t CLK_PIN = 13; // or SCK
const uint8_t DATA_PIN = 11; // or MOSI
const uint8_t CS_PIN = 10; // or SS
// SPI hardware interface
MD_MAXPanel mp = MD_MAXPanel(HARDWARE_TYPE, CS_PIN, X_DEVICES, Y_DEVICES);
// Arbitrary pins
// MD_MAXPanel mx = MD_MAXPanel(HARWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, X_DEVICES, Y_DEVICES);
#define SWITCH_PIN 6
// We always wait a bit between updates of the display
#define TICK_TIME 150 // in milliseconds
void setup(void)
{
#if DEBUG
Serial.begin(57600);
#endif
PRINTS("\n[MD_MAXPanel Game of Life]");
pinMode(SWITCH_PIN, INPUT_PULLUP);
mp.begin();
mp.clear();
randomSeed(seedOut(31, RANDOM_SEED_PORT));
}
void loop(void)
{
static uint32_t timeLastRun = 0;
static uint8_t sameCount = 10;
static uint32_t lastCount = 0;
uint32_t count = countCells();
if (lastCount == count) sameCount++; else sameCount = 0;
if (digitalRead(SWITCH_PIN) == LOW || sameCount >= 10)
{
mp.clear(); // mark the end of the display ...
delay(1000); // ... with a minor pause!
firstGeneration();
sameCount = 0;
}
lastCount = count;
// Check if next generation time
if (millis() - timeLastRun >= TICK_TIME)
{
timeLastRun = millis();
nextGeneration();
}
}
uint32_t countCells(void)
{
uint32_t count = 0;
for (uint16_t x = 0; x <= mp.getXMax(); x++)
for (uint16_t y = 0; y <= mp.getYMax(); y++)
count += (mp.getPoint(x,y) ? 1:0);
return(count);
}
void firstGeneration(void)
// Create a 4-way symmetric random setup
{
mp.update(false);
PRINTS("\n-- FIRST Generation");
PRINTXY("\n-- Field size (1,1) - ", mp.getXMax() - 1, mp.getYMax() - 1);
mp.clear();
for (uint16_t x=1; x<(mp.getXMax()+1) / 2; x++)
for (uint16_t y = 1; y < (mp.getYMax()+1) / 2; y++)
{
bool b = (random(101) > 50);
mp.setPoint(x, y, b);
mp.setPoint(mp.getXMax() - x, y, b);
mp.setPoint(x, mp.getYMax() - y, b);
mp.setPoint(mp.getXMax() - x, mp.getYMax() - y, b);
}
mp.update(true);
}
void nextGeneration(void)
// Apply the rules
{
bool rowBuf[2][mp.getXMax()+2];
uint16_t count;
bool newCell;
PRINTS("\n-- NEW generation");
// clear out the row buffers
memset(rowBuf, 0, sizeof(rowBuf));
mp.update(false);
for (uint16_t y=mp.getYMax()-1; y>=1; y--)
{
// copy the current row to the buffer
for (uint16_t x=0; x<mp.getXMax(); x++)
rowBuf[1][x] = mp.getPoint(x, y);
// work out a 'new' current row
for (uint16_t x=1; x<mp.getXMax(); x++)
{
// count the number of neighbours
count = rowBuf[0][x-1] ? 1:0;
count += rowBuf[0][x] ? 1:0;
count += rowBuf[0][x+1]? 1:0;
count += rowBuf[1][x-1]? 1:0;
count += rowBuf[1][x+1]? 1:0;
count += mp.getPoint(x-1, y-1)? 1:0;
count += mp.getPoint(x, y-1) ? 1:0;
count += mp.getPoint(x+1, y-1)? 1:0;
PRINTXY("\n@", x, y);
PRINT(" count=", count);
PRINTS(" ->");
if (count < 2)
{
// A live cell with fewer than two neighbors dies.
newCell = false;
PRINTS("dies.");
}
else if ((count == 2 || count == 3) && mp.getPoint(x, y))
{
// A live cell with two or three neighbors lives on.
newCell = true;
PRINTS("stays.");
}
else if (count == 3 && !mp.getPoint(x, y))
{
// A dead cell with exactly three neighbors becomes live.
newCell = true;
PRINTS("born.");
}
else
{
// A live cell with more than three neighbors dies.
newCell = false;
PRINTS("dies.");
}
mp.setPoint(x, y, newCell);
}
// update the saved row buffers
for (uint16_t x=0; x<=mp.getXMax(); x++)
rowBuf[0][x] = rowBuf[1][x];
}
mp.update(true);
}

View File

@@ -0,0 +1,45 @@
#pragma once
// Random seed creation --------------------------
// Adapted from http://www.utopiamechanicus.com/article/arduino-better-random-numbers/
const uint8_t RANDOM_SEED_PORT = A3; // port read for random seed
uint16_t bitOut(uint8_t port)
{
static bool firstTime = true;
uint32_t prev = 0;
uint32_t bit1 = 0, bit0 = 0;
uint32_t x = 0, limit = 99;
if (firstTime)
{
firstTime = false;
prev = analogRead(port);
}
while (limit--)
{
x = analogRead(port);
bit1 = (prev != x ? 1 : 0);
prev = x;
x = analogRead(port);
bit0 = (prev != x ? 1 : 0);
prev = x;
if (bit1 != bit0)
break;
}
return(bit1);
}
uint32_t seedOut(uint16_t noOfBits, uint8_t port)
{
// return value with 'noOfBits' random bits set
uint32_t seed = 0;
for (int i = 0; i<noOfBits; ++i)
seed = (seed << 1) | bitOut(port);
return(seed);
}
//------------------------------------------------------------------------------