180 likes | 379 Views
מבוא לתכנות – תוכנה. פונקציות. משחק החיים של Conway. The Game of life סימולצית פעילות מערכת תאים שפותחה על ידי המתמטיקאי הבריטי ג'ון הורטון קונווי בשנת 1970.
E N D
מבוא לתכנות – תוכנה פונקציות
משחק החיים של Conway • The Game of lifeסימולצית פעילות מערכת תאים שפותחה על ידי המתמטיקאי הבריטי ג'ון הורטון קונווי בשנת 1970. • מאז ועד היום מתמטיקאים ואנשי מדעי המחשב לא מפסיקים להתפעל מהמחשק, בעיקר כיוון שההוא מדגים כיצד מספר כללים פשוטים יכולים להניב תוצאות מורכבות ומפתיעות.
משחק החיים • המרחב של סימולציית משחק החיים הוא על לוח משבצות (דו-מימדי) אינסופי. • כל משבצת נחשבת ליחידה, שנקרא לה תא. • תא יכול להיות במצב של "חיים" או "מוות". • כדי לסמן זאת, נקבע כי משבצת מלאה היא תא "חי", ומשבצת ריקה היא תא "מת".
משחק החיים • כללי המשחק: • המשחק מתחיל ממצב התחלתי כלשהו, בו חלק מהתאים בלוח חיים וחלקם מתים. • מצב התאים במהלך המשחק משתנה בהתאם למספר כללים שקובעים את מצבם בכל רגע נתון במשחק. נהוג לכנות מצב נתון כ-"דור". • בכל דור נולדים ומתים תאים לפי הכללים הבאים: • לידה, מוות, הישרדות
משחק החיים • כללי המשחק: • לידה – אם למשבצת ריקה יש שלושה שכנים חיים, אז בשלב הבא יהיה בה יצור חי. • תא חי ימות אם: • יש לו שכן חי אחד או פחות (ימות מבדידות). • יש לו ארבעה שכנים חיים או יותר (ימות מצפיפות יתר). • זיקנה - התא חי במשך X שנים.
משחק החיים • דוגמאות למצבים יציבים:
משחק החיים • התוכנית אותה נכתוב תריץ סימולציה בשלבים. • כל שלב ידמה דור אחד.
משחק החיים • מבנה הנתונים: • מערך דו-מימדי בגודל SIZEXSIZE – מתאר את מצב הלוח: • 1- : המשבצת נמצאת על גבול הלוח. • 0 : המשבצת ריקה. • 1,2,3...OLD_AGE : התא חי. המספר מיצג את גיל התא.
הצהרה על פונקציות #include <iostream.h> #include <stdlib.h> #define SIZE 22 #define OLD_AGE 4 void init_array(int arr[SIZE][SIZE], int rect_size); void print_array(int arr[SIZE][SIZE]); int islive(int i); int calc_next(int arr[SIZE][SIZE],int line,int col); void next_stage(int arr1[SIZE][SIZE],int arr2[SIZE][SIZE]); int main() { int arr1[SIZE][SIZE]; int arr2[SIZE][SIZE]; int last; init_array(arr1, 5); cout << "Enter # of iterations : "; cin >> last; int i; for (i = 1 ; i <= last ; i++) { cout << "Stage # " << i << endl; cout << "==========" << endl; if (i % 2 == 1) { print_array(arr1); next_stage(arr1,arr2); } else { print_array(arr2); next_stage(arr2,arr1); } system("PAUSE"); } system("PAUSE"); return 0; } התוכנית הראשית main
int main() { int arr1[SIZE][SIZE]; int arr2[SIZE][SIZE]; int last; init_array(arr1, 5); cout << "Enter # of iterations : "; cin >> last; int i; for (i = 1 ; i <= last ; i++) { cout << "Stage # " << i << endl; cout << "==========" << endl; if (i % 2 == 1) { // for odd stages print_array(arr1); next_stage(arr1,arr2); } else { // for even stages print_array(arr2); next_stage(arr2,arr1); } system("PAUSE"); } system("PAUSE"); return 0; } קריאה לפונקציה שליחת משתנה מסוג מערך לפונקציה, שולחת את כתובתו ולא מעתיקה אותו (כמו קריאה by reference)
void init_array(int arr[SIZE][SIZE], int rect_size) { int i,j; int rect_start_idx = (SIZE - rect_size + 1) / 2; int rect_end_idx = SIZE - (SIZE - rect_size) / 2 - 1; /* coding: -1 : boundary 0 : empty spot 1 : occupied spot */ for (i = 0 ; i < SIZE ; i++) { for (j = 0 ; j < SIZE ; j++) { if (i == 0 || j == 0 || i == SIZE - 1 || j == SIZE - 1) arr[i][j] = -1; // boundary else if (i < rect_start_idx || j < rect_start_idx || i > rect_end_idx || j > rect_end_idx) arr[i][j] = 0; // empty spots else arr[i][j] = 1; // occupied spots } } }
void print_array(int arr[SIZE][SIZE]) { int i,j; for (i = 0 ; i < SIZE ; i++) { for (j = 0 ; j < SIZE ; j++) { if (arr[i][j] > 0) cout << arr[i][j]; // occupied else if (arr[i][j] < 0) cout << "."; //boundries else cout << " "; //empty } cout << endl; } }
void next_stage(int cur[SIZE][SIZE],int next[SIZE][SIZE]) { int i,j; for (i = 0 ; i < SIZE ; i++) { for (j = 0 ; j < SIZE ; j++) { next[i][j] = calc_next(cur,i,j); } } }
int calc_next(int arr[SIZE][SIZE],int row,int col) { if (arr[row][col] >= OLD_AGE) return 0; if (arr[row][col] < 0) return -1; int n = 0; // count number of living neighbors if (row > 0 && row < SIZE - 1 && col > 0 && col < SIZE - 1) { n = islive(arr[row-1][col-1]) + islive(arr[row-1][col]) + islive(arr[row-1][col + 1]) + islive(arr[row][col-1]) + islive(arr[row][col + 1]) + islive(arr[row+1][col-1]) + islive(arr[row+1][col]) + islive(arr[row+1][col + 1]); } if (arr[row][col] > 0) { if (n < 2) return 0; if (n >= 4) return 0; return arr[row][col] + 1; } if (n == 3) return 1; return 0; }
int islive(int i) { if (i > 0) return 1; else return 0; }
תרגיל - כפל מטריצות • כתוב תכנית הקולטת שתי מטריצות (3*3) • התכנית תיצור את מטריצת הכפל שלהן. • פלט התכנית יהיה הדפסה של מטריצת הכפל.
void read_matrix(double matrix[MAX_ROWS][MAX_COLS]) { for (int rCounter = 0; rCounter < MAX_ROWS; rCounter++) for (int cCounter = 0; cCounter < MAX_COLS; cCounter++) cin >> matrix[rCounter][cCounter]; } void write_matrix(const double matrix[MAX_ROWS][MAX_COLS]) { for (int rCounter = 0; rCounter < MAX_ROWS; rCounter++) { for (int cCounter = 0; cCounter < MAX_COLS; cCounter++) cout << matrix[rCounter][cCounter] << " "; cout << endl; } } void matrix_multip(const double matrix1[MAX_ROWS][MAX_COLS], const double matrix2[MAX_ROWS][MAX_COLS], double result[MAX_ROWS][MAX_COLS]) { for (int rCounter = 0; rCounter < MAX_ROWS; rCounter++) { for (int cCounter = 0; cCounter < MAX_COLS; cCounter++) { result[rCounter][cCounter] = 0; // reset the result matrix for (int i= 0; i < MAX_ROWS; i++) { result[rCounter][cCounter] += matrix1[rCounter][i]*matrix2[i][cCounter]; } } } }
const int MAX_ROWS =10; const int MAX_COLS =10; int main() { // for input double num_matrix1 [MAX_ROWS][MAX_COLS]; double num_matrix2 [MAX_ROWS][MAX_COLS]; // for output double res_matrix [MAX_ROWS][MAX_COLS]; read_matrix(num_matrix1); read_matrix(num_matrix2); matrix_multip(num_matrix1, num_matrix2, res_matrix); write_matrix(res_matrix); return 0; }