2016-12-30 18:49:55 +00:00
% Cellular Automaton LO27
% Bartuccio Antoine \cr Porée De Ridder Jean
% Autumn 2016
\newpage
# Introduction
The goal of this project is to provide a library containing a new abstract data type called **Matrix** with associated function to manipulate them. The final program have to enable a user to test the library in an interactive and practical way.
2017-01-01 22:21:27 +00:00
Since we decided to not store false value \footnote{cellElement does not contains values anymore, their existence is their value}in our matrix and to not store the colElement and rowElement \footnote{they are unified and renamed as listElement}that are empty, we decided not to worry too much about performances and we encapsulated all access to stored data in the Matrix structure to avoid too much complexity and allow more modularity, readability and re-usability. We created high level tools to manipulate our matrix and used it all along the project.
2016-12-30 18:49:55 +00:00
For compilation we didn't used the ** -ansi** flag since we had to deal with both clang and gcc for compilation and clang didn't accept this flag. Instead, we used the ** -std=c89** flag witch contains the same rules but is accepted on both softwares. Compiling with ** -ansi** still works.
We decided to create two different library. One for the graphical interface (which require SDL2) and the other with the Matrix data type) so this way you may just have to compile one lib if you don't need the gui.
# Description of abstract data types
Every function and data type are described in the documentation given with the project. This documentation is generated with doxygen.
# Algorithmic
2017-01-01 22:21:27 +00:00
The most interesting function are *getCellValue* and *setCellValue* . Those are the one we rely on the most. They are our way of dealing with our complex data structure allowing us to avoid to store false values. They are the functions that need the more computational power on the long run but are really useful due to their level of abstraction and their high level.
2016-12-30 18:49:55 +00:00
2017-01-01 22:21:27 +00:00
*getCellValue* is a simple function based on *findMatrixElem* :
```C
getCellValue(matrix:Matrix, ColPos:integer , RowPos:integer ) : bool
BEGIN
if ( colCount(matrix) < = ColPos OR rowCount(matrix) < = RowPos)
getCellValue < - ERROR
endif
2017-01-01 22:51:26 +00:00
if (findMatrixElem( matrix , ColPos , RowPos ) = NULL)
2017-01-01 22:21:27 +00:00
getCellValue < - false
endif
getCellValue < - true
END
findMatrixElem( matrix:Matrix , ColPos:integer, RowPos:integer ) : *cellElement
BEGIN
Row:ListElement < - NULL
elem:*cellElement < - NULL
Row < - getElementPos ( rows ( matrix ) , RowPos )
2017-01-01 22:51:26 +00:00
if (Row = NULL)
2017-01-01 22:21:27 +00:00
findMatrixElem < - NULL
endif
elem < - data ( Row )
while (elem != NULL AND colIndex(elem) != ColPos)
elem < - nextCol ( elem )
endwhile
2017-01-01 22:30:49 +00:00
findMatrixElem < - elem
2017-01-01 22:21:27 +00:00
END
```
*setCellValue* is a simple function based on *createMatrixElem* and *deleteMatrixElement* :
2017-01-01 23:29:15 +00:00
2016-12-30 18:49:55 +00:00
```C
2017-01-01 22:21:27 +00:00
setCellValue(matrix:Matrix, ColPos:integer, RowPos:integer,value:bool):bool
BEGIN
2017-01-01 22:51:26 +00:00
if (value = true)
2017-01-01 22:21:27 +00:00
setCellValue < - createMatrixElem ( matrix , ColPos , RowPos )
else
if ( deleteMatrixElem(matrix,ColPos,RowPos) >= 0 )
setCellValue < - true
else
setCellValue < - false
endif
endif
END
createMatrixElem( matrix:Matrix, ColPos:integer, RowPos:integer):bool
Row:*ListElement < -NULL
Col:*Listelemnt < - NULL
2017-01-01 22:30:49 +00:00
error:integer < - 0
2017-01-01 22:21:27 +00:00
elem: *cellElement < - NULL
tmp: *cellElement< - NULL
if (colCount(matrix) < = ColPos OR rowCount(matrix) < = RowPos )
2017-01-01 23:29:15 +00:00
createMatrixElem < - ERROR / * out of bounds * /
2017-01-01 22:21:27 +00:00
endif
elem < - CreateCellElem ( )
SetPositionIndex(elem,ColPos,RowPos)
Row < - getElementPos ( rows ( matrix ) , RowPos )
2017-01-01 22:30:49 +00:00
if (Row != NULL AND data(Row) != NULL)
2017-01-01 22:21:27 +00:00
2017-01-01 22:51:26 +00:00
if (colIndex(data(Row)) = ColPos)
2017-01-01 23:29:15 +00:00
error ++ /* the element already exists */
2017-01-01 22:21:27 +00:00
else
if (colIndex(data(Row)) > ColPos)
nextCol(elem) < - data ( Row )
data(Row) < - elem
endif
else
tmp < - data ( Row )
2017-01-01 23:29:15 +00:00
/* searching the previous element */
2017-01-01 22:21:27 +00:00
while ( nextCol(tmp) != NULL AND nextCol(colIndex(tmp)) < ColPos ) do
tmp < - nextCol ( tmp )
endwhile
2017-01-01 22:51:26 +00:00
if ( nextCol(tmp) = NULL OR colIndex(nextCol(tmp)) > ColPos)
2017-01-01 22:21:27 +00:00
nextCol(elem) < - nextCol ( tmp )
nextCol(tmp) < - elem
else
2017-01-01 23:29:15 +00:00
error ++ /* the element already exists */
2017-01-01 22:21:27 +00:00
endif
endif
else
2017-01-01 23:29:15 +00:00
/* if the list is empty */
2017-01-01 22:21:27 +00:00
push(rows(matrix),elem)
pos(tail(rows(matrix))) < - RowPos
endif
Col < - getElementPos ( cols ( matrix ) , ColPos )
if (Col != NULL AND data(Col) != NULL)
2017-01-01 22:51:26 +00:00
if (rowIndex(data(Col)) = RowPos)
2017-01-01 23:29:15 +00:00
error ++ /* the element already exists */
2017-01-01 22:21:27 +00:00
else
if (rowIndex(data(Col)) > RowPos)
nextRow(elem) < - data ( Col )
data(Col) < - elem
endif
else
tmp < - data ( Col )
2017-01-01 23:29:15 +00:00
/* searching the previous element */
2017-01-01 22:21:27 +00:00
while (nextRow(tmp) != NULL AND rowIndex(nextRow(tmp)) < RowPos ) do
2017-01-01 22:30:49 +00:00
tmp < - nextRow ( tmp )
2017-01-01 22:21:27 +00:00
endwhile
2017-01-01 22:51:26 +00:00
if (nextRow(tmp) = NULL OR rowIndex(nextRow(tmp)) > RowPos)
2017-01-01 22:21:27 +00:00
nexRow(elem) < - nextRow ( tmp )
newRow(tmp) < - elem
else
2017-01-01 23:29:15 +00:00
error ++ /* the element already exists */
2017-01-01 22:21:27 +00:00
endif
endif
else
2017-01-01 23:29:15 +00:00
/* if the list is empty */
2017-01-01 22:21:27 +00:00
push(cols(matrix),elem)
2017-01-01 22:30:49 +00:00
pos(tail(cols(matrix))) < - ColPos
2017-01-01 22:21:27 +00:00
endif
if (error != 0)
2017-01-01 23:29:15 +00:00
/* if the element already exists, free it */
2017-01-01 22:21:27 +00:00
FreeCellElement(elem)
createMatrixElem < - true
else
createMatrixElem < - false
endif
END
deleteMatrixElem(matrix:Matrix,ColPos:integer, RowPos:integer ):integer
BEGIN
elem : *cellElement < - NULL
tmp : *cellElement < - NULL
Row : *ListElement < - NULL
Col : *ListElement < - NULL
elem < - findMatrixElem ( matrix , ColPos , RowPos )
2017-01-01 22:51:26 +00:00
if (elem = NULL)
2017-01-01 23:29:15 +00:00
/* if the element does not exists */
2017-01-01 22:21:27 +00:00
deleteMatrixElem < - 0
endif
Row < - getElementPos ( rows ( matrix ) , RowPos )
2017-01-01 22:51:26 +00:00
if (Row = NULL)
2017-01-01 23:29:15 +00:00
/* this shouldn't happend */
2017-01-01 22:21:27 +00:00
deleteMatrixElem < - -1
endif
2017-01-01 22:51:26 +00:00
if (data(Row) = NULL)
2017-01-01 23:29:15 +00:00
/* this shouldn't happend too */
2017-01-01 22:21:27 +00:00
removeElementPos(rows(matrix),RowPos)
deleteMatrixElem < - -1
endif
2017-01-01 22:51:26 +00:00
if (colIndex(data(Row)) = ColPos)
2017-01-01 23:29:15 +00:00
/* the element is the first element */
2017-01-01 22:21:27 +00:00
data(Row) < - nextCol ( elem )
else
tmp < - data ( Row )
2017-01-01 23:29:15 +00:00
/* finding prefious element */
2017-01-01 22:21:27 +00:00
while (nextCol(tmp) != NULL AND nextCol(tmp) != elem) do
tmp < - nextCol ( tmp )
endwhile
2017-01-01 22:30:49 +00:00
if (nextCol(tmp) != NULL)
2017-01-01 23:29:15 +00:00
/* linking correctly the previous element */
2017-01-01 22:21:27 +00:00
nextCol(tmp) < - nextCol ( elem )
endif
endif
2017-01-01 22:51:26 +00:00
if (data(Row) = NULL)
2017-01-01 23:29:15 +00:00
/* if the row is empty now we delete it to save memory */
2017-01-01 22:21:27 +00:00
removeElementPos(rows(matrix),RowPos)
2017-01-01 22:30:49 +00:00
endif
2017-01-01 22:21:27 +00:00
2017-01-01 22:30:49 +00:00
Col < - getElementPos ( cols ( matrix ) , ColPos )
2017-01-01 22:51:26 +00:00
if (Col = NULL)
2017-01-01 23:29:15 +00:00
/* this shouldn't happend */
2017-01-01 22:21:27 +00:00
deleteMatrixElem < - -2
endif
2017-01-01 22:51:26 +00:00
if (data(Col) = NULL)
2017-01-01 23:29:15 +00:00
/* this shouldn't happend too */
2017-01-01 22:21:27 +00:00
removeElementPos(cols(matrix),ColPos)
2017-01-01 22:30:49 +00:00
deleteMatrixElem < - -1
2017-01-01 22:21:27 +00:00
endif
2017-01-01 23:29:15 +00:00
2017-01-01 22:51:26 +00:00
if (rowIndex(data(Col)) = RowPos)
2017-01-01 23:29:15 +00:00
/* the element is the first element */
2017-01-01 22:21:27 +00:00
data(Col) < - nextRow ( elem )
else
tmp < - data ( Col )
2017-01-01 23:29:15 +00:00
/* finding prefious element */
2017-01-01 22:21:27 +00:00
while (nextRow(tmp) != NULL AND nextRow(tmp) != elem) do
tmp < - nextRow ( tmp )
endwhile
if (nextRow(tmp) != NULL)
2017-01-01 23:29:15 +00:00
/* linking correctly the previous element */
2017-01-01 22:21:27 +00:00
nextRow(tmp) < - nextRow ( elem )
endif
endif
2016-12-30 18:49:55 +00:00
2017-01-01 22:51:26 +00:00
if (data(Col) = NULL)
2017-01-01 23:29:15 +00:00
/* if the col is empty now we delete it to save memory */
2017-01-01 22:21:27 +00:00
removeElementPos(cols(matrix),ColPos)
endif
FreeCellElement(elem)
deleteMatrixElem < - 1
END
2016-12-30 18:49:55 +00:00
```
Functions *andColSequenceOnMatrix* and *orColSequenceOnMatrix* are implemented with *colSequenceOnMatrix* and are really not interesting so we're gonna provide the algorithm of the last one :
```C
```
This is the same thing for *andRowSequenceOnMatrix* and *orRowSequenceOnMatrix* :
```C
2017-01-01 19:47:27 +00:00
colSequenceOnMatrix(m:Matrix, operator:(function(bool, bool):bool)): Matrix
BEGIN
a:integer
b:integer
i:integer
j:integer
newM:Matrix < - createMatrix ( )
rowCount(newM) < - rowCount ( m )
if (colCount(m) < = 1) then
colCount(newM) < - 0
colSequenceOnMatrix < - newM
endif
colCount(newM) < - colCount ( m ) - 1
2017-01-01 22:21:27 +00:00
for i from 0 to colCount(m) - 2 do
for j from 0 to rowCount(m) - 2 do
2017-01-01 19:47:27 +00:00
a < - getCellValue ( m , i , j )
b < - getCellValue ( m , i + 1 , j )
if operator(a, b) then
setCellValue(newM, i, j, true)
endif
endfor
endfor
2017-01-01 22:30:49 +00:00
colSequenceOnMatrix < - newM
2017-01-01 19:47:27 +00:00
END
2016-12-30 18:49:55 +00:00
```
Here are the algorithm of the function *applyRules* and all the one related to it :
```C
2017-01-01 22:21:27 +00:00
applyRules ( matrix:Matrix, Rules:integer, N:integer):Matrix
BEGIN
2017-01-01 23:29:15 +00:00
RulesMatrix :integer[9] /* the size is the number of fundamental rules */
2017-01-01 22:21:27 +00:00
i:integer < - 0
power:integer < - 2
sum:integer < - 0
j:integer < - 0
tempMatrix1:Matrix
tempMatrix2:Matrix
if (Rules < = 0 OR N < 1 )
2017-01-01 22:30:49 +00:00
applyRules < - matrix
2017-01-01 22:21:27 +00:00
endif
2017-01-01 23:29:15 +00:00
/* decompotition of the rule in basic rules */
2017-01-01 22:21:27 +00:00
while(power < = 512) do
RulesMatrix[i] < - Rules % power - sum
sum < - Rules % power
if (RulesMatrix[i]!=0)
i++
endif
power < - power * 2
endwhile
2017-01-01 23:29:15 +00:00
/* application of the rule */
2017-01-01 22:21:27 +00:00
tempMatrix1 < - matrixFromRules ( matrix , i , RulesMatrix )
for j from 0 to N do
tempMatrix2 < - matrixFromRules ( tempMatrix1 , i , RulesMatrix )
freeMatrix(tempMatrix1)
tempMatrix1 < - tempMatrix2
endfor
applyRules < - tempMatrix1
END
2016-12-30 18:49:55 +00:00
```
# Conclusion