#include "General.h" #define ATOM 4 #define NEUTRON_UP 3 #define NEUTRON_DOWN 5 #define NEUTRON_LEFT 7 #define NEUTRON_RIGHT 9 #define FILE_NAME "test.txt" #define OPEN_FILE_TYPE "rt" #define ASCII_COMMA ',' #define ASCII_ZERO '0' #define ASCII_HYPHEN '-' #define SM_ROWS 500 #define SM_COLUMNS 600 //--------------------------------------------------------------------------------------- // ReadStringFromFile // ------------------ // // General : Read from file as string and save the string to array. // // Parameters : // char ** ptr_save_data - save data from file in array // unsigned int length - length of array // // Return value : The number (int). // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void ReadStringFromFile(char ** ptr_save_data, unsigned int * length) { *length = ZERO; char ch; FILE * fp = fopen(FILE_NAME, OPEN_FILE_TYPE); if (fp) { *ptr_save_data = malloc(sizeof(ch)); while ((ch = fgetc(fp)) != EOF) { *((*ptr_save_data) + *length) = ch; (*length)++; *ptr_save_data = realloc(*ptr_save_data, sizeof(ch) * (*length + ONE)); } *ptr_save_data = realloc(*ptr_save_data, sizeof(ch) * (*length)); fclose(fp); } else { printf("Can't read file : \"%s\"\n", FILE_NAME); } } //--------------------------------------------------------------------------------------- // StringToNumber // -------------- // // General : Convert string to number. // // Parameters : // char * ptr_str - array of char // unsigned int length - length of array // // Return value : The number (int). // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- int StringToNumber(char * ptr_str, unsigned int length) { int number = ZERO; unsigned int counter; if (*ptr_str == ASCII_HYPHEN) { number = -(*(++ptr_str)); ptr_str++; } for (counter = ZERO; counter < length; counter++) { number = (number * TEN) + (*(ptr_str++) - ASCII_ZERO); } return (number); } //--------------------------------------------------------------------------------------- // FileDataToArray // --------------- // // General : Change the data we get from file as string to numbers array. // // Parameters : // char * ptr_file_data - pointer to char array // unsigned int length_file_data - length of char array // int ** ptr_array - pointer to save data from char array // unsigned int * length_array - pointer of ptr_array length // // Return value : None. // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void FileDataToArray(char * ptr_file_data, unsigned int length_file_data, int ** ptr_array, unsigned int * length_array) { char * temp_ptr_file_data = ptr_file_data; int temp_number; unsigned int loop_counter; *length_array = ONE; *ptr_array = malloc(sizeof(int)); for (loop_counter = ZERO; loop_counter < length_file_data; loop_counter++) { if (*temp_ptr_file_data == ASCII_COMMA) { (*ptr_array)[*length_array - ONE] = StringToNumber(ptr_file_data, temp_ptr_file_data - ptr_file_data); (*length_array)++; *ptr_array = realloc(*ptr_array, sizeof(int) * (*length_array)); ptr_file_data = ++temp_ptr_file_data + ONE; loop_counter++; } temp_ptr_file_data++; } *ptr_array = realloc(*ptr_array, sizeof(int) * (--(*length_array))); } //--------------------------------------------------------------------------------------- // InitBoard // --------- // // General : Initializing simulation board. // // Parameters : // SM * board - Simulation board // unsigned int rows - Amount of rows in board // unsigned int cols - Amount of cols in board // // Return value : None. // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void InitBoard(SM * board, unsigned int rows, unsigned int cols) { unsigned int counter; for (counter = ZERO; counter < rows; counter++) { AddRowSM(board); } for (counter = ZERO; counter < cols; counter++) { AddColSM(board); } } //--------------------------------------------------------------------------------------- // ArrayDataToSM // ------------- // // General : Copies all points to a sparse matrix from the array. // // Parameters : // SM * board - Simulation board // int * ptr_arr - pointer of points array (x1, y1, x2, y2, ..) // unsigned int length - length of points array // // Return value : None. // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void ArrayDataToSM(SM * board, int * ptr_arr, unsigned int length) { unsigned int counter; for (counter = ZERO; counter < length; counter += TWO) { AddItemSM(board, ptr_arr[counter], ptr_arr[counter+ONE]); GetItemSM(board, ptr_arr[counter], ptr_arr[counter+ONE])->info.int_ = ATOM; } } //--------------------------------------------------------------------------------------- // MoveUp // ------ // // General : Creates to the up of the node, a neutron facing the up side // of the simulation board. // // Parameters : // SM * board - Simulation board // SM * node - address of node in simulation board // queue * qt - queue of active objects // // Return value : None. // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void MoveUp(SM * manager, SM * node, queue * qt) { SM * temp = NULL; if (node->row > ZERO) { temp = GetItemSM(manager, node->row - ONE, node->col); if (!temp) { AddItemSM(manager, node->row - ONE, node->col); temp->info.int_ = ONE; } temp->info.int_ *= node->info.int_; } if (temp != NULL) { InsertQueue(qt, (Data_Type)(void *)temp); } } //--------------------------------------------------------------------------------------- // MoveDown // -------- // // General : Creates to the down of the node, a neutron facing the down side // of the simulation board. // // Parameters : // SM * board - Simulation board // SM * node - address of node in simulation board // queue * qt - queue of active objects // // Return value : None. // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void MoveDown(SM * manager, SM * node, queue * qt) { SM * temp = NULL; if ((node->row + ONE) < RowsCountSM(manager)) { temp = GetItemSM(manager, node->row + ONE, node->col); if (!temp) { AddItemSM(manager, node->row + ONE, node->col); temp->info.int_ = ONE; } temp->info.int_ *= NEUTRON_DOWN; } if (temp != NULL) { InsertQueue(qt, (Data_Type)(void *)temp); } } //--------------------------------------------------------------------------------------- // MoveLeft // -------- // // General : Creates to the left of the node, a neutron facing the left side // of the simulation board. // // Parameters : // SM * board - Simulation board // SM * node - address of node in simulation board // queue * qt - queue of active objects // // Return value : None. // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void MoveLeft(SM * manager, SM * node, queue * qt) { SM * temp = NULL; if (node->col > ZERO) { temp = GetItemSM(manager, node->row, node->col - ONE); if (!temp) { AddItemSM(manager, node->row, node->col - ONE); temp->info.int_ = ONE; } temp->info.int_ *= NEUTRON_LEFT; } if (temp != NULL) { InsertQueue(qt, (Data_Type)(void *)temp); } } //--------------------------------------------------------------------------------------- // MoveRight // --------- // // General : Creates to the right of the node, a neutron facing the right side // of the simulation board. // // Parameters : // SM * board - Simulation board // SM * node - address of node in simulation board // queue * qt - queue of active objects // // Return value : None. // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void MoveRight(SM * board, SM * node, queue * qt) { SM * temp = NULL; if ((node->col + ONE) < ColsCountSM(board)) { temp = GetItemSM(board, node->row, node->col + ONE); if (!temp) { AddItemSM(board, node->row, node->col + ONE); temp->info.int_ = ONE; } temp->info.int_ *= NEUTRON_RIGHT; } if (temp != NULL) { InsertQueue(qt, (Data_Type)(void *)temp); } } //--------------------------------------------------------------------------------------- // Explode // ------- // // General : Handles atomic fission mode. // // Parameters : // SM * board - Simulation board // SM * node - address of node in simulation board // queue * qt - queue of active objects // // Return value : None. // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void Explode(SM * board, SM * node, queue * qt) { MoveUp(board, node, qt); MoveDown(board, node, qt); MoveLeft(board, node, qt); MoveRight(board, node, qt); } //--------------------------------------------------------------------------------------- // Steps // ----- // // General : Handles all objects within the queue.. // // Parameters : // SM * manager - pointer of simulation board // queue * qt - queue of objects // // Return value : Amount atoms explode. // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- unsigned int Steps(SM * manager, queue * qt) { unsigned int booms_count = ZERO; SM * main_node; while (!IsEmptyQueue(qt)) { main_node = (SM *)RemoveQueue(qt).pointer; switch (main_node->info.int_) { case NEUTRON_UP: MoveUp(manager, main_node, qt); break; case NEUTRON_DOWN: MoveDown(manager, main_node, qt); break; case NEUTRON_LEFT: MoveLeft(manager, main_node, qt); break; case NEUTRON_RIGHT: MoveRight(manager, main_node, qt); break; default: if (!(main_node->info.int_ % TWO)); { Explode(manager, main_node, qt); booms_count++; } break; } RemoveItemSM(manager, main_node->row, main_node->col); } return (booms_count); } //--------------------------------------------------------------------------------------- // Atomic explosion // ------------------- // // General : The program is essentially an atomic explosion // simulation // // Input : A location where we want to blow up the atom // // Process : The program reads atoms the locations of the atoms // and presents them in the matrix. Then we choose a // place where we want to blow up the atom in the matrix // and count how many nuclear fission happened // // Output : None // //--------------------------------------------------------------------------------------- // Programmer : Cohen Idan // Student No : 211675038 // Date : 26.01.2020 //--------------------------------------------------------------------------------------- void main(void) { SM * board; SM * temp; queue active_objects; char * chars_from_file; unsigned int length_chars_from_file; int * atoms_position; unsigned int length_atoms_position; unsigned int chosen_row; unsigned int chosen_col; unsigned int booms_count; ReadStringFromFile(&chars_from_file, &length_chars_from_file); FileDataToArray(chars_from_file, length_chars_from_file, atoms_position, &length_atoms_position); free(chars_from_file); InitSM(&board); InitBoard(board, SM_ROWS, SM_COLUMNS); InitQueue(&active_objects); ArrayDataToSM(board, atoms_position + ONE, length_atoms_position - ONE); free(atoms_position); while (!temp) { printf("Enter X of atom you want to explode: "); scanf(" %u", &chosen_col); printf("Enter Y of atom you want to explode: "); scanf(" %u", &chosen_row); temp = GetItemSM(board, chosen_row, chosen_col); } InsertQueue(&active_objects, (Data_Type)(void *)temp); booms_count = Steps(board, &active_objects); printf("Energy: %d\n", booms_count); }