Dzięki za poprawione makra, zaraz potestuję ;) Tylko o jakie śmieci w moich makrach ci chodzi? selective-eval nie daje żadnych (te nile są potrzebne ;)) a preprocessor dowala tylko to nieszczęsne progn na początku bloku (i wymusza zastosowanie drugiego, ale to chyba dalej nic wielkiego ;))
A co do
;;WTF - gdzie sa ustawiane x i y?
Nigdzie. ;) Makra preprocessor i selective-eval miały za zadanie wstawienie tamtego kodu 'na chama' w odpowiednie miejsca pętli, np. pętla
(loop for x from 1 upto (- size 1) with y = 0 do
(setf (neighbours (aref my-array x y))
(selective-eval neighbour-list (t nil nil nil t t t t))))
była by rozwinięta do (pomijam rozwinięcie loopa)
(loop for x from 1 upto (- size 1) with y = 0 do
(setf (neighbours (aref my-array x y))
((aref my-array (- x 1) y)
nil
nil
nil
(aref my-array (+ x 1) y)
(aref my-array (+ x 1) (+ y 1))
(aref my-array x (+ y 1))
(aref my-array (- x 1) (+ y 1))))
(fakt, że chyba by się tu przydało 'list' na początku owej listy, zaraz sprawdzę, czy o to chodzi)
Nie da się tak? W każdym razie kod ma być tłumaczeniem na Lispa tego kodu napisanego w C++:
template<typename CELL, int WIDTH, int HEIGHT>
class CellularEngine
{
public:
CellularEngine();
~CellularEngine();
void run();
template<typename Func>
Func traverse(Func);
Array2D<CELL, WIDTH, HEIGHT>& getCells() {return cells;}
private:
Array2D<CELL, WIDTH, HEIGHT> cells;
};
template<typename CELL, int WIDTH, int HEIGHT>
CellularEngine<CELL, WIDTH, HEIGHT>::CellularEngine()
{
// xoox
// oooo
// oooo
// xoox
cells.at(0, 0).neighbours[0] = 0;
cells.at(0, 0).neighbours[1] = 0;
cells.at(0, 0).neighbours[2] = 0;
cells.at(0, 0).neighbours[3] = 0;
cells.at(0, 0).neighbours[4] = &(cells.at(1, 0));
cells.at(0, 0).neighbours[5] = &(cells.at(1, 1));
cells.at(0, 0).neighbours[6] = &(cells.at(0, 1));
cells.at(0, 0).neighbours[7] = 0;
cells.at(WIDTH-1, 0).neighbours[0] = &(cells.at(WIDTH-2, 0));
cells.at(WIDTH-1, 0).neighbours[1] = 0;
cells.at(WIDTH-1, 0).neighbours[2] = 0;
cells.at(WIDTH-1, 0).neighbours[3] = 0;
cells.at(WIDTH-1, 0).neighbours[4] = 0;
cells.at(WIDTH-1, 0).neighbours[5] = 0;
cells.at(WIDTH-1, 0).neighbours[6] = &(cells.at(WIDTH-1, 1));
cells.at(WIDTH-1, 0).neighbours[7] = &(cells.at(WIDTH-2, 1));
cells.at(0, HEIGHT-1).neighbours[0] = 0;
cells.at(0, HEIGHT-1).neighbours[1] = 0;
cells.at(0, HEIGHT-1).neighbours[2] = &(cells.at(0, HEIGHT-2));
cells.at(0, HEIGHT-1).neighbours[3] = &(cells.at(1, HEIGHT-2));
cells.at(0, HEIGHT-1).neighbours[4] = &(cells.at(1, HEIGHT-1));
cells.at(0, HEIGHT-1).neighbours[5] = 0;
cells.at(0, HEIGHT-1).neighbours[6] = 0;
cells.at(0, HEIGHT-1).neighbours[7] = 0;
cells.at(WIDTH-1, HEIGHT-1).neighbours[0] = &(cells.at(WIDTH-2, HEIGHT-1));
cells.at(WIDTH-1, HEIGHT-1).neighbours[1] = &(cells.at(WIDTH-2, HEIGHT-2));
cells.at(WIDTH-1, HEIGHT-1).neighbours[2] = &(cells.at(WIDTH-1, HEIGHT-2));
cells.at(WIDTH-1, HEIGHT-1).neighbours[3] = 0;
cells.at(WIDTH-1, HEIGHT-1).neighbours[4] = 0;
cells.at(WIDTH-1, HEIGHT-1).neighbours[5] = 0;
cells.at(WIDTH-1, HEIGHT-1).neighbours[6] = 0;
cells.at(WIDTH-1, HEIGHT-1).neighbours[7] = 0;
// oxxo
// xoox
// xoox
// oxxo
for(int i=1; i<WIDTH-1; i++)
{
cells.at(i, 0).neighbours[0] = &(cells.at(i-1, 0));
cells.at(i, 0).neighbours[1] = 0;
cells.at(i, 0).neighbours[2] = 0;
cells.at(i, 0).neighbours[3] = 0;
cells.at(i, 0).neighbours[4] = &(cells.at(i+1, 0));
cells.at(i, 0).neighbours[5] = &(cells.at(i+1, 1));
cells.at(i, 0).neighbours[6] = &(cells.at(i, 1));
cells.at(i, 0).neighbours[7] = &(cells.at(i-1, 1));
cells.at(i, HEIGHT-1).neighbours[0] = &(cells.at(i-1, HEIGHT-1));
cells.at(i, HEIGHT-1).neighbours[1] = &(cells.at(i-1, HEIGHT-2));
cells.at(i, HEIGHT-1).neighbours[2] = &(cells.at(i+1, HEIGHT-2));
cells.at(i, HEIGHT-1).neighbours[3] = &(cells.at(i+1, HEIGHT-2));
cells.at(i, HEIGHT-1).neighbours[4] = &(cells.at(i+1, HEIGHT-1));
cells.at(i, HEIGHT-1).neighbours[5] = 0;
cells.at(i, HEIGHT-1).neighbours[6] = 0;
cells.at(i, HEIGHT-1).neighbours[7] = 0;
}
for(int i=1; i<HEIGHT-1; i++)
{
cells.at(0, i).neighbours[0] = 0;
cells.at(0, i).neighbours[1] = 0;
cells.at(0, i).neighbours[2] = &(cells.at(0, i-1));
cells.at(0, i).neighbours[3] = &(cells.at(1, i-1));
cells.at(0, i).neighbours[4] = &(cells.at(1, i));
cells.at(0, i).neighbours[5] = &(cells.at(1, i+1));
cells.at(0, i).neighbours[6] = &(cells.at(0, i+1));
cells.at(0, i).neighbours[7] = 0;
cells.at(WIDTH-1, i).neighbours[0] = &(cells.at(WIDTH-2, i));
cells.at(WIDTH-1, i).neighbours[1] = &(cells.at(WIDTH-2, i-1));
cells.at(WIDTH-1, i).neighbours[2] = &(cells.at(WIDTH-1, i-1));
cells.at(WIDTH-1, i).neighbours[3] = 0;
cells.at(WIDTH-1, i).neighbours[4] = 0;
cells.at(WIDTH-1, i).neighbours[5] = 0;
cells.at(WIDTH-1, i).neighbours[6] = &(cells.at(WIDTH-1, i+1));
cells.at(WIDTH-1, i).neighbours[7] = &(cells.at(WIDTH-2, i+1));
}
// oooo
// oxxo
// oxxo
// oooo
for(int x=1; x<WIDTH-1; x++)
{
for(int y=1; y<HEIGHT-1; y++)
{
cells.at(x, y).neighbours[0] = &(cells.at(x-1, y));
cells.at(x, y).neighbours[1] = &(cells.at(x-1, y-1));
cells.at(x, y).neighbours[2] = &(cells.at(x, y-1));
cells.at(x, y).neighbours[3] = &(cells.at(x+1, y-1));
cells.at(x, y).neighbours[4] = &(cells.at(x+1, y));
cells.at(x, y).neighbours[5] = &(cells.at(x+1, y+1));
cells.at(x, y).neighbours[6] = &(cells.at(x, y+1));
cells.at(x, y).neighbours[7] = &(cells.at(x-1, y+1));
}
}
}
(pominąłem tylko implementację funkcji traverse oraz, z oczywistych względów, destruktora CellularEngine ;) Za to Array2D to klasa emulująca tablicę dwuwymiarową za pomocą jednowymiarowej, z równie oczywistych względów również pominięta w lispowym kodzie)
Naszpikowałem kod makrami właśnie po to, by uniknąć tego całego powtarzania kodu widocznego w powyższym.
EDIT:
(fakt, że chyba by się tu przydało 'list' na początku owej listy, zaraz sprawdzę, czy o to chodzi)
Niestety nie, po zmianie wywołania preprocesora na:
(preprocessor ((neighbour-list
(list
(aref my-array (- x 1) y)
(aref my-array (- x 1) (- y 1))
(aref my-array x (- y 1))
(aref my-array (+ x 1) (- y 1))
(aref my-array (+ x 1) y)
(aref my-array (+ x 1) (+ y 1))
(aref my-array x (+ y 1))
(aref my-array (- x 1) (+ y 1)))))
kompilator zmienia jeno gadkę na:
-+ Errors (1)
`-- (during macroexpansion)
Error in function WALKER::GET-WALKER-TEMPLATE:
Can't get template for
(NEIGHBOUR-LIST
(LIST (AREF MY-ARRAY (- X 1) Y)
(AREF MY-ARRAY (- X 1) (- Y 1))
(AREF MY-ARRAY X (- Y 1))
(AREF MY-ARRAY (+ X 1) (- Y 1))
(AREF MY-ARRAY (+ X 1) Y)
(AREF MY-ARRAY (+ X 1) (+ Y 1))
(AREF MY-ARRAY X (+ Y 1))
(AREF MY-ARRAY (- X 1) (+ Y 1)))).