particles[ i ].velocity += ( particles[ i ].force / particles.density + gravity ) * dt;
That means that as particles pile up, the pressure force will decrease. That's the opposite of what you want to happen.
You should instead divide the force by each particle's mass, such that F = ma. Density is not a substitute for mass in this case. Density shouldn't even be considered as a per-particle value - you're only storing it so that you can sample the density field via a smoothing kernel.
Simply removing that reference to density in the integration step should get you some fluid-like behaviour.