This works but it's ugly

One of my deficiencies is I’m just not as good at math as I’d like to be. That leads to functions like this…


function findPosition( $days, $time, $period) {
	$phase = findPhase( $days, $time, $period );
	
	switch ($time) {
		case 0: switch ($phase) {
			case 8: return 'setting';
			case 9: return 'descending';
			case 0: return 'overhead';
			case 1: return 'ascending';
			case 2: return 'rising';
			default: return 'set';		
		}
		case 1: switch ($phase) {
			case 9: return 'setting';
			case 0: return 'descending';
			case 1: return 'overhead';
			case 2: return 'ascending';
			case 3: return 'rising';
			default: return 'set';		
		}
		case 2: switch ($phase) {
			case 0: return 'setting';
			case 1: return 'descending';
			case 2: return 'overhead';
			case 3: return 'ascending';
			case 4: return 'rising';
			default: return 'set';	
		}
		case 3: switch ($phase) {
			case 1: return 'setting';
			case 2: return 'descending';
			case 3: return 'overhead';
			case 4: return 'ascending';
			case 5: return 'rising';
			default: return 'set';	
		}
		case 4: switch ($phase) {
			case 2: return 'setting';
			case 3: return 'descending';
			case 4: return 'overhead';
			case 5: return 'ascending';
			case 6: return 'rising';
			default: return 'set';	
		}
		case 5: switch ($phase) {
			case 3: return 'setting';
			case 4: return 'descending';
			case 5: return 'overhead';
			case 6: return 'ascending';
			case 7: return 'rising';
			default: return 'set';	
		}
		case 6: switch ($phase) {
			case 4: return 'setting';
			case 5: return 'descending';
			case 6: return 'overhead';
			case 7: return 'ascending';
			case 8: return 'rising';
			default: return 'set';	
		}
		case 7: switch ($phase) {
			case 5: return 'setting';
			case 6: return 'descending';
			case 7: return 'overhead';
			case 8: return 'ascending';
			case 9: return 'rising';
			default: return 'set';	
		}
		case 8: switch ($phase) {
			case 6: return 'setting';
			case 7: return 'descending';
			case 8: return 'overhead';
			case 9: return 'ascending';
			case 0: return 'rising';
			default: return 'set';	
		}
		case 9: switch ($phase) {
			case 7: return 'setting';
			case 8: return 'descending';
			case 9: return 'overhead';
			case 0: return 'ascending';
			case 1: return 'rising';
			default: return 'set';	
		}
	}

So, what’s this for. Well, Dungeons & Dragons. My campaign world has three moons and this function is part of the mini program I plan to use during play to tell me where the moons are (roughly) and what phase they are in. The find Phase function returns a value 0 to 9. 0 is noon, 1 is evening and so on, 5 is midnight and back to dawn at 9. Not that the world has 10 hours, but for game play purposes it isn’t terribly useful to track time any closer than day phases. This is rough, but it’s for fun and not too serious.

But that double switch is ugly and my brain refuses to work out the math to do it any other way. The function returns whether the moon is rising, ascending, overhead, descending or setting by comparing the phase (and therefore orbit position) against the time of day (position of the observer on the ground).

Can anyone trim this up?

This seems to do the trick.

$phaseShiftedTime = ($time - $phase + 10) % 10;

switch ($phaseShiftedTime) {
    case 0: return 'overhead';
    case 1: return 'descending';
    case 2: return 'setting';
    case 8: return 'rising';
    case 9: return 'ascending';
    default: return 'set';
}