我正在进行一项JS练习,它基本上是一种功能,可以播放摇滚,纸张,剪刀的比赛,并根据哪个玩家拥有什么来宣告获胜者。现在我有一个完全正常的程序:
const rps = (p1, p2) => {
var r = "rock";
var p = "paper";
var s = "scissors";
if(p1 == r && p2 == s || p1 == s && p2 == p || p1 == p && p2 == r){
return "Player 1 won!";
}
else if (p1 == s && p2 == r || p1 == p && p2 == s || p1 == r && p2 == p){
return "Player 2 won!";
}
else if (p1 === p2){
return "Draw!";
}
};
console.log(rps("rock","scissors"));
我知道它不是很漂亮但是,我还在学习绳索。所以考虑到这一点,我想知道是否有办法通过做这样的事情来更多地干掉代码:
const rps = (p1, p2) => {
var r = "rock";
var p = "paper";
var s = "scissors";
if ((r,s) || (s,p) || (p,r)){
return "Player 1 won!";
}
else if((s,r) || (p,s) || (r,p)){
return "Player 2 won!";
}
else if (p1 === p2){
return "Draw";
}
};
console.log(rps("rock","scissors"));
在比较过程中需要变量并使用函数参数作为指定点的东西。我运行上面的脚本并且非常惊讶它实际上返回了任何东西,我认为它会引发错误。但是......无论我在函数调用中使用什么字符串(即使在测试绘制时),它总是返回“Player 1 won”。
有可能做这样的事情,还是我离开基地?
===编辑===
我以为我会在这里添加速度测试结果以便更好地阅读。正如我在下面的评论中提到的,我测试了每个脚本100k次3轮,并通过console.time()返回完成时间
如果有人好奇,这是我的测试循环:
console.time("speed test");
for (var i = 1; i < 100000; i++) {
rps("scissors","scissors");
}
console.timeEnd("speed test");
===更新===
在我的机器(WAMP服务器)本地测试而不是Cloud9的终端,速度更好:
以下是(“摇滚,纸”)的结果:
Cloud9
if/else script --> 4.091ms, 4.228ms, 4.698ms
case script --> 24.844ms, 31.974ms, 20.763ms
table script --> 68.934ms, 86.619ms, 51.805ms
Local
if/else script --> 4.412ms, 4.160ms, 4.374ms
case script --> 6.347ms, 5.551ms, 5.478ms
table script --> 18.093ms, 18.664ms, 19.065ms
以下是(“剪刀”,“剪刀”)的结果:
Cloud9
if/else script --> 4.351ms, 4.214ms, 5.023ms
case script --> 28.387ms, 19.079ms, 29.333ms
table script --> 62.740ms, 59.410ms, 70.401ms
Local
if/else script --> 5.743ms, 5.262ms, 4.858ms
case script --> 5.685ms, 6.447ms, 4.503ms
table script --> 27.116ms, 25.780ms, 24.467ms
性能方面似乎if / else和case方法的速度至少在本地非常接近。
是否有可能:是的,你是否离开基地:不。
这是经典的Matrix数学设置。很酷的部分是,您通过尝试if
语句以错误的方式定义了Matrix。如果你看一下if语句,你会看到组合就出现了。好消息是,这个很容易合理化,因为事实证明我们所要处理的只是一个非常小的笛卡尔坐标系。基于您的定义的坐标系在下面的代码示例中。运行该示例以查看该表。
代码由简单的查找表组成。
我希望这是有益的,有帮助的,而不是指导解决方案。
function RPS(p1Tool, p2Tool) {
const tools = ["rock", "paper", "scissors"];
const p1Wins = [2,21,10];
const p2Wins = [20,12,1];
const draw = [0,11,22];
// p1Tool = 'rock' returns 0, p2Tool = 'scissors' returns 2
const winner = +(tools.indexOf(p1Tool) + tools.indexOf(p2Tool));
// look up the results in our matrixes
return (p1Wins.includes(winner))
? 'Player 1'
: (p2Wins.includes(winner))
? 'Player 2'
: 'No One';
}
let winner = RPS('rock', 'scissors');
alert(winner + ' wins!');
<TABLE border="1">
<TH></TH><TH>R(0)</TH><TH>P(1)</TH><TH>S(2)</TH>
<TR ALIGN="CENTER">
<TD>R(0)</TD>
<TD>D</TD>
<TD>P</TD>
<TD>R</TD>
</TR>
<TR ALIGN="CENTER">
<TD>P(1)</TD>
<TD>P</TD>
<TD>D</TD>
<TD>S</TD>
</TR>
<TR ALIGN="CENTER">
<TD>S(2)</TD>
<TD>R</TD>
<TD>S</TD>
<TD>D</TD>
</TR>
</TABLE>
<span>Think Cartesian Coordinates</span>
这是一个我认为非常简单的解决方案(对不起,如果格式不完美):
<html>
<script language=javascript>
const r = 1;
const p = 10;
const s = 100;
function rps (p1, p2) {
//alert (p1);
//alert (p2);
var num = Math.abs(p1 - p2); // rock wins when the difference is 99
alert (num); // scissors when it is 90
// paper when it is 9
switch (num) {
case 9:
// Paper wins!
alert ("Paper wins!");
break;
case 90:
// Scissors wins!
alert ("Scissors wins!");
break;
case 99:
// Rock wins!
alert ("Rock wins!");
break;
default:
// It is a tie!
alert ("It is a tie!");
break;
}
}
function runit() {
//alert (r);
//alert (p);
//alert (s);
rps(r,p);
rps(p,r);
rps(r,s);
rps(s,r);
rps(p,s);
rps(s,p);
rps(r,r);
rps(p,p);
rps(s,s);
}
</script>
<body onload="runit()">
been so long
</body>
</html>
在第二个例程中,您甚至不会使用传入的变量来确定它们是什么。除了它产生的结果之外,你怎么期望它确定任何东西,你根本不理解为什么它会产生它。 (r,s)并且可能所有相似的条件都在评估'真',可能只是因为它们不是零,一旦你有'真'它就会开始,所以它每次都会这样。