算24是一款扑克牌游戏,它的游戏方式是把四张牌的牌面数值通过四则运算得到结果24,四张牌必须仅用一次。这是一种挺好的锻炼孩子算数能力的扑克牌游戏。

各地玩法还有点差别,有的只算1-10,其它抽出来;有的地方把整幅牌都算上,把其中J当作11,Q当作12,K当作13,小王当作15,大王当作18. 个人觉得后者不但省了理牌还更能锻炼人。

绝大多数四张牌的组合都容易算出来,有部分就要费点脑筋了,如5,5,5,1;3,7,3,7;12,12,12,10...,当然也有完全算不出来的,如5,7,8,11;1,1,6,11...

算24也是有窍门的,那就是逐步缩小范围,具体来说是看三个数运算能否和第四个数通过加减乘除得到24,继而看三个数操作能否得到24和第四个数的四则运算结果,继而看两个数的操作能否得到第三个数和上次结果的四则运算结果。具体比如有2,3,4,12四个数,看到12后想2,3,4是否能组合个2出来,然后想到2*3-4的方案。

按照这个思维我编了下面的程序,各位家长可以在和孩子玩这个游戏实在算不出来时验证下看有没有解决方案。

//======================================================
// “快算24”扑克牌游戏算法
// 2018年4月18日 逆火
//======================================================

var micro=0.000001 // 定义一个极小量,运算结果绝对值小于它就算相等

//======================================================
// C2类,用于判断两个数通过加减乘除运算能否得到某个结果
// C代表Caculate,2代表两个操作数
// op1:操作数1,op2:操作数2,result,结果
//======================================================
function C2(op1,op2,result){
    var obj=new Object();
    obj.op1=op1;
    obj.op2=op2;
    obj.result=result;

    obj.findComputationMethods=function(){
        var arr=[];

        if(Math.abs(result-(op1+op2))<micro){
            arr.push(op1+"+"+op2);    // op1+op2
        }

        if(Math.abs(result-op1*op2)<micro){
            arr.push(op1+"*"+op2);    // op1*op2
        }

        if(Math.abs(result-(op1-op2))<micro){
            arr.push(op1+"-"+op2);    // op1-op2
        }

        if(Math.abs(result-(op2-op1))<micro){
            arr.push(op2+"-"+op1);    // op2-op1
        }

        if(Math.abs(result-op1/op2)<micro){
            arr.push(op1+"/"+op2);    // op1/op2
        }

        if(Math.abs(result-op2/op1)<micro){
            arr.push(op2+"/"+op1);    // op2/op1
        }

        return arr;
    }

    return obj;
}

//======================================================
// C3类,用于判断三个数通过加减乘除运算能否得到某个结果
// C代表Caculate,3代表两个操作数
// op1:操作数1,op2:操作数2,op3:操作数3,result,结果
//======================================================
function C3(op1,op2,op3,result){
    var obj=new Object();
    obj.op1=op1;
    obj.op2=op2;
    obj.op3=op3;
    obj.result=result;

    obj.findComputationMethods=function(){
        var retArr=[];// 返回数组

        var permutationArr=[ [this.op1,this.op2,this.op3],
                        [this.op1,this.op3,this.op2],
                        [this.op2,this.op1,this.op3],
                        [this.op2,this.op3,this.op1],
                        [this.op3,this.op2,this.op1],
                        [this.op3,this.op1,this.op2], ]; // 排列数组,三个操作数共有6种排列方式

        for(var i=0;i<permutationArr.length;i++){
            var arr=permutationArr[i];
            var op1=arr[0];
            var op2=arr[1];
            var op3=arr[2];

            var c2=new C2(op1,op2,this.result+op3);
            var methods=c2.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push('('+methods[j]+")"+"-"+op3);// [op1,op2]-op3
                }
            }

            c2=new C2(op1,op2,this.result*op3);
            methods=c2.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push('('+methods[j]+")"+"/"+op3);// [op1,op2]/op3
                }
            }

            c2=new C2(op1,op2,this.result-op3);
            methods=c2.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push('('+methods[j]+")"+"+"+op3);// [op1,op2]+op3
                }
            }

            c2=new C2(op1,op2,op3-this.result);
            methods=c2.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push(op3+"-"+'('+methods[j]+")");// op3-[op1,op2]
                }
            }

            c2=new C2(op1,op2,this.result/op3);
            methods=c2.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push('('+methods[j]+")"+"*"+op3);// [op1,op2]*op3
                }
            }

            c2=new C2(op1,op2,op3/this.result);
            methods=c2.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push(op3+"/"+'('+methods[j]+")");// op3/[op1,op2]
                }
            }
        }

        return retArr;
    };

    return obj;
}

//======================================================
// C4类,用于判断三个数通过加减乘除运算能否得到某个结果
// C代表Caculate,4代表两个操作数
// op1:操作数1,op2:操作数2,op3:操作数3,op4:操作数4,result,结果
//======================================================
function C4(op1,op2,op3,op4,result){
    var obj=new Object();
    obj.op1=op1;
    obj.op2=op2;
    obj.op3=op3;
    obj.op4=op4;
    obj.result=result;

    obj.findComputationMethods=function(){
        var retArr=[];// 返回数组

        var permutationArr=[    [this.op1,this.op2,this.op3,this.op4],
                             [this.op1,this.op2,this.op4,this.op3],
                             [this.op1,this.op3,this.op2,this.op4],
                             [this.op1,this.op3,this.op4,this.op2],
                             [this.op1,this.op4,this.op2,this.op3],
                             [this.op1,this.op4,this.op3,this.op2],
                                [this.op2,this.op1,this.op3,this.op4],
                             [this.op2,this.op1,this.op4,this.op3],
                             [this.op2,this.op3,this.op1,this.op4],
                             [this.op2,this.op3,this.op4,this.op1],
                             [this.op2,this.op4,this.op1,this.op3],
                             [this.op2,this.op4,this.op3,this.op1],
                                [this.op3,this.op1,this.op2,this.op4],
                             [this.op3,this.op1,this.op4,this.op2],
                             [this.op3,this.op2,this.op1,this.op4],
                             [this.op3,this.op2,this.op4,this.op1],
                             [this.op3,this.op4,this.op1,this.op2],
                             [this.op3,this.op4,this.op2,this.op1],
                                [this.op4,this.op1,this.op2,this.op3],
                             [this.op4,this.op1,this.op3,this.op2],
                             [this.op4,this.op2,this.op1,this.op3],
                             [this.op4,this.op2,this.op3,this.op1],
                             [this.op4,this.op3,this.op1,this.op2],
                             [this.op4,this.op3,this.op2,this.op1],
                           ]; // 排列数组,四个操作数共有24种排列方式

        for(var i=0;i<permutationArr.length;i++){
            var arr=permutationArr[i];

            var op1=arr[0];
            var op2=arr[1];
            var op3=arr[2];
            var op4=arr[3];            

            var c3=new C3(op1,op2,op3,this.result+op4);
            var methods=c3.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push('('+methods[j]+")"+"-"+op4);// [op1,op2,op3]-op4
                }
            }

            var c3=new C3(op1,op2,op3,this.result*op4);
            var methods=c3.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push('('+methods[j]+")"+"/"+op4);// [op1,op2,op3]/op4
                }
            }

            var c3=new C3(op1,op2,op3,this.result-op4);
            var methods=c3.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push('('+methods[j]+")"+"+"+op4);// [op1,op2,op3]+op4
                }
            }

            var c3=new C3(op1,op2,op3,op4-this.result);
            var methods=c3.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push(op4+"-"+'('+methods[j]+")");// op4-[op1,op2,op3]
                }
            }

            var c3=new C3(op1,op2,op3,this.result/op4);
            var methods=c3.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push('('+methods[j]+")"+"*"+op4);// [op1,op2,op3]*op4
                }
            }

            var c3=new C3(op1,op2,op3,op4/this.result);
            var methods=c3.findComputationMethods();
            if(methods.length>0){
                for(var j=0;j<methods.length;j++){
                    retArr.push(op4+"/"+'('+methods[j]+")");// op4/[op1,op2,op3]
                }
            }

            if(op1*op2-op3*op4==result){
                retArr.push(op1+"*"+op2+"-"+op3+"*"+op4);// op1*op2-op3*op4,这是c3里不曾有的
            }

            if(op1*op2+op3*op4==result){
                retArr.push(op1+"*"+op2+"+"+op3+"*"+op4);// op1*op2+op3*op4,这是c3里不曾有的
            }

            if(op1/op2-op3/op4==result){
                retArr.push(op1+"/"+op2+"-"+op3+"/"+op4);// op1/op2-op3/op4,这是c3里不曾有的
            }

            if(op1/op2+op3/op4==result){
                retArr.push(op1+"/"+op2+"+"+op3+"/"+op4);// op1/op2+op3/op4,这是c3里不曾有的
            }

            if(op1*op2-op3/op4==result){
                retArr.push(op1+"*"+op2+"-"+op3+"/"+op4);// op1*op2-op3/op4,这是c3里不曾有的
            }

            if(op1*op2+op3/op4==result){
                retArr.push(op1+"*"+op2+"+"+op3+"/"+op4);// op1*op2+op3/op4,这是c3里不曾有的
            }
        }

        return retArr;
    }

    return obj;
}

//======================================================
// 用来得到仅包含不重复元素的数组
//======================================================
function getDistinctArray(arr){
    var returnArr=new Array();

    var sortedArr=arr.sort();
    for(var i=0;i<sortedArr.length;i++){
        if(returnArr[returnArr.length-1]!=sortedArr[i]){
            returnArr.push(sortedArr[i]);
        }
    }

    return returnArr;
}

//======================================================
// 程序入口 人生之路就是一个个未竟之志铺起来的
//======================================================
function main(){
    var c4=new C4(6,7,9,10,24);
    var arr=getDistinctArray(c4.findComputationMethods());

    for(var i=0;i<arr.length;i++){
        console.log(arr[i]+"=24");
    }
}

// 开始
main();

2018年4月21日05点21分

【Nodejs】“快算24”扑克牌游戏算法的更多相关文章

  1. 【Nodejs】“快算24”扑克牌游戏算法 1.02

    快算24是一种挺好的锻炼孩子算数能力的扑克牌游戏,它的游戏方式是把四张牌的牌面数值通过有限四则运算得到结果24,四张牌必须仅用一次.各地玩法还有点差别,有的只算1-10,其它抽出来:有的地方把整幅牌都 ...

  2. 【Nodejs】“快算24”扑克牌游戏算法 1.01

    考虑到1.00版本需要改源码变更四个数字,这版修改了一下变成控制台输入了. 先把两个数四则运算得到结果想清楚就是C2代码,三个数就是C3,四个数就是C4.简单的代码简单,却是复杂的基础:复杂的脱胎于简 ...

  3. php实现 24点游戏算法

    php实现 24点游戏算法 一.总结 一句话总结:把多元运算转化为两元运算,先从四个数中取出两个数进行运算,然后把运算结果和第三个数进行运算,再把结果与第四个数进行运算.在求表达式的过程中,最难处理的 ...

  4. POJ 3983:快算24

    快算24 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4791   Accepted: 2930 Description ...

  5. 快算24点,POJ(3983)

    题目链接:http://poj.org/problem?id=3983 中文题,就不解释题意了. 类似之前的一篇博客,这里也不上解释了,直接上代码吧. #include <iostream> ...

  6. POJ3983 快算24

    很正常的题目,迷一样的答案. 测试数据只有一组,对没错只有一组. #include<cstdio> int main() { printf("5*(5-(1/5))\n" ...

  7. python实现算24的算法

    1.介绍 给定4个整数,数字范围在1-13之间,任意使用 + - * / ( ) ,构造出一个表达式,使得最终结果为24,这就是常见的算24的游戏.本文介绍用Python语言实现的两种方式.2.实现思 ...

  8. 用python代替人脑运算24点游戏

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:老方玩编程 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...

  9. python实例:解决经典扑克牌游戏 -- 四张牌凑24点 (二)

    Hey! 如果你还没有看这篇的上文的话,可以去稍稍瞅一眼,会帮助加速理解这一篇里面涉及到的递归结构哦!(上一篇点这里:<python实例:解决经典扑克牌游戏 -- 四张牌凑24点 (一)> ...

随机推荐

  1. loj#2721. 「NOI2018」屠龙勇士

    题目链接 loj#2721. 「NOI2018」屠龙勇士 题解 首先可以列出线性方程组 方程组转化为在模p意义下的同余方程 因为不保证pp 互素,考虑扩展中国剩余定理合并 方程组是带系数的,我们要做的 ...

  2. CF17E Palisection 差分+manacher算法

    题目大意: 给定一个串$S$,询问有多少对相交的回文子串 直接做的办法: 我们先考虑求出以$i$为结尾的串的数量,这个很好统计 之后,我们再求出所有包含了点$i$的回文串的数目 这个相当于在$i$的左 ...

  3. [BZOJ5305][HAOI2018]苹果树(DP)

    首先注意到每种树都是等概率出现的,于是将问题转化成计数求和问题. f[n]表示所有n个点的树的两两点距离和的总和. g[n]表示所有n个点的树的所有点到根的距离和的总和. h[n]表示n个点的树的可能 ...

  4. SPOJ QTREE

    QTREE /* 题目大意:维护一棵树,允许修改边权以及查询链上最大值 题解:我们将边权转为点权,标记在深度较深的点上,树链剖分后用线段树处理即可 */ #include <cstdio> ...

  5. Curl 及 Curl的使用介绍

    Curl 简介 Curl是Linux下一个很强大的http命令行工具,其功能十分强大. 1) 二话不说,先从这里开始吧! $ curl http://www.linuxidc.com 回车之后,www ...

  6. python日常碎碎念

    关于取命令行中参数的方法 1,sys.argv 这个方法自动获取参数,并split.一般情况下第一个元素是程序的名字.即 python script.py arg1 arg2 然后sys.argv返回 ...

  7. Codeforces Round #356 (Div. 1) D. Bear and Chase 暴力

    D. Bear and Chase 题目连接: http://codeforces.com/contest/679/problem/D Description Bearland has n citie ...

  8. NOIP 2002提高组 选数 dfs/暴力

    1008 选数 2002年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 已知 n 个整数 x1,x2,…, ...

  9. Git_时光机穿梭

    我们已经成功地添加并提交了一个readme.txt文件,现在,是时候继续工作了,于是,我们继续修改readme.txt文件,改成如下内容: Git is a distributed version c ...

  10. Ubuntu16.04配置Android5.0编译环境

    1.安装jdk7 Ubuntu16.04的安装源已经默认没有openjdk7了,所以要自己手动添加仓库,如下: $ sudo add-apt-repository ppa:openjdk-r/ppa ...