现在的位置: 首页 > 综合 > 正文

24点扑克牌游戏编程算法详解

2013年07月18日 ⁄ 综合 ⁄ 共 4619字 ⁄ 字号 评论关闭

   24点扑克牌游戏,简单点来说就是:一副扑克牌去掉大小王,任意发四张牌给玩家,玩家要将这四张牌做加减乘除运算,规则是四张牌的顺序不定但不可以重复,计算结果如果是24则玩家赢。本程序实现让计算机自动派牌,并判断扑克牌组合是否可以计算成24点,并输出所有计算方法。
    游戏的算法可描述如下:随机产生4个1-13的数字,然后生成表达式,表达式包括:四个1-13的数字、加减乘除运算符、成对出现的括号。这些表达式必须是合法的,什么是合法的表达式?举个例子,如(2+10)*(6-4)就是个合法的、并且计算结果是24的表达式,如2+4()*38+就是非法的表达式,(2+8)/5*2是个合法的表达式但计算结果不是24。然后根据运算法则计算这个表达式是否等于24。
    算法可逐步求解如下:
    现有三个集合,
    集合1={N1, N2, N3, N4},
   集合2={op1, op2, op3},
   集合3={"(", ")"}
   N1,N2,N3,N4可以是1-13中的任意一个数字,op1,op2,op3可以是"+","-","*","/"中的任意一个操作符
    (1)首先从集合1中随机抽取一个元素,并删除抽取出来的元素,然后再从集合2中随机抽取一个元素组成字符数组;
    (2)重复第一步操作,直到集合1为空,集合1为空时不再从集合2中抽取元素,最后得到的表达式表示如下所示:
     expression = N1 op1 N2 op2 N3 op3 N4
   (3)将集合3的元素组合插入到表达式expression中,得到的合法的表达式可以表示如下:
      (N1 op1 N2) op2 N3 op3 N4
     N1 op1 (N2 op2 N3) op3 N4
     N1 op1 N2 op2 (N3 op3 N4)
     (N1 op1 N2 op2 N3) op3 N4
     N1 op1 (N2 op2 N3 op3 N4)
     ((N1 op1 N2) op2 N3) op3 N4
     (N1 op1 (N2 op2 N3)) op3 N4
     N1 op1 ((N2 op2 N3) op3 N4)
     N1 op1 (N2 op2 (N3 op3 N4))
     (N1 op1 N2) op2 (N3 op3 N4)
     以上三步在Get24PointExpression.java中实现。
    (4)这样的话,根据排列和组合原理,将会得到C41*C31*C21*C11*C41*C41*C41*10=4!*4*4*4*10个合法的表达式,然后逐一分析这些表达式是否已经重复出现,然后再逐一将这些表达式转换成实际的数学运算式,并计算结果,判断计算结果是否等于24。
   这一步在Cancal24.java中实现。
   算法实现部分代码:

package PokerGame24Point;
import com.Allen.*;
public class Get24PointExpression {
    /**
     * 求任意扑克组合的计算24点的表达式
     * @haram array 扑克组合
     * @return 计算24点的表达式
     */
    static String[] get24CalExpression(int[] array) {
        String[] op = {"+", "-", "*", "/"};
        String[] ch = {"(", ")"};        
        String[] sentence = new String[array.length+op.length-1];
         
        int opNumIndex = PublicFunction.getRandom(0, array.length);
        sentence[0] = Integer.toString(array[opNumIndex]); 
        array = PublicFunction.deleteOneElement(array, array[opNumIndex]);
        int opIndex = PublicFunction.getRandom(0, op.length);
        sentence[1] = op[opIndex];
        opNumIndex = PublicFunction.getRandom(0, array.length);
        sentence[2] =  Integer.toString(array[opNumIndex]); 
        array = PublicFunction.deleteOneElement(array, array[opNumIndex]);
        opIndex = PublicFunction.getRandom(0, op.length);
        sentence[3] = op[opIndex];
        opNumIndex = PublicFunction.getRandom(0, array.length);
        sentence[4] = Integer.toString(array[opNumIndex]); 
        array = PublicFunction.deleteOneElement(array, array[opNumIndex]);
        opIndex = PublicFunction.getRandom(0, op.length);
        sentence[5] = op[opIndex];
        opNumIndex = PublicFunction.getRandom(0, array.length);
        sentence[6] =  Integer.toString(array[opNumIndex]);
         
        //用数组标识括号可能出现的位置
        int[][] chindex1 = {{0, 4}, {2, 6},  {4, 8}, {0, 6}, {2, 8}};
        int[][][] chindex2 = {{{0, 6}, {1, 5}}, {{0, 6}, {3, 7}}, 
                {{2, 8}, {3, 7}}, {{2, 8}, {5, 9}}, {{0, 4}, {6, 10}}};
        //随机产生括号位置组合,插入括号
        int selectedArray = PublicFunction.getRandom(1, 3);
        if (selectedArray == 1)
        {
            int index = PublicFunction.getRandom(0, 5);
            sentence = PublicFunction.insertOneElement(
                    sentence, chindex2[index][0][0], ch[0]);
            sentence = PublicFunction.insertOneElement(
                    sentence, chindex2[index][0][1], ch[1]);
            sentence = PublicFunction.insertOneElement(
                    sentence, chindex2[index][1][0], ch[0]);
            sentence = PublicFunction.insertOneElement(
                    sentence, chindex2[index][1][1], ch[1]);    
        }
        else
        {
            int index = PublicFunction.getRandom(0, 5);
            sentence = PublicFunction.insertOneElement(
                    sentence, chindex1[index][0], ch[0]);
            sentence = PublicFunction.insertOneElement(
                    sentence, chindex1[index][1], ch[1]);
        }
        return sentence;
    }
}
 
 
PublicFunction.java
 
package com.allen;
import java.util.Random;
 
public class PublicFunction {    
    /**
     * 获取指定范围的随机数
     * @param from 指定范围最小值
     * @param to   指定范围最大值
     * @return     指定范围的随机数
     */
    public static int getRandom(int from, int to) {
        return new Random().nextInt(to)%(to-from) + from;
    }
    /**
     * 求阶乘
     * @param n 阶数
     * @return 阶乘
     */
    public static int getFabonacci(int n) {
        if (n==0 | n == 1) return 1;
        else return n*getFabonacci(n-1);
    }    
     
    /**
     * 删除整型数组中的一个元素
     * @param 整型数组
     * @param 删除的元素
     * @return 删除后的整型数组
     */
    public static int[] deleteOneElement(int[] array, int element) {
        int[] result = new int[array.length-1];
        int mark = 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == element) {
                mark = i;
                break;
            }
        }
        int index = 0;
        for (int i = 0; i < mark; i++) {
            result[index] = array[i]; 
            index++;
        }
        for (int i = mark + 1; i < array.length;  i++) {
            result[index] = array[i];
            index++;
        }
        return result;
    }
 
    /**
     * 判断字符数组array中是否存在元素element
     * @param array   字符数组
     * @param element 元素
     * @return        数组array中是否存在元素element
     */
    public static boolean isExistsElement(String[] array, String element) {
        boolean result = false;
        if (array == null) return false;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == null) break;
            if (array[i].equals(element)) 
                result = true;
        }
        return result;
    }
     
    /**
     * 字符串数组插入一个元素
     * @param array 字符串数组
     * @param insertIndex 插入位置
     * @param element 插入元素
     * @return 插入后的字符串数组
     */
    public static String[] insertOneElement(
            String[] array, int insertIndex, String element) {
        String[] result = new String[array.length+1];
        int index = 0;
        for (int i = 0; i < insertIndex; i++) {
            result[index] = array[i];
            index++;
        }
        result[index] = element;
        index++;
        if (insertIndex == (array.length-1))
            result[index] = array[insertIndex];
        for (int i = insertIndex; i < array.length; i++) {
            result[index] = array[i];
            index++;
        }
        return result;        
    }
}

 

【上篇】
【下篇】

抱歉!评论已关闭.