kinda a tall order.
the long answer:
---------------------{array alighnment}--------------------------------
you need to align everything to a grid, something like 64x64
then set a value 'Tx' (so tile x position) and 'Ty' for your object 
always set those value to 
Tx: round(.x/64)
Ty: round(.y/64)
this will give you your x and y position in your array.
have a similar process for all your objects (maybe just put them all in a family so you only have to do this once?)
-------------------------- {Moving}------------------------------------
always, 
for each object: 
	- >set position array ('Tx','Ty'+1<-(or whatever),2)too object .uid
then when an object want to move in a given direction
check that spaces Z2 position, if that position is equal to 0, go ahead and move.
but if its not
	- >add parameter: value at array position (the tile being checked,z2)
- >add parameter: oject value'Tx'
- >add parameter: object value'Ty'
- >call a function "swap" forgetting objects(this is just to make sure the program forgets the current object)
- > move to space ( it will be clear, because the funtcion will have taken care of that.)
on function "swap"
object uid = 'paramiter 1'
        -> move to( parameter 2, parameter 3)
------------------------------{checking}--------------------------------
as far as checking the fastest method(in terms of cpu speed) is manually so: 
is position at array(Tx+1, ty,2)
however this can be  time consuming to write, and a little messy to read.
so the other method is to check using Modulo [ the symbol %](for and extended explanation go to Tulamide's little corner) 
but for or purposes it will be  calling a loop 4 time's and checking the value of:
 .Tx + ((loop-2)%2)
so -1,0,1,0
 .Ty + ((loop-1)%2)
so 0,-1,0,1
-----------------------------
so in you script it would look like 
on loop "check"
array position((.Tx + ((loop-2)%2),(.Ty + ((loop-1)%2),2)=0
      than do the stuff we talked about.
--------------------(Replacing only if it has too)--------------------
so i take it you want the object to only replace something if thats the only thing it can do?
this would be a mater of how you organize you events.
when the objects ready to move, set another value in it like 'moveme' 
to 1 
for each object     
value 'moveme' = 1:
   - call loop "blank search"
on loop "black search"
  - preform the search mention above and if something matches what its checking.
   -> move the object
   -> set object 'moveme' to 0
than another event after the first (beacuse its after the first, it will only happen if the value move is still equal to 0)
for each object     
value 'moveme' = 1:
   - call loop "swap search"
on loop "swap search"
  - preform the search mention above and if something matches what its checking.
   -> do the paramiter switching function thing
   -> move the object
   -> set object 'moveme' to 0
     
_______________________________________________________________________        
for some more advance moving and checking in arrays 
Array A*
you can ignore the actual A* part, and just look at how it checks,
______________________________________________________________________
I just did this of the top of my head, it should work, but i would need to see your specific case to know for sure.
--------------------------------------------------------
so the short answer too your question :
"Is there a simple way to check to see if any spaces around an object are empty and move to that space; and if they aren't have the two objects swap positions. "
...no..
(unless somebody made a plugin)