前言
在学android的时候,总觉的要做点什么才能感觉到自己在学东西,所以一个小游戏24点就打算做出来试试。为什么要做24点游戏呢?因为之前用javaSwing组件做了一个电脑版的24点,学了android之后就像做一个手机版的,好了,这就是我做24点的缘由了。
实现
先给大家看一下效果图:
图中有四张扑克牌,一个用来显示答案的输入框和两个按钮。点击开始按钮就会出现四张扑克牌,然后玩家去思考该怎么去做出来,如果做不出来可以点击答案按钮查看响应的答案。
这个游戏的最主要的就是24点游戏的算法,如何判断四张牌能不能产生24点,以及四张牌如何产生24点,解决了这两个问题,游戏基本就完成了。在工程中有一个GameUtil类,这个类封装类了上面两个问题的解决方法,先放出来源码给大家看一下,然后再说明如何实现那两个算法的。
GameUtil.java
public class GameUtil {
/**
* 得到所有能算出24点的表达式
* @param a
* @param b
* @param c
* @param d
* @return
*/
public static List<String> getResultList(int a,int b,int c,int d){
List<String> _List = new ArrayList<String>();
int op1,op2,op3;
for(op1=1;op1<=4;op1++)
for(op2=1;op2<=4;op2++)
for(op3=1;op3<=4;op3++){
if(calculate_model1(a,b,c,d,op1,op2,op3)==24){
String s1="(("+a+showFuHao(op1)+b+")"+showFuHao(op2)+c+")"+showFuHao(op3)+d;
_List.add(s1);
}
if(calculate_model2(a,b,c,d,op1,op2,op3)==24){
String s2="("+a+showFuHao(op1)+"("+b+showFuHao(op2)+c+")"+")"+showFuHao(op3)+d;
_List.add(s2);
}
if(calculate_model3(a,b,c,d,op1,op2,op3)==24){
String s3 = a+showFuHao(op1)+"("+b+showFuHao(op2)+"("+c+showFuHao(op3)+d+"))";
_List.add(s3);
}
if(calculate_model4(a,b,c,d,op1,op2,op3)==24){
String s4 = a+showFuHao(op1)+"(("+b+showFuHao(op2)+c+")"+showFuHao(op3)+d+")";
_List.add(s4);
}
if(calculate_model5(a,b,c,d,op1,op2,op3)==24){
String s5 = "("+a+showFuHao(op1)+b+")"+showFuHao(op2)+"("+c+showFuHao(op3)+d+")";
_List.add(s5);
}
}
return _List;
}
private static String showFuHao(int op){
switch(op){
case 1:return "+";
case 2:return "-";
case 3:return "*";
case 4:return "/";
}
return "";
}
private static float calculate_model1(float i,float j,float k,
float t,int op1,int op2,int op3){
float r1,r2,r3; /*对应表达式类型:((A□B)□C)□D*/
r1 = cal(i,j,op1);
r2 = cal(r1,k,op2);
r3 = cal(r2,t,op3);
return r3;
}
private static float calculate_model2(float i,float j,float k,
float t,int op1,int op2,int op3){
float r1,r2,r3; /*对应表达式类型:(A□(B□C))□D */
r1 = cal(j,k,op2);
r2 = cal(i,r1,op1);
r3 = cal(r2,t,op3);
return r3;
}
private static float calculate_model3(float i,float j,float k,
float t,int op1,int op2,int op3){
float r1,r2,r3; /*对应表达式类型:A□(B□(C□D))*/
r1 = cal(k,t,op3);
r2 = cal(j,r1,op2);
r3 = cal(i,r2,op1);
return r3;
}
private static float calculate_model4(float i,float j,float k,
float t,int op1,int op2,int op3){
float r1,r2,r3; /*对应表达式类型:A□((B□C)□D)*/
r1 = cal(j,k,op2);
r2 = cal(r1,t,op3);
r3 = cal(i,r2,op1);
return r3;
}
private static float calculate_model5(float i,float j,float k,
float t,int op1,int op2,int op3){
float r1,r2,r3; /*对应表达式类型:(A□B)□(C□D)*/
r1 = cal(i,j,op1);
r2 = cal(k,t,op3);
r3 = cal(r1,r2,op2);
return r3;
}
private static float cal(float x,float y,int op){ //计算两个操作数
switch(op){
case 1:return x+y;
case 2:return x-y;
case 3:return x*y;
case 4:return x/y;
}
return 0;
}
/**
* 判断能不能得到24点
* @param a
* @param b
* @param c
* @param d
* @return
*/
public static boolean isGet24(int a,int b,int c,int d){ //判断是否能得到24
boolean result = false;
List<String> _list = getResultList(a, b, c, d);
if(_list.size()>0)
result = true;
return result;
}
}
如何得到四个数产生24点的所有表达式
比如说现在有四个数 A B C D 经过加减乘除运算之后能够得到24点,这里我保持四个数的顺序在计算时不变,现在要考虑的是共有多少种情况。
因为在计算式中如 A□B□C□D ,共出现3个运算符,每个运算符都会有加减乘除四种可能,那么共有64中可能,因为运算符的级别不一样,所以在表达式中会出现括号来限定运算符,那么会有几种加括号的可能呢?
总共有5种:
1. ((A□B)□C)□D
2. (A□(B□C))□D
3. A□(B□(C□D))
4. A□((B□C)□D)
5. (A□B)□(C□D)
这5中是所有的运算情况,也就是说每一个运算符的排列对应着5种括号的排列,总共有320个表达式,如果其中有一个或多个表达式算出的结果为24,那么这四个数就可以得到24点,反之就不可以得到。算法的实现过程在上面的代码里面,比较简单,这里我就不说了。
小结
因为这个游戏是之前做的,大概有一年的时间了,现在才拿出来写一篇博客说明,有点懒了/(ㄒoㄒ)/~~
因为时间比较长,所以一些代码中有一些东西是可以优化的,一些用法还不是太好,可以直接用Handler代替Thread来刷新界面,更加的方便,不需要担心在Thread刷新界面崩溃的问题了。