Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the right way to handle "One, Both, or None" logic?

I have a logic situation that is best described as two "Teams" trying to win a task. The outcome of this task could be a single winner, a tie (draw), or no winner (stalemate).

Currently, I'm using a nested if/else statement like so:

// using PHP, but the concept seems language agnostic.
if ($team_a->win()) {
    if ($team_b->win()) {
        //  this is a draw
    } else {
        //  team_a is the winner
    }
} else {
    if ($team_b->win()) { 
        //  team_b is the winner
    } else {
        //  This is a stalemate, no winner.
    }
}

This seems rather spaghetti-like and repetitive. Is there a more logical, DRY pattern I could use?

like image 765
Stephen Avatar asked Dec 23 '10 23:12

Stephen


3 Answers

Another way would be if win(a) && win(b) then Draw, else if win(a), else if win(b).

Or:

if win(a) and win(b) then
   // Draw
else if win(a) then
   // a wins
else if win(b) then
   // b wins
else 
   // Stalemate
like image 54
Robinson Avatar answered Oct 19 '22 22:10

Robinson


I don't think it can be done much better than what you currently are doing.

One alternative is to use a switch expression:

switch (($team_a->win() << 1) + $team_b->win()) {
case 3:
    //  this is a draw
case 2:
    //  team_a is the winner
case 1:
    //  team_b is the winner
case 0:
    //  This is a stalemate, no winner.
}

However while it is more DRY, I don't think this improves readability. Note that in some languages instead of $team_x->win() you need to write ($team_x->win() ? 1 : 0).

like image 4
Mark Byers Avatar answered Oct 20 '22 00:10

Mark Byers


if($TeamA->win() && $TeamB->win()){
  // Tie
}else if($TeamA->win()){
  // Team A wins
}else if($TeamB->win()){
  // Team B wins
}else{
  // No winner
}

Also, depending on what your win() method does, it may be more efficient to check it once outside the if...else so it only runs the check once:

$team_a = $TeamA->win();
$team_b = $TeamB->win();

if($team_a && $team_b){
  // Tie
}else if($team_a){
  // Team A wins
}else if($team_b){
  // Team B wins
}else{
  // No winner
}
like image 3
Sarah Avatar answered Oct 19 '22 22:10

Sarah