方法优化
Method optimization
我有一个 void 函数,里面有很多 if 语句,而且它们都是必需的,我真的不能删除任何东西。但我觉得它可以做得更好。使用一些 LINQ.Where
、类 或类似的东西。我想用尽可能少的字符优化和表达 void Smooth
:
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
方法
private static double RoundN(int sChips, int n) {
double a = Math.Round((sChips / n) / 100d, 0) * 100;
return a;
}
Fold
方法
private void Fold(ref bool sTurn, ref bool SFTurn, Label sStatus) {
raising = false;
sStatus.Text = "Fold";
sTurn = false;
SFTurn = true;
}
Check
方法
private void Check(ref bool cTurn, Label cStatus) {
cStatus.Text = "Check";
cTurn = false;
raising = false;
}
Call
方法
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
方法
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;
}
Smooth
方法可以简化(或者用你的话来说:优化?)在某些方面:
- 要删除条件 (
if-else
) 嵌套块,请考虑使用早期 return
来处理两者中较简单或没有进一步延续的条件。这样,您可以删除 "difficult-to-read" 个嵌套块。
- 为避免"duplicate"块,具有相同动作的块应被视为组合在一起而不是分开。
- 考虑一下反转条件是否有助于简化代码
- 利用您所知道的有关语言评估的任何有益行为。例如,for C#, in the argument of the conditional statement like
if (a || b)
case, the left expression (that is: a
) will be evaluated first - this is known as Short Circuit Evaluation.
- 只要有可能,在不显着降低可读性的情况下,考虑使用 Ternary operator 替换
if-else
块。
- 声明您将多次使用的变量而不更改值仅一次
- 注意重叠(doubled/duplicated)条件!
- 使用正确数据类型会帮助!
对于你的情况,简化的代码可以是这样的
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();
}
}
没有注释它甚至看起来更紧凑,像这样
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();
}
}
我有一个 void 函数,里面有很多 if 语句,而且它们都是必需的,我真的不能删除任何东西。但我觉得它可以做得更好。使用一些 LINQ.Where
、类 或类似的东西。我想用尽可能少的字符优化和表达 void Smooth
:
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
方法
private static double RoundN(int sChips, int n) {
double a = Math.Round((sChips / n) / 100d, 0) * 100;
return a;
}
Fold
方法
private void Fold(ref bool sTurn, ref bool SFTurn, Label sStatus) {
raising = false;
sStatus.Text = "Fold";
sTurn = false;
SFTurn = true;
}
Check
方法
private void Check(ref bool cTurn, Label cStatus) {
cStatus.Text = "Check";
cTurn = false;
raising = false;
}
Call
方法
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
方法
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;
}
Smooth
方法可以简化(或者用你的话来说:优化?)在某些方面:
- 要删除条件 (
if-else
) 嵌套块,请考虑使用早期return
来处理两者中较简单或没有进一步延续的条件。这样,您可以删除 "difficult-to-read" 个嵌套块。 - 为避免"duplicate"块,具有相同动作的块应被视为组合在一起而不是分开。
- 考虑一下反转条件是否有助于简化代码
- 利用您所知道的有关语言评估的任何有益行为。例如,for C#, in the argument of the conditional statement like
if (a || b)
case, the left expression (that is:a
) will be evaluated first - this is known as Short Circuit Evaluation. - 只要有可能,在不显着降低可读性的情况下,考虑使用 Ternary operator 替换
if-else
块。 - 声明您将多次使用的变量而不更改值仅一次
- 注意重叠(doubled/duplicated)条件!
- 使用正确数据类型会帮助!
对于你的情况,简化的代码可以是这样的
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();
}
}
没有注释它甚至看起来更紧凑,像这样
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();
}
}