2015-12-20 1 views
1

J'ai une fonction de vide qui a beaucoup de cas dans les déclarations et tous sont nécessaires, je ne peux vraiment pas enlever quoi que ce soit. Mais j'ai l'impression que ça pourrait être mieux fait. En utilisant certains LINQ.Where, des classes ou quelque chose comme ça. Je souhaite optimiser et d'exprimer void Smooth dans le plus petit nombre de caractères possibles:optimisation Méthode

void Smooth(ref int botChips, ref bool botTurn, Label botStatus, int name, int n, int r) { 
     Random rand = new Random(); 
     int rnd = rand.Next(1, 3); 
     if (rounds == 0 || rounds == 1) 
     { 
      if (call <= 0) 
      { 
       Check(ref botTurn, botStatus); 
      } 
      else 
      { 
       if (call >= RoundN(botChips, n)) 
       { 
        Call(ref botChips, ref botTurn, botStatus); 
       } 
       else 
       { 
        if (botChips >= call * 2) 
        { 
         Raise *= 2; 
         Raised(ref botChips, ref botTurn, botStatus); 
        } 
        else 
        { 
         Call(ref botChips, ref botTurn, botStatus); 
        } 
       } 
      } 
     } 
     if (rounds == 2 || rounds == 3) 
     { 
      if (call <= 0) 
      { 
       if (rnd == 1) 
       { 
        Raise = RoundN(botChips, r); 
        Raised(ref botChips, ref botTurn, botStatus); 
       } 
       else if (rnd!=1 && rounds==2) 
       { 
        Check(ref botTurn, botStatus); 
       } 
      } 
      else 
      { 
       if (call >= RoundN(botChips, r)) 
       { 
        if (botChips > call) 
        { 
         Call(ref botChips, ref botTurn, botStatus); 
        } 
        if (botChips <= call) 
        { 
         raising = false; 
         botTurn = false; 
         botChips = 0; 
         botStatus.Text = "Call " + call; 
         tbPot.Text = (int.Parse(tbPot.Text) + call).ToString(); 
        } 
       } 
       else 
       { 
        if (Raise <= (RoundN(botChips, r))/2) 
        { 
         Raise = RoundN(botChips, r); 
         Raised(ref botChips, ref botTurn, botStatus); 
        } 
        else 
        { 
         Raise *= 2; 
         Raised(ref botChips, ref botTurn, botStatus); 
        } 
       } 
      } 
     } 
    } 

RoundN procédé

private static double RoundN(int sChips, int n) { 
     double a = Math.Round((sChips/n)/100d, 0) * 100; 
     return a; 
    } 

Fold procédé

private void Fold(ref bool sTurn, ref bool SFTurn, Label sStatus) { 
     raising = false; 
     sStatus.Text = "Fold"; 
     sTurn = false; 
     SFTurn = true; 
    } 

Check métho d

private void Check(ref bool cTurn, Label cStatus) { 
     cStatus.Text = "Check"; 
     cTurn = false; 
     raising = false; 
    } 

Call méthode

private void Call(ref int sChips, ref bool sTurn, Label sStatus) { 
     raising = false; 
     sTurn = false; 
     sChips -= call; 
     sStatus.Text = "Call " + call; 
     tbPot.Text = (int.Parse(tbPot.Text) + call).ToString(); 
    } 

Raised méthode

private void Raised(ref int sChips, ref bool sTurn, Label sStatus) { 
     sChips -= Convert.ToInt32(Raise); 
     sStatus.Text = "Raise " + Raise; 
     tbPot.Text = (int.Parse(tbPot.Text) + Convert.ToInt32(Raise)).ToString(); 
     call = Convert.ToInt32(Raise); 
     raising = true; 
     sTurn = false; 
    } 
+0

Avez-vous essayé le profilage? BTW Je définirais le 'Random' qu'une seule fois et diviserais cette grande méthode en quelques plus petites (' Ctrl + R, M') –

+0

Je sais que ce n'est pas ce que vous avez demandé, mais c'est une utilisation très dangereuse de 'new Random' ; si vous appelez 'Smooth' dans une boucle, il pourrait utiliser la même graine. Vous devriez faire 'rand' une variable d'instance et l'initialiser dans le constructeur. –

+0

Merci pour votre réponse! Non je n'ai pas essayé le profilage et je vais corriger le 'nouveau Random' – kopelence

Répondre

2

La méthode Smooth peut être simplifié (ou en vous r terme: optimisé) à certains égards:

  1. Pour supprimer les conditionnels (if-else) blocs imbriqués, envisager l'utilisation précoce return pour des conditions qui sont plus simples parmi les deux ou n'a pas d'autre suite. De cette façon, vous pouvez supprimer les blocs imbriqués "difficiles à lire".
  2. Pour éviter les blocs "en double", les blocs ayant des actions identiques doivent être considérés comme étant groupés ensemble plutôt que séparés. Pensez si l'inversion de la condition peut aider à simplifier votre code
  3. Exploitez tous les comportements bénéfiques que vous connaissez sur l'évaluation du langage. Par exemple, for C#, dans l'argument de l'instruction conditionnelle comme if (a || b) cas, l'expression left sera évaluée en premier (c'est-à-dire: a) - cela s'appelle Short Circuit Evaluation.
  4. Chaque fois que possible, et sans perdre de manière significative la lisibilité, envisager d'utiliser Ternary operator pour remplacer le bloc if-else.
  5. variable Confirmez que vous utiliserez plusieurs fois sans changer la valeur que une fois
  6. Attention à chevauchement (double/dupliqués) conditions!
  7. Utilisez correct le type de données va help!

Pour votre cas, le code simplifié peut être quelque chose comme ça

uint rounds = 0; //read 8. 
void Smooth(ref int botChips, ref bool botTurn, Label botStatus, int name, int n, int r) { 
    Random rand = new Random(); 
    int rnd = rand.Next(1, 3); 
    if (rounds <= 1) { //read 8. 
     if (call <= 0) { 
      Check(ref botTurn, botStatus); //since your Check doesn't change rounds, this is legal     
      return; //read 1. early return     
     } //beyond this call > 0 
     if (call >= RoundN(botChips, n) || botChips < call * 2) { //read 2., 3., 4., and 7. 
      Call(ref botChips, ref botTurn, botStatus); 
      return; //read 1. 
     } //beyond this is the opposite of both conditions 
     Raise *= 2; 
     Raised(ref botChips, ref botTurn, botStatus); 
    } 

    if (rounds == 2 || rounds == 3) { 
     if (call <= 0) { 
      if (rnd == 1) { //call <= 0, rnd == 1, similar to the block on call < rNBChips, may potentially be further simplified 
       Raise = RoundN(botChips, r); 
       Raised(ref botChips, ref botTurn, botStatus); 
      } else if (rounds == 2) //read 7. rnd is definitely not 1, no need for further check 
       Check(ref botTurn, botStatus); 
      return; //read 1. this is valid since you don't want to continue 
     } 
     double rNBChips = RoundN(botChips, r); //read 6. this way you avoid multiple calls. It both shorter and faster 
     if (call < rNBChips) { //read 3. 
      Raise = Raise <= rNBChips/2 ? rNBChips : Raise * 2; //read 5. 
      Raised(ref botChips, ref botTurn, botStatus); 
      return; // read 1. 
     } 
     if (botChips > call) { 
      Call(ref botChips, ref botTurn, botStatus); 
      return; //read 1. 
     } 
     raising = false; 
     botTurn = false; 
     botChips = 0; 
     botStatus.Text = "Call " + call; 
     tbPot.Text = (int.Parse(tbPot.Text) + call).ToString(); 
    } 
} 

Sans les commentaires il semble encore beaucoup plus compact, comme ce

uint rounds = 0; 
void Smooth(ref int botChips, ref bool botTurn, Label botStatus, int name, int n, int r) { 
    Random rand = new Random(); 
    int rnd = rand.Next(1, 3); 
    if (rounds <= 1) { 
     if (call <= 0) { 
      Check(ref botTurn, botStatus);    
      return; 
     } 
     if (call >= RoundN(botChips, n) || botChips < call * 2) { 
      Call(ref botChips, ref botTurn, botStatus); 
      return; 
     } 
     Raise *= 2; 
     Raised(ref botChips, ref botTurn, botStatus); 
    } 

    if (rounds == 2 || rounds == 3) { 
     if (call <= 0) { 
      if (rnd == 1) { 
       Raise = RoundN(botChips, r); 
       Raised(ref botChips, ref botTurn, botStatus); 
      } else if (rounds == 2) 
       Check(ref botTurn, botStatus); 
      return; 
     } 
     double rNBChips = RoundN(botChips, r); 
     if (call < rNBChips) { 
      Raise = Raise <= rNBChips/2 ? rNBChips : Raise * 2; 
      Raised(ref botChips, ref botTurn, botStatus); 
      return; 
     } 
     if (botChips > call) { 
      Call(ref botChips, ref botTurn, botStatus); 
      return; 
     } 
     raising = false; 
     botTurn = false; 
     botChips = 0; 
     botStatus.Text = "Call " + call; 
     tbPot.Text = (int.Parse(tbPot.Text) + call).ToString(); 
    } 
}