一个剪刀石头布输赢的程序。
import java.util.Scanner;
public class Test{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
System.out.println("----猜拳游戏----");
System.out.println("请输入: (1.石头 2.剪刀 3.布)");
int pChoice=in.nextInt(), //人的选择 person choice
cChoice=(int)(Math.random()*3+1); //电脑的选择 computer choice
String pStr = choice(pChoice),
cStr = choice(cChoice);
if(pChoice==cChoice){ //判断条件
System.out.println("你出的是:"+pStr+" 电脑出的是:"+cStr+"平局了");
}else if(pChoice==1&&cChoice==2||pChoice==2&&cChoice==3||pChoice==3&&cChoice==1){
System.out.println("你出的是:"+pStr+" 电脑出的是:"+cStr+ "你赢了");
}else{
System.out.println("你出的是:"+pStr+" 电脑出的是:"+cStr+ "你输了");
}
in.close();
}
static String choice(int num) {
String str = " ";
switch(num){
case 1: str="石头";break;
case 2: str="剪刀";break;
case 3: str="布";break;
}
return str;
}
}
本来这样就该交工了 ,但是我觉得在判断条件这一模块还有文章可做。首先,剪刀石头布这三个属性相生相克,分别赋予他们位次 1、2、3 来进行比较判断,难道只有枚举法(或数组,变相的枚举)可以解决吗?其次,若是四个、五个属性相生相克,用枚举法过于麻烦了吧?
思考的算法如下:(设属性个数为 m )
默认排序:第一位>第二位,第二位>第三位,....,倒数第二位>倒数第一位,倒数第一位>第一位
-
先讨论最简单的剪刀石头布情况,即 m =3 时,判断条件:(pChoice - cChoice +5 )%3 -1
人的选择 电脑的选择 是否获胜 1 2 是 2 3 是 3 1 是 可以看出当(人选择的数字-电脑选择的数字)= -1 或者 2 时人获胜;同理,(人选择的数字-电脑选择的数字)= 1 或者 -2 时人失败,(人选择的数字-电脑选择的数字)= 0 时平局。
以相减得出的数字为判断条件继续划分范围,对五个数字进行相同操作,条件逐渐清晰:(肯定还有类似的判断,仅举例一种)
初始 加5 除以3取余 减1 人获胜:-1 2 人获胜:4 7 人获胜:1 1 人获胜:0 人失败:1 -2 人失败:6 3 人失败:0 0 人失败:-1 人平局: 0 人平局:5 人平局:2 人平局:1
那么判断条件可以改为:
int num = (pChoice-cChoice+5)%3-1;
if(num>0){
System.out.println("你出的是:"+pStr+" 电脑出的是:"+cStr+"平局了");
}else if(num==0){
System.out.println("你出的是:"+pStr+" 电脑出的是:"+cStr+ "你赢了");
}else{
System.out.println("你出的是:"+pStr+" 电脑出的是:"+cStr+ "你输了");
}
// 用 switch 看起来更简洁一点。
switch((pChoice-cChoice+5)%3-1){
case 1: System.out.println("你出的是:"+pStr+" 电脑出的是:"+cStr+"平局了");break;
case 0: System.out.println("你出的是:"+pStr+" 电脑出的是:"+cStr+ "你赢了");break;
case -1: System.out.println("你出的是:"+pStr+" 电脑出的是:"+cStr+ "你输了");break;
}(平局得分,赢了不得分,输了扣分,双赢最厉害,哈哈)
-
开始扩展,m = 4,m=5,m= 6时,判断条件分别为:(pChoice - cChoice +7 )%4 -2、(pChoice - cChoice +9 )%5 -3、(pChoice - cChoice +11 )%6 -4
同理可得出以下数据:
初始 | 加 7 | 除以 4 取余 | 减 2 |
---|---|---|---|
人获胜:-1、3 | 人获胜:6、10 | 人获胜:2 | 0 |
人失败:1、-3 | 人失败:8、4 | 人失败:0 | -2 |
平局:0 | 平局:7 | 平局:3 | 1 |
初始 | 加 9 | 除以 5 取余 | 减 3 |
---|---|---|---|
人获胜:-1、4 | 人获胜:8、13 | 人获胜:3 | 0 |
人失败:1、-4 | 人失败:10、5 | 人失败:0 | -3 |
平局:0 | 平局:9 | 平局:4 | 1 |
初始 | 加 11 | 除以 6 取余 | 减4 |
---|---|---|---|
人获胜:-1、5 | 人获胜:10、16 | 人获胜:4 | 0 |
人失败:1、-5 | 人失败:12、6 | 人失败:0 | -4 |
平局:0 | 平局:11 | 平局:5 | 1 |
- 结论:
当 m = n 时,判断条件为:( pChoice - cChoice +(2*n-1) ) % n - ( n-2)
最后总结,当有 n 个循环依次相克的属性,依次赋予他们1~n 数值,且大小关系为:第一位>第二位,第二位>第三位,....,倒数第二位 > 倒数第一位,倒数第一位 > 第一位,则他们的判断依据为:( before - later +(2*n-1) ) % n - ( n-2),最后的值 =0 为前者获胜,> 0 为平局,< 0 为前者失败。
如果只有倒数第一位克制第一位,而其余均遵守小数>大数的规则,原理也是一样的,依据也是数字相减的范围。