Looks to me like the issue is checking elements in the array which don't exist throwing an error. i.e. you will call using your method index-4 = cells[-1]
when someone clicks on box 3. I would suspect all your edges would be susceptible to errors.
In each loop you could simply check the bounding condition as well:
return function () {
if ((index-1 >= 0)
&& cells[index - 1].innerHTML == "empty"
&& index !== 4
&& index !== 8
&& index !== 12) {
cells[index - 1].innerHTML = cells[index].innerHTML;
cells[index].innerHTML = "empty";
}
else if ((index+1<=15)
&& cells[index + 1].innerHTML == "empty"
&& index !== 3
&& index !== 7
&& index !== 11) {
cells[index + 1].innerHTML = cells[index].innerHTML;
cells[index].innerHTML = "empty";
}
...
}
Doing the same for your +/- 4 as well. That should at least get you closer. Also I would recommend installing something you can use to debug your javascript (Firebug is awesome), as this error would have been apparent quickly.