经典纸牌游戏:24点游戏
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
注:此程序篇幅较长,但原理较容易理解。
过程解析:
一、取四个在1~13里边的随机数,并把对应的数字改为扑克牌对应的字母;
二、将四个符号放入一个char数组中,以便之后使用;
三、列举四个数字所能出现的所有状况,并将其一一对应的列举出来,并把数字和符号放在一起做一个函数;
四、算数步骤由于有三个符号,所以默认会有三个步骤,将三个步骤一一划分,并在每次运算完成后都给式子带上括号,这样首先不存在由于运算顺序导致的算数值出错;
五、将所有数字所能出现的情况做一个整合,并用函数和三个步骤的运算结合在一起,得出运算式子。
源程序:
package zhipai;
import java.util.Random;
public class you {
static char[] operator= {'+','-','*','/'};
static int z[]=new int[4]; //随机数所要进入的数组
static int se=0;//判断运算能不能得到24的值
public static void suiji(int z[])
{
Random r=new Random();
int a1=r.nextInt(13)+1;
int a2=r.nextInt(13)+1;
int a3=r.nextInt(13)+1;
int a4=r.nextInt(13)+1;
z[0]=a1;
z[1]=a2;
z[2]=a3;
z[3]=a4;//四个随机数的产生
}
public static void main(String[] args) {
int b[]=new int[4];
suiji(b);
for(int i=0;i<4;i++) {
if(b[i]==1) {
System.out.println("A");
}
else if(b[i]==11) {
System.out.println("J");
}
else if(b[i]==12) {
System.out.println("Q");
}
else if(b[i]==13) {
System.out.println("K");
}//根据扑克牌的规定将数字改为扑克牌的数值
else
System.out.println(b[i]);
}
for(int j=0;j<4;j++) {
z[j]=b[j];//将随机数赋值给全局数组
}
paixu();
}
public static int fu(int a , int b,char operator)
{
if(operator=='+')
{
return a+b;
}
else if((operator=='-')&&(a>b)) {
return a-b;
}
else if(operator=='*') {
return a*b;
}
else if((operator=='/')&&(b!=0)&&(a%b==0)&&(a>b)) {
return a/b;
}//各个符号所代表的意义
else
return -1;
}
public static void suan(int a,int b,int c,int d) {
for(int i=0;i<4;i++)
{
char operator1=operator[i];
int v1=fu(a,b,operator1);
int v2=fu(b,c,operator1);
int v3=fu(c,d,operator1);//第一步的运算
for(int j=0;j<4;j++) {
char operator2=operator[j];
int v12=fu(v1,c,operator2);
int v13=fu(c,d,operator2);
int v21=fu(a,v2,operator2);
int v23=fu(v2,d,operator2);
int v32=fu(b,v3,operator2);//第二步运算
for(int k=0;k<4;k++) {
char operator3=operator[k];//第三步运算
if(fu(v12,d,operator3)==24) {
System.out.println("(("+a+operator1+b+")"+operator2+c+")"+operator3+d);
se=1;
}
if(fu(v1,v13,operator3)==24) {
System.out.println("("+a+operator1+b+")"+operator3+"("+c+operator2+d+")");
se=1;
}
if(fu(v21,d,operator3)==24) {
System.out.println(""+a+operator3+"(("+b+operator1+c+")"+operator2+d+")");
se=1;
}
if(fu(a,v32,operator3)==24) {
System.out.println(""+a+operator3+"("+b+operator2+"("+c+operator1+d+"))");
se=1;
}//输出所有可以得到24的式子
}
}
}
}
public static void paixu() {//由于不同的随机数可能会有不同的排列组合,所以根据情况将随机数的排列列出来
if(z[0]==z[1]&&z[1]==z[2]&&z[2]==z[3]) {
suan(z[0],z[1],z[2],z[3]);
}
if(z[0]==z[1]&&z[1]!=z[2]&&z[2]!=z[3]&&z[1]!=z[3]) {
suan(z[0],z[0],z[2],z[3]);
suan(z[0],z[0],z[3],z[2]);
suan(z[0],z[2],z[0],z[3]);
suan(z[0],z[2],z[3],z[0]);
suan(z[0],z[3],z[0],z[2]);
suan(z[0],z[3],z[2],z[0]);
suan(z[2],z[0],z[0],z[3]);
suan(z[2],z[0],z[3],z[0]);
suan(z[2],z[3],z[0],z[0]);
suan(z[3],z[0],z[0],z[2]);
suan(z[3],z[0],z[2],z[0]);
suan(z[3],z[2],z[0],z[0]);
}
if(z[0]==z[2]&&z[2]!=z[1]&&z[2]!=z[3]&&z[1]!=z[3]) {
suan(z[0],z[0],z[1],z[3]);
suan(z[0],z[0],z[3],z[1]);
suan(z[0],z[1],z[0],z[3]);
suan(z[0],z[1],z[3],z[0]);
suan(z[0],z[3],z[0],z[1]);
suan(z[0],z[3],z[1],z[0]);
suan(z[1],z[0],z[0],z[3]);
suan(z[1],z[0],z[3],z[0]);
suan(z[1],z[3],z[0],z[0]);
suan(z[3],z[0],z[0],z[1]);
suan(z[3],z[0],z[1],z[0]);
suan(z[3],z[1],z[0],z[0]);
}
if(z[0]==z[3]&&z[0]!=z[1]&&z[0]!=z[2]&&z[1]!=z[2]) {
suan(z[0],z[0],z[1],z[2]);
suan(z[0],z[0],z[2],z[1]);
suan(z[0],z[1],z[0],z[2]);
suan(z[0],z[1],z[2],z[0]);
suan(z[0],z[2],z[0],z[1]);
suan(z[0],z[2],z[1],z[0]);
suan(z[1],z[0],z[0],z[2]);
suan(z[1],z[0],z[2],z[0]);
suan(z[1],z[2],z[0],z[0]);
suan(z[2],z[0],z[0],z[1]);
suan(z[2],z[0],z[1],z[0]);
suan(z[2],z[1],z[0],z[0]);
}
if(z[0]==z[1]&&z[2]==z[3]&&z[0]!=z[2]) {
suan(z[0],z[0],z[2],z[2]);
suan(z[0],z[2],z[0],z[2]);
suan(z[0],z[2],z[2],z[0]);
suan(z[2],z[2],z[0],z[0]);
suan(z[2],z[0],z[2],z[0]);
suan(z[2],z[0],z[0],z[2]);
}
if(z[0]==z[2]&&z[1]==z[3]&&z[1]!=z[2]) {
suan(z[0],z[0],z[1],z[1]);
suan(z[0],z[1],z[0],z[1]);
suan(z[0],z[1],z[1],z[0]);
suan(z[1],z[1],z[0],z[0]);
suan(z[1],z[0],z[1],z[0]);
suan(z[1],z[0],z[0],z[1]);
}
if(z[0]==z[3]&&z[1]==z[2]&&z[0]!=z[1]) {
suan(z[0],z[0],z[2],z[2]);
suan(z[0],z[2],z[0],z[2]);
suan(z[0],z[2],z[2],z[0]);
suan(z[2],z[2],z[0],z[0]);
suan(z[2],z[0],z[2],z[0]);
suan(z[2],z[0],z[0],z[2]);
}
if(z[0]==z[1]&&z[3]==z[2]&&z[0]!=z[3]) {
suan(z[0],z[0],z[0],z[3]);
suan(z[0],z[0],z[3],z[0]);
suan(z[0],z[3],z[0],z[0]);
suan(z[3],z[0],z[0],z[0]);
}
if(z[0]==z[1]&&z[1]==z[3]&&z[0]!=z[2]) {
suan(z[0],z[0],z[0],z[2]);
suan(z[0],z[0],z[2],z[0]);
suan(z[0],z[2],z[0],z[0]);
suan(z[2],z[0],z[0],z[0]);
}
if(z[0]==z[2]&&z[2]==z[3]&&z[0]!=z[1]) {
suan(z[0],z[0],z[0],z[1]);
suan(z[0],z[0],z[1],z[0]);
suan(z[0],z[1],z[0],z[0]);
suan(z[1],z[0],z[0],z[0]);
}
if(z[1]==z[2]&&z[2]==z[3]&&z[0]!=z[1]) {
suan(z[0],z[1],z[1],z[1]);
suan(z[1],z[0],z[1],z[1]);
suan(z[1],z[1],z[0],z[1]);
suan(z[1],z[1],z[1],z[0]);
}
if(z[0]!=z[1]&&z[0]!=z[2]&&z[0]!=z[3]&&z[1]!=z[2]&&z[2]!=z[3]) {
suan(z[0],z[1],z[2],z[3]);
suan(z[0],z[1],z[3],z[2]);
suan(z[0],z[2],z[1],z[3]);
suan(z[0],z[2],z[3],z[1]);
suan(z[0],z[3],z[1],z[2]);
suan(z[0],z[3],z[2],z[1]);
suan(z[1],z[0],z[2],z[3]);
suan(z[1],z[0],z[3],z[2]);
suan(z[1],z[2],z[0],z[3]);
suan(z[1],z[2],z[3],z[0]);
suan(z[1],z[3],z[0],z[2]);
suan(z[1],z[3],z[2],z[0]);
suan(z[2],z[0],z[1],z[3]);
suan(z[2],z[0],z[3],z[1]);
suan(z[2],z[1],z[0],z[3]);
suan(z[2],z[1],z[3],z[0]);
suan(z[2],z[3],z[0],z[1]);
suan(z[2],z[3],z[1],z[0]);
suan(z[3],z[0],z[1],z[2]);
suan(z[3],z[0],z[2],z[1]);
suan(z[3],z[1],z[0],z[2]);
suan(z[3],z[1],z[2],z[0]);
suan(z[3],z[2],z[1],z[0]);
suan(z[3],z[2],z[0],z[1]);
}
if(se==0) {
System.out.println("这四张纸牌不能通过运算得到24!");
}
}
}
程序结果截屏:
结果一:四个数字运算可以得出24
结果二:通过四则运算不能得出24
程序调试:
程序在进入在开始的随机函数时的调试:
程序进入运算第一步时调试:
各个步骤运算的总调试:
程序测试:
随机函数测试代码:
package zhipaiceshi;
import java.util.Random;
public class ce {
public static void main(String[] args) {
int z[]=new int[4];
Random r=new Random();
int a1=r.nextInt(13)+1;
int a2=r.nextInt(13)+1;
int a3=r.nextInt(13)+1;
int a4=r.nextInt(13)+1;
z[0]=a1;
z[1]=a2;
z[2]=a3;
z[3]=a4;//四个随机数的产生
for(int i=0;i<4;i++) {
if(z[i]==1) {
System.out.println("A");
}
else if(z[i]==11) {
System.out.println("J");
}
else if(z[i]==12) {
System.out.println("Q");
}
else if(z[i]==13) {
System.out.println("K");
}//根据扑克牌的规定将数字改为扑克牌的数值
else
System.out.println(z[i]);
}
}
}
代码结果截屏:
运算函数测试代码:
package zhipaiceshi;
import java.util.Scanner;
public class ceshi1 {
static char[] operator= {'+','-','*','/'};
public static void main(String[] args) {
Scanner x=new Scanner(System.in);
System.out.print("请输入a的值");
int a=x.nextInt();
System.out.print("请输入b的值");
int b=x.nextInt();
for(int i=0;i<4;i++) {
char operator1=operator[i];
System.out.println(fu(a,b,operator1));
}
}
public static int fu(int a , int b,char operator)
{
if(operator=='+')
{
return a+b;
}
else if((operator=='-')&&(a>b)) {
return a-b;
}
else if(operator=='*') {
return a*b;
}
else if((operator=='/')&&(b!=0)&&(a%b==0)&&(a>b)) {
return a/b;
}//各个符号所代表的意义
else
return -1;
}
}
测试结果截屏:
式子测试代码:
package zhipaiceshi;
import java.util.Scanner;
public class ceshi2 {
static char[] operator= {'+','-','*','/'};
static int se=0;
public static void main(String[] args) {
Scanner x=new Scanner(System.in);
System.out.print("请输入a的值");
int a=x.nextInt();
System.out.print("请输入b的值");
int b=x.nextInt();
System.out.print("请输入c的值");
int c=x.nextInt();
System.out.print("请输入d的值");
int d=x.nextInt();
for(int i=0;i<4;i++)
{
char operator1=operator[i];
int v1=fu(a,b,operator1);
int v2=fu(b,c,operator1);
int v3=fu(c,d,operator1);//第一步的运算
for(int j=0;j<4;j++) {
char operator2=operator[j];
int v12=fu(v1,c,operator2);
int v13=fu(c,d,operator2);
int v21=fu(a,v2,operator2);
int v23=fu(v2,d,operator2);
int v32=fu(b,v3,operator2);//第二步运算
for(int k=0;k<4;k++) {
char operator3=operator[k];//第三步运算
if(fu(v12,d,operator3)==24) {
System.out.println("(("+a+operator1+b+")"+operator2+c+")"+operator3+d);
se=1;
}
if(fu(v1,v13,operator3)==24) {
System.out.println("("+a+operator1+b+")"+operator3+"("+c+operator2+d+")");
se=1;
}
if(fu(v21,d,operator3)==24) {
System.out.println(""+a+operator3+"(("+b+operator1+c+")"+operator2+d+")");
se=1;
}
if(fu(a,v32,operator3)==24) {
System.out.println(""+a+operator3+"("+b+operator2+"("+c+operator1+d+"))");
se=1;
}//输出所有可以得到24的式子
}
}
}
if(se==0) {
System.out.println("这四个数不能通过四则运算得到24!");
}
}
public static int fu(int a , int b,char operator)
{
if(operator=='+')
{
return a+b;
}
else if((operator=='-')&&(a>b)) {
return a-b;
}
else if(operator=='*') {
return a*b;
}
else if((operator=='/')&&(b!=0)&&(a%b==0)&&(a>b)) {
return a/b;
}//各个符号所代表的意义
else
return -1;
}
}
测试结果截屏:
总结:
本次是第一次使用java来做,可以发现有一些用法、java的程序包等等都有一些不太知道的,在使用的过程中可能一个非常小的问题都要改半天,但我也知道了一些比较基本的非逻辑上的错误应该怎么来改;还有一个收获比较大的地方就是在有一些自己之前没有注意到的小错误,java中在自己打程序的时候都会提示出来;基本上都会不自觉的看看写出来的程序会不会有什么其他的问题。
我学会了使用全局的变量等,让整个程序变得更加的流畅,不再是之前的分裂状态,只要不在一个函数内都会存在考虑数据关系问题。
程序中存在的不足:
由于四则运算中的乘、除优先原则无法正常的在程序中体现出来,所以我采用了将每一步运算都要用括号括起来的方式,这样它不会有优先问题,但也使得整个程序变得麻烦,需要使用数字的排列组合使存在的所有情况都出现,这样程序就会大大拉长,并不简洁。
还有一个未解决的问题:
如何将一个外部调用函数直接使用着写入文件?
错误代码: bw.write(paixu());
写入文件程序代码:
package zhipaiceshi;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class xieru {
OutputStreamWriter bw=null;
try {
bw=new OutputStreamWriter(new FileOutputStream("C:\\Users\\张敏\\Desktop\\软工一班-17408070802-张敏\\源程序.TopList.txt"),"UTF-8");
for(int k=0;k<4;k++)
bw.write(z[k]);
}
catch(Exception e) {
e.printStackTrace();
}finally {
try {
if(bw!=null) {
bw.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
}