PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RP6Control M32: Conway's Game Of Life



Dirk
29.04.2011, 19:40
Wenn der Motortreiber des RP6 mal heiss gelaufen ist, kann man auch ein Spielchen machen, bei dem der RP6 nicht rumfährt.
Das "Game Of Life" von 1970 ist eine einfache Simulation von Zellwachstum.
Siehe: http://de.wikipedia.org/wiki/Conways_Spiel_des_Lebens

Das Programm zeigt das "Spielfeld" im Terminalfenster des RP6Loaders.

Bei jedem Schritt (jede Sekunde) entsteht die nächste Generation von Zellen.

Anfangs kann man Zellen "aussähen". Dafür gibt es 7 Funktionen mit Anfangsmustern, von denen man sich im Quelltext eine aussuchen kann,- man kann aber auch eigene Muster ergänzen.

Viel Spaß!

/*
* ************************************************** **************************
* RP6 ROBOT SYSTEM - RP6 CONTROL M32 TESTS
* ************************************************** **************************
* Example: Game Of Life
* Author(s): Dirk
* ************************************************** **************************
* Description:
* This program for RP6 Control simulates J. H. Conway's "Game Of Life". 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, live or
* dead. Every cell interacts with its eight neighbours, 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 neighbours dies, as if caused by
* under-population.
* 2. Any live cell with two or three live neighbours lives on to the next
* generation.
* 3. Any live cell with more than three live neighbours dies, as if by
* overcrowding.
* 4. Any dead cell with exactly three live neighbours 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 (in other words, each
* generation is a pure function of the preceding one). The rules continue to
* be applied repeatedly to create further generations.
*
* You will find further information here:
* http://en.wikipedia.org/wiki/Conway's_Game_of_Life
*
* ################################################## ##########################
* The Robot does NOT move in this example! You can simply put it on a table
* next to your PC and you should connect it to the PC via the USB Interface!
* ################################################## ##########################
* ************************************************** **************************
*/
/************************************************** ***************************/
// Includes:
#include "RP6ControlLib.h" // The RP6 Control Library.
// Always needs to be included!
/************************************************** ***************************/
// Defines:
#define GRID_WIDTH 41 // Grid width
#define GRID_HEIGHT 21 // Grid height
#define STEPPING 1000 // New generation every 1000ms
/************************************************** ***************************/
// Variables:
uint8_t grid_actual[GRID_WIDTH][GRID_HEIGHT]; // Actual grid
uint8_t grid_backup[GRID_WIDTH][GRID_HEIGHT]; // Backup grid
uint8_t x; // Width index
uint8_t y; // Height index
/************************************************** ***************************/
// Functions:
/**
* SEED CLUSTER
*
* Initial pattern: Simple cell cluster 3x3 in the middle
*
*/
void seedCluster(void)
{
grid_actual[19][9] = 1; // XXX
grid_actual[19][10] = 1; // XXX
grid_actual[19][11] = 1; // XXX
grid_actual[20][9] = 1;
grid_actual[20][10] = 1;
grid_actual[20][11] = 1;
grid_actual[21][9] = 1;
grid_actual[21][10] = 1;
grid_actual[21][11] = 1;
}
/**
* SEED STILL LIVES
*
* Initial pattern: Still lives (Block, Beehive, Loaf, Boat)
*
*/
void seedStillLives(void)
{
// Block:
grid_actual[10][5] = 1; // XX
grid_actual[11][5] = 1; // XX
grid_actual[10][6] = 1;
grid_actual[11][6] = 1;
// Beehive:
grid_actual[30][4] = 1; // XX
grid_actual[31][4] = 1; // X X
grid_actual[29][5] = 1; // XX
grid_actual[32][5] = 1;
grid_actual[30][6] = 1;
grid_actual[31][6] = 1;
// Loaf:
grid_actual[10][14] = 1; // XX
grid_actual[11][14] = 1; // X X
grid_actual[9][15] = 1; // X X
grid_actual[12][15] = 1; // X
grid_actual[10][16] = 1;
grid_actual[12][16] = 1;
grid_actual[11][17] = 1;
// Boat:
grid_actual[29][14] = 1; // XX
grid_actual[30][14] = 1; // X X
grid_actual[29][15] = 1; // X
grid_actual[31][15] = 1;
grid_actual[30][16] = 1;
}
/**
* SEED OSCILLATORS
*
* Initial pattern: Oscillators (Blinker, Toad, Beacon, Pulsar)
*
*/
void seedOscillators(void)
{
// Blinker:
grid_actual[4][5] = 1; // XXX
grid_actual[5][5] = 1;
grid_actual[6][5] = 1;
// Toad:
grid_actual[35][5] = 1; // XXX
grid_actual[36][5] = 1; // XXX
grid_actual[37][5] = 1;
grid_actual[34][6] = 1;
grid_actual[35][6] = 1;
grid_actual[36][6] = 1;
// Beacon:
grid_actual[5][14] = 1; // XX
grid_actual[6][14] = 1; // X
grid_actual[5][15] = 1; // X
grid_actual[8][16] = 1; // XX
grid_actual[7][17] = 1;
grid_actual[8][17] = 1;
// Pulsar:
grid_actual[17][3] = 1; // X X
grid_actual[23][3] = 1; // X X
grid_actual[17][4] = 1; // XX XX
grid_actual[23][4] = 1; //
grid_actual[17][5] = 1; // XXX XX XX XXX
grid_actual[18][5] = 1; // X X X X X X
grid_actual[22][5] = 1; // XX XX
grid_actual[23][5] = 1; //
grid_actual[13][7] = 1; // XX XX
grid_actual[14][7] = 1; // X X X X X X
grid_actual[15][7] = 1; // XXX XX XX XXX
grid_actual[18][7] = 1; //
grid_actual[19][7] = 1; // XX XX
grid_actual[21][7] = 1; // X X
grid_actual[22][7] = 1; // X X
grid_actual[25][7] = 1;
grid_actual[26][7] = 1;
grid_actual[27][7] = 1;
grid_actual[15][8] = 1;
grid_actual[17][8] = 1;
grid_actual[19][8] = 1;
grid_actual[21][8] = 1;
grid_actual[23][8] = 1;
grid_actual[25][8] = 1;
grid_actual[17][9] = 1;
grid_actual[18][9] = 1;
grid_actual[22][9] = 1;
grid_actual[23][9] = 1;
grid_actual[17][11] = 1;
grid_actual[18][11] = 1;
grid_actual[22][11] = 1;
grid_actual[23][11] = 1;
grid_actual[15][12] = 1;
grid_actual[17][12] = 1;
grid_actual[19][12] = 1;
grid_actual[21][12] = 1;
grid_actual[23][12] = 1;
grid_actual[25][12] = 1;
grid_actual[13][13] = 1;
grid_actual[14][13] = 1;
grid_actual[15][13] = 1;
grid_actual[18][13] = 1;
grid_actual[19][13] = 1;
grid_actual[21][13] = 1;
grid_actual[22][13] = 1;
grid_actual[25][13] = 1;
grid_actual[26][13] = 1;
grid_actual[27][13] = 1;
grid_actual[17][15] = 1;
grid_actual[18][15] = 1;
grid_actual[22][15] = 1;
grid_actual[23][15] = 1;
grid_actual[17][16] = 1;
grid_actual[23][16] = 1;
grid_actual[17][17] = 1;
grid_actual[23][17] = 1;
}
/**
* SEED SPACESHIPS
*
* Initial pattern: Spaceships (Glider, LWSS)
*
*/
void seedSpaceships(void)
{
/*
*/
// Glider:
grid_actual[10][4] = 1; // X
grid_actual[11][5] = 1; // X
grid_actual[9][6] = 1; // XXX
grid_actual[10][6] = 1;
grid_actual[11][6] = 1;
// Lightweight spaceship (LWSS):
grid_actual[27][4] = 1; // X X
grid_actual[30][4] = 1; // X
grid_actual[31][5] = 1; // X X
grid_actual[27][6] = 1; // XXXX
grid_actual[31][6] = 1;
grid_actual[28][7] = 1;
grid_actual[29][7] = 1;
grid_actual[30][7] = 1;
grid_actual[31][7] = 1;
}
/**
* SEED GUNS
*
* Initial pattern: Gosper glider gun
*
*/
void seedGuns(void)
{
grid_actual[26][3] = 1; // X
grid_actual[24][4] = 1; // X X
grid_actual[26][4] = 1; // XX XX XX
grid_actual[14][5] = 1; // X X XX XX
grid_actual[15][5] = 1; // XX X X XX
grid_actual[22][5] = 1; // XX X X XX X X
grid_actual[23][5] = 1; // X X X
grid_actual[36][5] = 1; // X X
grid_actual[37][5] = 1; // XX
grid_actual[13][6] = 1;
grid_actual[17][6] = 1;
grid_actual[22][6] = 1;
grid_actual[23][6] = 1;
grid_actual[36][6] = 1;
grid_actual[37][6] = 1;
grid_actual[2][7] = 1;
grid_actual[3][7] = 1;
grid_actual[12][7] = 1;
grid_actual[18][7] = 1;
grid_actual[22][7] = 1;
grid_actual[23][7] = 1;
grid_actual[2][8] = 1;
grid_actual[3][8] = 1;
grid_actual[12][8] = 1;
grid_actual[16][8] = 1;
grid_actual[18][8] = 1;
grid_actual[19][8] = 1;
grid_actual[24][8] = 1;
grid_actual[26][8] = 1;
grid_actual[12][9] = 1;
grid_actual[18][9] = 1;
grid_actual[26][9] = 1;
grid_actual[13][10] = 1;
grid_actual[17][10] = 1;
grid_actual[14][11] = 1;
grid_actual[15][11] = 1;
}
/**
* SEED METHUSALAHS
*
* Initial pattern: Methusalahs (F-pentomino, Diehard, Acorn)
*
*/
void seedMethusalahs(void)
{
// F-pentomino:
grid_actual[10][4] = 1; // XX
grid_actual[11][4] = 1; // XX
grid_actual[9][5] = 1; // X
grid_actual[10][5] = 1;
grid_actual[10][6] = 1;
// Diehard:
grid_actual[33][4] = 1; // X
grid_actual[27][5] = 1; // XX
grid_actual[28][5] = 1; // X XXX
grid_actual[28][6] = 1;
grid_actual[32][6] = 1;
grid_actual[33][6] = 1;
grid_actual[34][6] = 1;
// Acorn:
grid_actual[9][14] = 1; // X
grid_actual[11][15] = 1; // X
grid_actual[8][16] = 1; // XX XXX
grid_actual[9][16] = 1;
grid_actual[12][16] = 1;
grid_actual[13][16] = 1;
grid_actual[14][16] = 1;
}
/**
* SEED INFINITE GROWTH
*
* Initial pattern: Infinite Growth
*
*/
void seedInfiniteGrowth(void)
{
// 10 cells:
grid_actual[13][4] = 1; // X
grid_actual[11][5] = 1; // X XX
grid_actual[13][5] = 1; // X X
grid_actual[14][5] = 1; // X
grid_actual[11][6] = 1; // X
grid_actual[13][6] = 1; // X X
grid_actual[11][7] = 1;
grid_actual[9][8] = 1;
grid_actual[7][9] = 1;
grid_actual[9][9] = 1;
// 5x5 square:
grid_actual[28][4] = 1; // XXX X
grid_actual[29][4] = 1; // X
grid_actual[30][4] = 1; // XX
grid_actual[32][4] = 1; // XX X
grid_actual[28][5] = 1; // X X X
grid_actual[31][6] = 1;
grid_actual[32][6] = 1;
grid_actual[29][7] = 1;
grid_actual[30][7] = 1;
grid_actual[32][7] = 1;
grid_actual[28][8] = 1;
grid_actual[30][8] = 1;
grid_actual[32][8] = 1;
// One cell high:
grid_actual[1][15] = 1; // XXXXXXXX XXXXX XXX XXXXXXX XXXXX
grid_actual[2][15] = 1;
grid_actual[3][15] = 1;
grid_actual[4][15] = 1;
grid_actual[5][15] = 1;
grid_actual[6][15] = 1;
grid_actual[7][15] = 1;
grid_actual[8][15] = 1;
grid_actual[10][15] = 1;
grid_actual[11][15] = 1;
grid_actual[12][15] = 1;
grid_actual[13][15] = 1;
grid_actual[14][15] = 1;
grid_actual[18][15] = 1;
grid_actual[19][15] = 1;
grid_actual[20][15] = 1;
grid_actual[27][15] = 1;
grid_actual[28][15] = 1;
grid_actual[29][15] = 1;
grid_actual[30][15] = 1;
grid_actual[31][15] = 1;
grid_actual[32][15] = 1;
grid_actual[33][15] = 1;
grid_actual[35][15] = 1;
grid_actual[36][15] = 1;
grid_actual[37][15] = 1;
grid_actual[38][15] = 1;
grid_actual[39][15] = 1;
}
/**
* TICK
*
* This function calculates the next generation.
*
*/
void tick(void)
{
// Copy actual to backup grid:
for (x = 0; x < GRID_WIDTH; x++) {
for (y = 0; y < GRID_HEIGHT; y++) {
grid_backup[x][y] = grid_actual[x][y];
}
}
// Calculate next generation:
for (x = 1; x < (GRID_WIDTH - 1); x++) {
for (y = 1; y < (GRID_HEIGHT - 1); y++) {
// Calculate number of neighbours:
uint8_t cnt = 0;
cnt = cnt + grid_backup[x - 1][y - 1] + grid_backup[x][y - 1]
+ grid_backup[x + 1][y - 1];
cnt = cnt + grid_backup[x - 1][y] + grid_backup[x + 1][y];
cnt = cnt + grid_backup[x - 1][y + 1] + grid_backup[x][y + 1]
+ grid_backup[x + 1][y + 1];
// Calculate transitions:
// 1. Under-Population:
if (cnt < 2) {
grid_actual[x][y] = 0; // Cell dies
}
// 2. Stay alive: cnt = 2..3: Cell survives
// Nothing to do ...
// 3. Overcrowding:
if (cnt > 3) {
grid_actual[x][y] = 0; // Cell dies
}
// 4. Reproduction:
if (cnt == 3) {
grid_actual[x][y] = 1; // New cell born
}
}
}
}
/**
* SHOW GRID
*
* This function shows the actual generation.
*
*/
void showGrid(void)
{
writeChar('\n');
writeChar('\n');
for (y = 0; y < GRID_HEIGHT; y++) {
for (x = 0; x < GRID_WIDTH; x++) {
if (grid_actual[x][y] == 1) {
// Show a live cell (Q):
writeString_P("Q ");
}
else {
// Show a dead cell (~):
writeString_P("~ ");
}
}
writeChar('\n');
}
}
/************************************************** ***************************/
// Main function - The program starts here:
int main(void)
{
initRP6Control(); // Always call this first! The Processor will not work
// correctly otherwise.
initLCD(); // Initialize the LC-Display (LCD)
// Always call this before using the LCD!
// Write some text messages to the UART - just like on RP6Base:
writeString_P("\n\n _______________________\n");
writeString_P(" \\| RP6 ROBOT SYSTEM |/\n");
writeString_P(" \\_-_-_-_-_-_-_-_-_-_/\n\n (file://\\_-_-_-_-_-_-_-_-_-_/\n\n)");

writeString_P("Game Of Life for RP6 CONTROL!\n");
// Set the four Status LEDs:
setLEDs(0b1111);
mSleep(500);
setLEDs(0b0000);

showScreenLCD("################", "################");
mSleep(1500);
showScreenLCD("<<RP6 Control>>", "<<LC - DISPLAY>>");
mSleep(2500);
showScreenLCD(" J. H. Conway's ", " Game Of Life ");
mSleep(2500);
clearLCD(); // Clear the whole LCD Screen
// Play four sounds with the Piezo Beeper on the RP6Control:
sound(Tone_Cis2, 300, 200);
sound(Tone_Fis2, 200, 100);
sound(Tone_Ais2, 100, 100);
sound(Tone_Dis3, 50, 100);
startStopwatch1(); // Used for stepping speed
// Set grid with the initial pattern (seed):
// (Activate only ONE of the following 7 functions!)
seedCluster(); // Cluster 3x3
//seedStillLives(); // Still lives
//seedOscillators(); // Oscillators
//seedSpaceships(); // Spaceships
//seedGuns(); // Guns
//seedMethusalahs(); // Methusalahs
//seedInfiniteGrowth(); // Infinite growth
showGrid(); // Show the initial generation
mSleep(5000); // Wait 5s
while(true)
{
if (getStopwatch1() > STEPPING) {
tick(); // Calculate the next generation
showGrid(); // Show the actual generation
setStopwatch1(0);
}
}
return 0;
}
/************************************************** ****************************
* Additional info
* ************************************************** **************************
* Changelog:
* - v. 1.0 (initial release) 29.04.2011 by Dirk
*
* ************************************************** **************************
*/
/************************************************** ***************************/

radbruch
29.04.2011, 19:54
Das wäre auch eine gute Anwendung für ZOC (http://www.emtec.com/download.htm). Stehendes Bild und Farben als Ersatz für den Loader::
https://www.roboternetz.de/community/showthread.php?48073-VT100-Ansi-Terminal-f%FCr-den-RP6

RolfD
29.04.2011, 21:17
Jetzt fehlt nur noch Eliza *laaach

Für die jüngeren:
http://de.wikipedia.org/wiki/ELIZA

Dirk
02.05.2011, 20:41
Jetzt fehlt nur noch Eliza *laaach
Wie wär's mit einem kleinen Psychiater?

/*
* ************************************************** **************************
* RP6 ROBOT SYSTEM - RP6 CONTROL M32 TESTS
* ************************************************** **************************
* Example: Doc Z
* Author(s): Dirk
* ************************************************** **************************
* Description:
* This program for RP6 Control is a simple "electronic psychiatrist".
* It asks questions (German language) and gives you an advice in the end.
* Years ago a similar BASIC program was "Dr.Z" (K. Menzel, 1984).
*
* ################################################## ##########################
* The Robot does NOT move in this example! You can simply put it on a table
* next to your PC and you should connect it to the PC via the USB Interface!
* ################################################## ##########################
* ************************************************** **************************
*/
/************************************************** ***************************/
// Includes:
#include "RP6ControlLib.h" // The RP6 Control Library (1.3beta or higher).
// Always needs to be included!
/************************************************** ***************************/
// Defines:
#define MAX_TEXTNO 12 // Number of prepared questions in psyTexts()
#define QUESTIONS 8 // Number of asked questions
/************************************************** ***************************/
// Variables:
// Reception buffer for the function getInputLine():
char receiveBuffer[UART_RECEIVE_BUFFER_SIZE + 1];
char username[UART_RECEIVE_BUFFER_SIZE + 1];
uint8_t i, rnd, rnd1, rnd2;
/************************************************** ***************************/
// Functions:
// UART receive functions:
/**
* Get chars of an input line from the UART.
*
* Returns 0 (false), if the UART receive buffer is empty
* OR a character of the input line has been received.
* Returns 1, if the whole input line has been received
* (with a "new line" character at the end).
* Returns 2, if the UART receive buffer overflows.
* The input line is stored in the receiveBuffer array.
*
*/
uint8_t getInputLine(void)
{static uint8_t buffer_pos = 0;
if(getBufferLength()) {
receiveBuffer[buffer_pos] = readChar();
if(receiveBuffer[buffer_pos] == '\n') {
receiveBuffer[buffer_pos] = '\0';
buffer_pos = 0;
return 1;
}
else if(buffer_pos >= UART_RECEIVE_BUFFER_SIZE) {
receiveBuffer[UART_RECEIVE_BUFFER_SIZE] = '\0';
buffer_pos = 0;
return 2;
}
buffer_pos++;
}
return 0;
}
/**
* Get a complete input line from the UART.
*
* This function waits for a whole input line from the UART.
* The input line is stored in the receiveBuffer array.
* The function is blocking until one of the two following
* conditions occurs:
* - A "new line" character has been received at the end of
* the input line.
* - The UART receive buffer overflows.
*
*/
void enterString(void)
{
while(!getInputLine());
}
/**
* GET SEED
*
* Gets a starting value for srand().
*
*/
uint16_t get_seed(void)
{
uint16_t seed = 0;
uint16_t *p = (uint16_t*) (RAMEND + 1);
extern uint16_t __heap_start;
while (p >= &__heap_start + 1)
seed ^= * (--p);
return seed;
}
/**
* PSY TEXTS
*
* Shows one of MAX_TEXTNO questions that the "psychiatrist" asks.
*
*/
void psyTexts(uint8_t textno)
{
switch (textno) {
case 1 :
writeString_P("Erzähl mir mehr!\n");
break;
case 2 :
writeString_P("Fühlst du das schon lange?\n");
break;
case 3 :
writeString_P("Denkst du, das ist vernünftig?\n");
break;
case 4 :
writeString_P("Würden deine Freunde das glauben?\n");
break;
case 5 :
writeString_P("Kannst du damit leben?\n");
break;
case 6 :
writeString_P("Glaubst du, das ist normal?\n");
break;
case 7 :
writeString_P("Was könnte der Grund sein?\n");
break;
case 8 :
writeString_P("Hast du schon darüber gesprochen?\n");
break;
case 9 :
writeString_P("Bist du manchmal ängstlich?\n");
break;
case 10 :
writeString_P("Bist du oft unzufrieden?\n");
break;
case 11 :
writeString_P("Schläfst du gut?\n");
break;
case 12 :
writeString_P("Bist du häufig enttäuscht?\n");
break;
// case 13 :
// writeString_P("...?\n");
// break;
}
}
/************************************************** ***************************/
// Main function - The program starts here:
int main(void)
{
initRP6Control(); // Always call this first! The Processor will not work
// correctly otherwise.
initLCD(); // Initialize the LC-Display (LCD)
// Always call this before using the LCD!
// Write some text messages to the UART - just like on RP6Base:
writeString_P("\n\n _______________________\n");
writeString_P(" \\| RP6 ROBOT SYSTEM |/\n");
writeString_P(" \\_-_-_-_-_-_-_-_-_-_/\n\n (file://\\_-_-_-_-_-_-_-_-_-_/\n\n)");
writeString_P("Doc Z for RP6 CONTROL!\n");
// Set the four Status LEDs:
setLEDs(0b1111);
mSleep(500);
setLEDs(0b0000);
showScreenLCD("################", "################");
mSleep(1500);
showScreenLCD("<<RP6 Control>>", "<<LC - DISPLAY>>");
mSleep(2500);
showScreenLCD(" Doc Z ", " ************ ");
mSleep(2500);
clearLCD(); // Clear the whole LCD Screen
// Play four sounds with the Piezo Beeper on the RP6Control:
sound(Tone_Cis2, 300, 200);
sound(Tone_Fis2, 200, 100);
sound(Tone_Ais2, 100, 100);
sound(Tone_Dis3, 50, 100);
writeString_P("\nGuten Tag, ich bin der RP6 Psychiater.\n");
writeString_P("Wie ist dein Name?\n");
clearReceptionBuffer(); // Make sure reception Buffer is empty.
enterString();
for (i = 0; i <= UART_RECEIVE_BUFFER_SIZE; i++) {
username[i] = receiveBuffer[i];
}
writeString_P("Wie fühlst du dich, ");
writeString(username); // Output the user's name as a String
writeString_P("?\n");
enterString();
srand(get_seed());
for (i = 1; i <= QUESTIONS; i++) { // Ask QUESTIONS questions
do {rnd = (rand() % MAX_TEXTNO + 1);} // rnd = [0..MAX_TEXTNO]
while((rnd == rnd2) || (rnd == rnd1));
rnd2 = rnd1; // Don't repeat questions to fast
rnd1 = rnd;
psyTexts(rnd); // Ask a random question
enterString(); // Get the answer
}
mSleep(1500);
writeString_P("\nIch denke, du machst gute Fortschritte\n");
writeString_P("bei der Lösung deiner Probleme, ");
writeString(username);
writeString_P(".\n\n");
writeString_P("Bis zum nächsten Mal.\n");
while(true) {}
return 0;
}
/************************************************** ****************************
* Additional info
* ************************************************** **************************
* Changelog:
* - v. 1.0 (initial release) 02.05.2011 by Dirk
*
* ************************************************** **************************
*/
/************************************************** ***************************/

Schäääm ...