'07/01/2023
'magic squares of positive integer order (3..)
uses console
print "Magic Squares" cr

begin:
======
'
int e=0,m=0,n=0,r=0,v=0,w=0,x=0,y=0,px=0,py=0
redim int a(0,0) static

'
'INPUT
'=====
print cr
print "Enter positive integer (3..14) "
n=input
print cr
'
'SELECT
'======

select n
case <0 : end
case 0  : end
case 1  : 'allowed
end select
'
redim int a(n,n) clear

select n and 3

case 2: 'SINGLY EVEN
'
'CALCULATE
'=========
r=n
n=r/2
m=n*n
x=n*0.5+0.5
y=1
v=1
do
  a[y,x]=v           'top left
  a[y+n,x+n]=v+m     'bottom right
  a[y  ,x+n]=v+m+m   'top right
  a[y+n,x  ]=v+m+m+m 'bottom left
  py=y : px=x
  y-- : x++
  if y<1 then y=y+n
  if x>n then x=x-n
  if a[y,x]>0 then y=py+1 : x=px
  v++
  if v>m then exit do
loop
'blocks swap
e=n\2
'left side
for x=1 to e
  for y=1 to n
    swap a[y,x],a[y+n,x]
  next
next
'right side
for x=r-e+2 to r
  for y=1 to n
    swap a[y,x],a[y+n,x]
  next
next
swap a[e+1,e],a[e+1+n,e] 
swap a[e+1,e+1],a[e+1+n,e+1] 
n=r
gosub displaySquare
goto begin


case 0: 'DOUBLY EVEN
'
'n divisible by 4
'
'CALCULATE
'=========
int b[4,4]
b={ -1,0,0,-1, 0,-1,-1,0,  0,-1,-1,0, -1,0,0,-1 }
'
py=1
px=1
v=1
w=n*n
for y=1 to n
  for x=1 to n
    if b[py,px]<0
      a[y,x]=v
    else
      a[y,x]=w
    endif
    v++ : w--
    px++
    if px>4 then px=1
  next
  py++
  if py>4 then py=1
next
gosub displaySquare
goto begin


case 1,3: 'ODD
'
'04/01/2023
'magic squares of odd order (3,5,7,9,11 ...)
'
'CALULATE
=========
m=n*n
x=n*0.5+0.5
y=1
v=1
do
  a[y,x]=v
  py=y : px=x
  y-- : x++
  if y<1 then y=y+n
  if x>n then x=x-n
  if a[y,x]>0 then y=py+1 : x=px
  v++
  if v>m then exit do
loop
gosub displaySquare

end select
goto begin


'DISPLAY
'=======
displaySquare: 'subroutine
for y=1 to n
  v=0 : w=0
  for x=1 to n
    v+=a[y,x]
    print a[y,x] tab
  next
  print v cr 'row totals
next
print cr
for x=1 to n
  v=0
  for y=1 to n
    v+=a[y,x]
    if x=y then w+=a[y,x] 'diagonal from top left
  next
  print v tab 'column totals
next
print w cr 'diagonal total
ret

