480 lines
15 KiB
C
480 lines
15 KiB
C
#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);
|
|
|
|
} |