Is there a formula without if/else/switch/? etc that could replace the solution[,] matrix and what are the implications or differences on performance/efficiency for that?
class Program
{
private static Random r = new Random();
// names of the "moves"
private static string[] rps = { "PAPER", "ROCK", "SCISSORS"};
// result feedback string to be formatted
private static string[] feedback = { "{1} Beats {0}, You Loose!","{0} Equals {1}, Draw!", "{0} Beats {1}, You Win!" };
// solution matrix ( 0 = loose ; 1 = draw ; 2 = win // array1: for paper; array2: for rock; array3: for scissors; )
private static int[,] solution = {{1, 2, 0},{0, 1, 2},{2, 0, 1}};
/// <summary>
/// Rock Paper scissors solution w/o calculation or if/case/else/
/// </summary>
/// <param name="args">dummy.</param>
static void Main(string[] args)
{
// simulate the players move
int player = r.Next(3);
// simulate the computers move
int computer = r.Next(3);
// retrieve the result from the matrix
int result = solution[player, computer];
//write the result of the match
Console.WriteLine(String.Format("you : {0} vs {1} : computer", rps[player], rps[computer]));
Console.WriteLine(S开发者_StackOverflowtring.Format(feedback[result], rps[player], rps[computer]));
}
}
Yes, there is a quite simple formula:
player computer solution (c+4-p)%3
0 0 1 1
0 1 2 2
0 2 0 0
1 0 0 0
1 1 1 1
1 2 2 2
2 0 2 2
2 1 0 0
2 2 1 1
So you can use:
int result = (computer + 4 - player) % 3;
Accessing the array and calculating the value would take rougly the same time. However, the difference in performance in this application is negligible. Just writing the result to the console takes a lot longer than either using the array or calculating the value. Of course, by calculating the value you don't need the array, but as it's so small that doesn't make much of a difference.
Consider also the readability of the solution. The formula has no logical connection to what you use it for, it's just a means to get to a specific result, so you would need a large comment that explains what it accomplishes...
Edit:
If you want focus on readability, you could put the logic in a separate class:
public class Play {
public enum Value { Paper = 0, Rock = 1, Scissors = 2 }
private Value _value;
public Play(Random rnd) {
_value = (Value)rnd.Next(3);
}
public bool SameAs(Play other) {
return _value == other._value;
}
public bool Beats(Play other) {
return
(_value == Value.Paper && other._value == Value.Rock) ||
(_value == Value.Rock && other._value == Value.Scissors) ||
(_value == Value.Scissors && other._value == Value.Paper);
}
public override string ToString() {
switch (_value) {
case Value.Paper: return "PAPER";
case Value.Rock: return "ROCK";
default: return "SCISSORS";
}
}
}
Now the logic gets clearer:
Random r = new Random();
Play player = new Play(r);
Play computer = new Play(r);
Console.WriteLine("you : {0} vs {1} : computer", player, computer);
string feedback;
if (player.SameAs(computer)) {
feedback = "{0} Equals {1}, Draw!";
} else if (player.Beats(computer)) {
feedback = "{0} Beats {1}, You Win!";
} else {
feedback = "{1} Beats {0}, You Loose!";
}
Console.WriteLine(feedback, player, computer);
精彩评论