``````
unit U_MagicSquare1;
{Finds magic squares of odd size using an algorithm
developed by Cornelius Agrippa around 1500 or De La Loubere - date unknown (by me)
as follows:
"Start with 1 in the middle of the top row; then go up
and left assigning numbers in increasing order to
empty cells; if you fall off of the square imagine
the same square as tiling the plane and continue; if a
cell is occupied, move down instead and
continue."}

.
.  {generated code snipped here}
.``````
``Function isodd(n:integer):boolean;``
``````{tests for odd number}
Begin
if n mod 2 =0 then result:=false
else result:=true;
end;

procedure TForm1.CalcBtnClick(Sender: TObject);``````
``````{calculate an odd order magic square}
var
i,j,count,order,size:integer;
oldi,oldj:integer;
begin
order:=strtoint(intedit1.text);
if (isodd(order)) and (order<=51) then
begin
with stringgrid1 do
begin
{initialize things}
rowcount:=order+1;
colcount:=order+1;
for i:=0 to colcount-1 do
for j:=0 to rowcount-1 do cells[i,j]:='';
size:=order*order;
{make font size bigger for small squares, smaller for big squares}
if size<100 then font.size:=12 else font.size:=8;
{now we have to adjust cell size appropriately for the font}
canvas.font:=font;
defaultcolwidth:=canvas.textwidth(inttostr(size))+4;
defaultrowheight:=defaultcolwidth;
{make the grid size match the sum of the cells + grid lines sizes}
width:=(defaultcolwidth+1)*order+2;
height:=((defaultrowheight+1)*order+2);``````
``````      {here's the algorithm}
i:=order div 2; {center of top row}
j:=0;
count:=0;
repeat
inc(count);
cells[i,j]:=inttostr(count); {get next number}
if count<size then
Begin
oldi:=i;
dec(i);   {move up}
if i<0 then i:=order-1; {loop around if necessary}
oldj:=j;
dec(j); {and left}
if j<0 then j:=order-1; {loop around if necessary}
if cells[i,j]<>'' then {occupied?}
Begin
i:=oldi;
if j>order then j:=0;
end;
if cells[i,j]<>'' then showmessage('Algorithm error');
end;
until count=size;
end;
{Sum is always (order^3+order) div 2}
SumLbl.caption:='Sum of each row, column and diagonal is '
+inttostr((size*order+order) div 2);
Sumlbl.visible:=true;
end
else beep;
end;

procedure TForm1.IntEdit1KeyPress(Sender: TObject; var Key: Char);
{make sure only digits or backspace keys are pressed}
begin
If not (key in ['0'..'9',#8 {backsapace}]) then
begin
key:=#0;
beep;
end;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
windowstate := wsMaximized; {make form full size}
end;

end.

``````