【Nodejs】“快算24”扑克牌游戏算法 1.02
快算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...从规律上讲,似乎5,7,11,13这样的素数参与越多越是难算。
算24也是有窍门的,那就是逐步缩小范围,具体来说是看三个数运算能否和第四个数通过加减乘除得到24,继而看三个数操作能否得到24和第四个数的四则运算结果,继而看两个数的操作能否得到第三个数和上次结果的四则运算结果。具体比如有2,3,4,12四个数,看到12后想2,3,4是否能组合个2出来,然后想到2*3-4的方案,或者2*(4-3)的方案。
按照这个思维我编了下面的程序。具体思路是这样的,先制作一个C4类(2,3,4,12,24),这个类会形成24种组合(以及六种特殊组合方式),再由24种组合生成6种子方案,子方案又生成六种孙方案,最后挑选出符合条件的结果。
//======================================================
// 算24 C4 1.02
// 整理代码,去掉一些多余冗杂的地方
// 2018年4月23日 完成
// 2019年3月2日修改
//======================================================
//======================================================
// 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.findComputeMethods=function(){
var micro=0.000001 // 定义一个极小量,运算结果绝对值小于它就算相等
var arr=[];
// 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-(op1-op2))<micro){
arr.push(op1+"-"+op2);
}
// op2-op1
if(Math.abs(result-(op2-op1))<micro){
arr.push(op2+"-"+op1);
}
// op1/op2
if(Math.abs(result-op1/op2)<micro){
arr.push(op1+"/"+op2);
}
// op2/op1
if(Math.abs(result-op2/op1)<micro){
arr.push(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.findComputeMethods=function(){
var retArr=[];// 最终返回数组
// 排列数组,三个操作数共有6种排列方式
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],
];
for(var i=0;i<permutationArr.length;i++){
var arr=permutationArr[i];
var op1=arr[0];
var op2=arr[1];
var op3=arr[2];
// [op1,op2]-op3
var c2=new C2(op1,op2,this.result+op3);
var methods=c2.findComputeMethods();
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.findComputeMethods();
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.findComputeMethods();
for(var j=0;j<methods.length;j++){
retArr.push('('+methods[j]+")"+"+"+op3);
}
// op3-[op1,op2]
c2=new C2(op1,op2,op3-this.result);
methods=c2.findComputeMethods();
for(var j=0;j<methods.length;j++){
retArr.push(op3+"-"+'('+methods[j]+")");
}
// [op1,op2]*op3
c2=new C2(op1,op2,this.result/op3);
methods=c2.findComputeMethods();
for(var j=0;j<methods.length;j++){
retArr.push('('+methods[j]+")"+"*"+op3);
}
// op3/[op1,op2]
c2=new C2(op1,op2,op3/this.result);
methods=c2.findComputeMethods();
for(var j=0;j<methods.length;j++){
retArr.push(op3+"/"+'('+methods[j]+")");
}
}
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.findComputeMethods=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];
// [op1,op2,op3]-op4
var c3=new C3(op1,op2,op3,this.result+op4);
var methods=c3.findComputeMethods();
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.findComputeMethods();
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.findComputeMethods();
for(var j=0;j<methods.length;j++){
retArr.push('('+methods[j]+")"+"+"+op4);
}
// op4-[op1,op2,op3]
var c3=new C3(op1,op2,op3,op4-this.result);
var methods=c3.findComputeMethods();
for(var j=0;j<methods.length;j++){
retArr.push(op4+"-"+'('+methods[j]+")");
}
// [op1,op2,op3]*op4
var c3=new C3(op1,op2,op3,this.result/op4);
var methods=c3.findComputeMethods();
for(var j=0;j<methods.length;j++){
retArr.push('('+methods[j]+")"+"*"+op4);
}
// op4/[op1,op2,op3]
var c3=new C3(op1,op2,op3,op4/this.result);
var methods=c3.findComputeMethods();
for(var j=0;j<methods.length;j++){
retArr.push(op4+"/"+'('+methods[j]+")");
}
// 以下为C4中特有的先成对组合再看运算结果的六种情况
// op1*op2-op3*op4
if(op1*op2-op3*op4==result){
retArr.push(op1+"*"+op2+"-"+op3+"*"+op4);
}
// op1*op2+op3*op4
if(op1*op2+op3*op4==result){
retArr.push(op1+"*"+op2+"+"+op3+"*"+op4);
}
// op1/op2-op3/op4
if(op1/op2-op3/op4==result){
retArr.push(op1+"/"+op2+"-"+op3+"/"+op4);
}
// op1/op2+op3/op4
if(op1/op2+op3/op4==result){
retArr.push(op1+"/"+op2+"+"+op3+"/"+op4);
}
// op1*op2-op3/op4
if(op1*op2-op3/op4==result){
retArr.push(op1+"*"+op2+"-"+op3+"/"+op4);
}
// op1*op2+op3/op4
if(op1*op2+op3/op4==result){
retArr.push(op1+"*"+op2+"+"+op3+"/"+op4);
}
}
return retArr;
}
return obj;
}
//======================================================
// 用来得到仅包含不重复元素的数组
// arr:传入的数组
//======================================================
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 RESULT=24 // 定义24这个结果
process.stdin.resume();
process.stdout.write("\033[33m 请输入四个数字,用逗号分隔: \033[39m");// 草黄色
process.stdin.setEncoding('utf8');
process.stdin.on('data',function(text){
var input=text.trim();
process.stdin.end();// 退出输入状态
var arrTemp=input.split(",");
var op1=parseInt(arrTemp[0],10);
var op2=parseInt(arrTemp[1],10);
var op3=parseInt(arrTemp[2],10);
var op4=parseInt(arrTemp[3],10);
var c4=new C4(op1,op2,op3,op4,RESULT);
var arr=getDistinctArray(c4.findComputeMethods());
if(arr.length>0){
for(var i=0;i<arr.length;i++){
console.log(arr[i]+"="+RESULT);
}
}else{
console.log(input+"这四个数无法计算得到24");
}
});
}
// 开始
main();
运行效果是这样的:
C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 12,2,3,8 ((12-8)*2)*3=24 ((12-8)*3)*2=24 ((12/2)-3)*8=24 ((12/3)+8)*2=24 ((3*8)-12)*2=24 ((3*8)/2)+12=24 ((3/2)*8)+12=24 ((8*3)-12)*2=24 ((8*3)/2)+12=24 ((8-2)*12)/3=24 ((8-2)/3)*12=24 ((8/2)*3)+12=24 (12-(8/2))*3=24 (3/(2/8))+12=24 (8-(2*3))*12=24 (8-(3*2))*12=24 (8/(2/3))+12=24 12/(3/(8-2))=24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 4,4,4,4 ((4*4)+4)+4=24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 9,9,9,9 9,9,9,9这四个数无法计算得到24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 10,10,4,4 ((10*10)-4)/4=24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 8,8,8,8 8,8,8,8这四个数无法计算得到24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 6,6,6,6 ((6*6)-6)-6=24 ((6+6)+6)+6=24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 5,5,5,5 5*5-5/5=24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 3,3,3,3 ((3*3)*3)-3=24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 2,2,2,2 2,2,2,2这四个数无法计算得到24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 12,12,12,12 ((12*12)/12)+12=24 ((12+12)*12)/12=24 ((12+12)+12)-12=24 ((12+12)-12)+12=24 ((12+12)/12)*12=24 ((12-12)+12)+12=24 ((12/12)*12)+12=24 (12-(12-12))+12=24 (12/(12/12))+12=24 12-((12-12)-12)=24 12-(12-(12+12))=24 12/(12/(12+12))=24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 11,13,4,2 11,13,4,2这四个数无法计算得到24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 12,11,13,1 ((1*13)-11)*12=24 ((13*1)-11)*12=24 ((13-11)*1)*12=24 ((13-11)*12)*1=24 ((13-11)*12)/1=24 ((13-11)/1)*12=24 ((13/1)-11)*12=24 (13-(1*11))*12=24 (13-(11*1))*12=24 (13-(11/1))*12=24 12/(1/(13-11))=24 C:\Users\horn1\Desktop\node.js\56-算24c41.02>node c24.js 请输入四个数字,用逗号分隔: 8,7,9,10 (8/(10-7))*9=24 (9/(10-7))*8=24 8/((10-7)/9)=24 9/((10-7)/8)=24
还有:

各位家长可以在和孩子玩这个游戏实在算不出来时验证下看有没有解决方案。
【Nodejs】“快算24”扑克牌游戏算法 1.02的更多相关文章
- 【Nodejs】“快算24”扑克牌游戏算法
算24是一款扑克牌游戏,它的游戏方式是把四张牌的牌面数值通过四则运算得到结果24,四张牌必须仅用一次.这是一种挺好的锻炼孩子算数能力的扑克牌游戏. 各地玩法还有点差别,有的只算1-10,其它抽出来:有 ...
- 【Nodejs】“快算24”扑克牌游戏算法 1.01
考虑到1.00版本需要改源码变更四个数字,这版修改了一下变成控制台输入了. 先把两个数四则运算得到结果想清楚就是C2代码,三个数就是C3,四个数就是C4.简单的代码简单,却是复杂的基础:复杂的脱胎于简 ...
- php实现 24点游戏算法
php实现 24点游戏算法 一.总结 一句话总结:把多元运算转化为两元运算,先从四个数中取出两个数进行运算,然后把运算结果和第三个数进行运算,再把结果与第四个数进行运算.在求表达式的过程中,最难处理的 ...
- POJ 3983:快算24
快算24 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4791 Accepted: 2930 Description ...
- 快算24点,POJ(3983)
题目链接:http://poj.org/problem?id=3983 中文题,就不解释题意了. 类似之前的一篇博客,这里也不上解释了,直接上代码吧. #include <iostream> ...
- POJ3983 快算24
很正常的题目,迷一样的答案. 测试数据只有一组,对没错只有一组. #include<cstdio> int main() { printf("5*(5-(1/5))\n" ...
- python实现算24的算法
1.介绍 给定4个整数,数字范围在1-13之间,任意使用 + - * / ( ) ,构造出一个表达式,使得最终结果为24,这就是常见的算24的游戏.本文介绍用Python语言实现的两种方式.2.实现思 ...
- 用python代替人脑运算24点游戏
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:老方玩编程 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...
- python实例:解决经典扑克牌游戏 -- 四张牌凑24点 (二)
Hey! 如果你还没有看这篇的上文的话,可以去稍稍瞅一眼,会帮助加速理解这一篇里面涉及到的递归结构哦!(上一篇点这里:<python实例:解决经典扑克牌游戏 -- 四张牌凑24点 (一)> ...
随机推荐
- iptables配置允许mysql远程访问
vi /etc/sysconfig/iptables iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCE ...
- python开发_webbrowser_浏览器控制模块
''' python的webbrowser模块支持对浏览器进行一些操作 主要有以下三个方法: webbrowser.open(url, new=0, autoraise=True) webbrowse ...
- UOJ 12 猜数 数学题
[UER #1]猜数 这一天,小Y.小D.小C正在愉快地玩耍. 小Y是个数学家,他一拍脑袋冒出了一个神奇的完全平方数 n. 小D是个机灵鬼,很快从小Y嘴里套出了 n 的值.然后在脑内把 n 写成了 a ...
- Android 5.0 源代码结构
本节书摘来自异步社区<深入理解Android 5 源代码>一书中的第2章,第2.2节分析Android源代码结构,作者 李骏. 网址:https://yq.aliyun.com/artic ...
- Windows Server 2016 Essentials试用
下载地址: Windows Server 2016 Essentials (x64) SHA-1: 6E1D1880873157ADCEF3D74363308A95DC89103D ed ...
- C#程序集系列04,在程序集包含多个module的场景下理解关键字internal
本篇在一个程序集包含多个module的场景下体验internal的含义. →查看F盘as文件夹下的文件→删除MainClass.exe→把MyFirstModule和MySecondModule组装到 ...
- MVC中使用AngularJS-01,基本
Angularjs是一个前端的Javascript MVC 库和框架,使前端得到更好的设计.维护和测试.它的核心特性有:MVC.双向数据绑定.指令和语义化标签.模块化工具.依赖注入.HTML模板,以及 ...
- Spring初始化完成后直接执行一个方法,初始化数据(解决方法被重复执行两次的情况)
在做WEB项目时,经常在项目第一次启动时利用WEB容器的监听.Servlet加载初始化等切入点为数据库准备数据,这些初始化数据 是系统开始运行前必须的数据,例如权限组.系统选项.默认管理员等等.但是项 ...
- Google Admob广告Android全攻略1
一.登录Google AdMob中文官网:http://www.google.cn/ads/admob/ ,注册帐号. 1.点击注册AdMob帐号 2.进入Google帐号注册页面,因为要创建一个 ...
- Java Web开发基础(2)-JSP
上一篇博我粗略的介绍了一下Servlet.粗略是由于博主也刚刚学习这部分的内容,还不是非常懂所以无法讲的非常精细.可是本着二八原则,我还是先继续学习.所以,这篇博客接着JSP的内容.由于.这两个内容关 ...