案例一24点游戏

任务要求:输入4个数字,进行+-*/各种运算拼凑出24

现在用junit测试看是否输入的4个数字能拼凑出24,还有就是对比满足条件的第一个式子是否为8/(3-8/3)即预期值8/(3-8/3)

项目框架:

业务代码:

实现24点(这个不是本课程重点)

//
//  Calc24.java
//  
//
//  Created by Xie Qian on 10-8-27.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//
package test;

import java.util.ArrayList;
import java.util.List;

public class Calc24New {
    private static int iOprs[][] = new int[64][3];
    static {
       // initialize operator composition.
       int i = 0;
       for (int j1 = 0; j1 < 4; j1++)
          for (int j2 = 0; j2 < 4; j2++)
             for (int j3 = 0; j3 < 4; j3++) {
                iOprs[i][0] = j1;
                iOprs[i][1] = j2;
                iOprs[i][2] = j3;
                i++;
             }
    }

    private int iComps, iSeqs[][];
    private int iPriority;
    private int iNum[] = new int[4];
    private int iSeq[] = new int[4];
    private int iOpr[] = new int[3];
    private final char opr[] = { '+', '-', '*', '/' };
    private List<String> lst = new ArrayList<String>();

    public Calc24New(int a, int b, int c, int d) {
       int iRows = 0;
       // assign and sort.
       iNum[0] = a;
       if(iNum[0]>b) {
          iNum[1] = iNum[0];
          iNum[0] = b;
       }
       else
          iNum[1] = b;
       if(iNum[1]>c) {
          iNum[2] = iNum[1];
          iNum[1] = c;
       }
       else
          iNum[2] = c;
       if(iNum[2]>d) {
          iNum[3] = iNum[2];
          iNum[2] = d;
       }
       else
          iNum[3] = d;   // iNum[3] is biggest
       if(iNum[0]>iNum[1]) {
          iNum[0] += iNum[1];
          iNum[1] = iNum[0] - iNum[1];
          iNum[0] -= iNum[1];
       }
       if(iNum[1]>iNum[2]) {
          iNum[1] += iNum[2];
          iNum[2] = iNum[1] - iNum[2];
          iNum[1] -= iNum[2];
       }  // iNum[2] is second biggest
       if(iNum[0]>iNum[1]) {
          iNum[0] += iNum[1];
          iNum[1] = iNum[0] - iNum[1];
          iNum[0] -= iNum[1];
       }  // ok
       
       if(iNum[0]==iNum[3]) { // 4 equal
          iComps = 1;
          iSeqs = new int[iComps][4];
          for(int i=0;i<4;i++)
             iSeqs[iRows][i] = iNum[i];
       } 
       else if(iNum[0]==iNum[2]||iNum[1]==iNum[3]) {  // 3 equal
          if(iNum[0]==iNum[2]) {
             iNum[0] += iNum[3];
             iNum[3] = iNum[0] - iNum[3];
             iNum[0] -= iNum[3];
          }  // iNum[0] is different
          iComps = 4;
          iSeqs = new int[iComps][4];
          for(iRows=0;iRows<iComps;iRows++)
             for(int i=0;i<4;i++) {
                if(i==iRows)
                   iSeqs[iRows][i] = iNum[0];
                else
                   iSeqs[iRows][i] = iNum[3];
             }
       }
       else if(iNum[0]==iNum[1]&&iNum[2]==iNum[3]) {  // 2 pairs
          iComps = 6;
          iSeqs = new int[iComps][4];
          for (int i1 = 1; i1 < 3; i1++)
             for (int i2 = 1; i2 < 3; i2++)
                for (int i3 = 1; i3 < 3; i3++)
                   for (int i4 = 1; i4 < 3; i4++) {
                      if (i1 + i2 + i3 + i4 != 6)       // !!!
                         continue;
                      iSeqs[iRows][0] = iNum[i1];
                      iSeqs[iRows][1] = iNum[i2];
                      iSeqs[iRows][2] = iNum[i3];
                      iSeqs[iRows][3] = iNum[i4];
                      iRows ++;
                   }
       }
       else if(iNum[0]==iNum[1]||iNum[1]==iNum[2]||iNum[2]==iNum[3]) {    // 2 equal
          if(iNum[1]==iNum[2]) {
             iNum[1] += iNum[3];
             iNum[3] = iNum[1] - iNum[3];
             iNum[1] -= iNum[3];
          }
          else if(iNum[0]==iNum[1]) {
             iNum[0] += iNum[2];
             iNum[2] = iNum[0] - iNum[2];
             iNum[0] -= iNum[2];
             iNum[1] += iNum[3];
             iNum[3] = iNum[1] - iNum[3];
             iNum[1] -= iNum[3];
          }  // iNum[2]==iNum[3];
          iComps = 12;
          iSeqs = new int[iComps][4];
          for (int i1 = 0; i1 < 3; i1++)
             for (int i2 = 0; i2 < 3; i2++)
                for (int i3 = 0; i3 < 3; i3++)
                   for (int i4 = 0; i4 < 3; i4++) {
                      if (i1 + i2 + i3 + i4 != 5 || (i1!=0 && i2!=0 && i3!=0 && i4!=0) )    // !!!
                         continue;
                      iSeqs[iRows][0] = iNum[i1];
                      iSeqs[iRows][1] = iNum[i2];
                      iSeqs[iRows][2] = iNum[i3];
                      iSeqs[iRows][3] = iNum[i4];
                      iRows ++;
                   }
       }
       else { // all different
          iComps = 24;
          iSeqs = new int[iComps][4];
          for (int i1 = 0; i1 < 4; i1++)
             for (int i2 = 0; i2 < 4; i2++) {
                if (i2 == i1)
                   continue;
                for (int i3 = 0; i3 < 4; i3++) {
                   if (i3 == i1 || i3 == i2)
                      continue;
                   for (int i4 = 0; i4 < 4; i4++) {
                      if (i1 == i4 || i2 == i4 || i3 == i4)
                         continue;
                      iSeqs[iRows][0] = iNum[i1];
                      iSeqs[iRows][1] = iNum[i2];
                      iSeqs[iRows][2] = iNum[i3];
                      iSeqs[iRows][3] = iNum[i4];
                      iRows ++;
                   }
                }
             }
       }
    }

    public List<String> getResult() {
       return lst;
    }

    private float calcEntry(float a, float b, int opr) {
       switch (opr) {
       case 0: // +
          return a + b;
       case 1: // -
          return a - b;
       case 2: // *
          return a * b;
       case 3: // /
          if (b == 0)
             return -9999;
          return a / b;
       }
       return -9999; // should not be here
    }

    private float calc() {
       // normalize
       // 1. a+b or a*b:only keep a<=b
       // 2. a+(b?c) or a*(b?c): drop
       float r1, r2, r3 = 0;
       switch (iPriority) {
       case 0: // ((a?b)?c)?d
          if(iOpr[0]%2==0 && iSeq[0]>iSeq[1])       // + or *
             break;
          r1 = calcEntry(iSeq[0], iSeq[1], iOpr[0]);
          r2 = calcEntry(r1, iSeq[2], iOpr[1]);
          r3 = calcEntry(r2, iSeq[3], iOpr[2]);
          break;
       case 1: // (a?b)?(c?d)
          if(iOpr[0]%2==0 && iSeq[0]>iSeq[1])
             break;
          if(iOpr[2]%2==0 && iSeq[2]>iSeq[3])
             break;
          r1 = calcEntry(iSeq[0], iSeq[1], iOpr[0]);
          r2 = calcEntry(iSeq[2], iSeq[3], iOpr[2]);
          r3 = calcEntry(r1, r2, iOpr[1]);
          break;
       case 2: // (a?(b?c))?d
          if(iOpr[0]%2==0)
             break;
          if(iOpr[1]%2==0 && iSeq[1]>iSeq[2])
             break;
          r1 = calcEntry(iSeq[1], iSeq[2], iOpr[1]);
          r2 = calcEntry(iSeq[0], r1, iOpr[0]);
          r3 = calcEntry(r2, iSeq[3], iOpr[2]);
          break;
       case 3: // a?((b?c)?d)
          if(iOpr[0]%2==0)
             break;
          if(iOpr[1]%2==0 && iSeq[1]>iSeq[2])
             break;
          r1 = calcEntry(iSeq[1], iSeq[2], iOpr[1]);
          r2 = calcEntry(r1, iSeq[3], iOpr[2]);
          r3 = calcEntry(iSeq[0], r2, iOpr[0]);
          break;
       case 4: // a?(b?(c?d))
          if(iOpr[0]%2==0 || iOpr[1]%2==0)
             break;
          if(iOpr[2]%2==0 && iSeq[2]>iSeq[3])
             break;
          r1 = calcEntry(iSeq[2], iSeq[3], iOpr[2]);
          r2 = calcEntry(iSeq[1], r1, iOpr[1]);
          r3 = calcEntry(iSeq[0], r2, iOpr[0]);
          break;
       }
       return r3;
    }

    private void addList() {
       // todo: consider priority
       String str = new String();
       switch (iPriority) {
       case 0: // ((a?b)?c)?d
//        str = "((" + iSeq[0] + opr[iOpr[0]] + iSeq[1] + ")" + opr[iOpr[1]]
//              + iSeq[2] + ")" + opr[iOpr[2]] + iSeq[3];
          str = "" + iSeq[0] + opr[iOpr[0]] + iSeq[1];
          if(iOpr[0]/2 < iOpr[1]/2 )
             str = "(" + str + ")" + opr[iOpr[1]] + iSeq[2];
          else
             str = str + opr[iOpr[1]] + iSeq[2];
          if(iOpr[1]/2 < iOpr[2]/2 )
             str = "(" + str + ")" + opr[iOpr[2]] + iSeq[3];
          else
             str = str + opr[iOpr[2]] + iSeq[3];
          break;
       case 1: // (a?b)?(c?d)
//        str = "(" + iSeq[0] + opr[iOpr[0]] + iSeq[1] + ")" + opr[iOpr[1]]
//              + "(" + iSeq[2] + opr[iOpr[2]] + iSeq[3] + ")";
          str = "" + iSeq[0] + opr[iOpr[0]] + iSeq[1];
          if(iOpr[0]/2 < iOpr[1]/2 )
             str = "(" + str + ")" + opr[iOpr[1]];
          else
             str = str + opr[iOpr[1]];
          if(iOpr[1]/2 < iOpr[2]/2 )
             str = str + iSeq[2] + opr[iOpr[2]] + iSeq[3];
          else if(iOpr[1]/2 == iOpr[2]/2 && iOpr[1] %2 == 0)
             str = str + iSeq[2] + opr[iOpr[2]] + iSeq[3];
          else
             str = str + "(" + iSeq[2] + opr[iOpr[2]] + iSeq[3] +")";
          break;
       case 2: // (a?(b?c))?d
//        str = "(" + iSeq[0] + opr[iOpr[0]] + "(" + iSeq[1] + opr[iOpr[1]]
//              + iSeq[2] + "))" + opr[iOpr[2]] + iSeq[3];
          str = "" + iSeq[1] + opr[iOpr[1]] + iSeq[2];
          if(iOpr[0]/2 < iOpr[1]/2 )
             str = "" + iSeq[0] + opr[iOpr[0]] + str;
          else if(iOpr[0]/2 == iOpr[1]/2 && iOpr[0] %2 == 0)
             str = "" + iSeq[0] + opr[iOpr[0]] + str;
          else
             str = "" + iSeq[0] + opr[iOpr[0]] + "(" + str + ")";
          if(iOpr[0]/2 < iOpr[2]/2 )
             str = "(" + str + ")" + opr[iOpr[2]] + iSeq[3];
          else
             str = str + opr[iOpr[2]] + iSeq[3];
          break;
       case 3: // a?((b?c)?d)
//        str = "" + iSeq[0] + opr[iOpr[0]] + "((" + iSeq[1] + opr[iOpr[1]]
//              + iSeq[2] + ")" + opr[iOpr[2]] + iSeq[3] + ")";
          str = "" + iSeq[1] + opr[iOpr[1]] + iSeq[2];
          if(iOpr[1]/2 < iOpr[2]/2 )
             str = "(" + str + ")" + opr[iOpr[2]] + iSeq[3];
          else
             str = str + opr[iOpr[2]] + iSeq[3];
          if(iOpr[0]/2 < iOpr[2]/2 )
             str = "" + iSeq[0] + opr[iOpr[0]] + str;
          else if(iOpr[0]/2 == iOpr[2]/2 && iOpr[0] %2 == 0)
             str = "" + iSeq[0] + opr[iOpr[0]] + str;
          else
             str = "" + iSeq[0] + opr[iOpr[0]] + "(" + str + ")";
          break;
       case 4: // a?(b?(c?d))
//        str = "" + iSeq[0] + opr[iOpr[0]] + "(" + iSeq[1] + opr[iOpr[1]]
//              + "(" + iSeq[2] + opr[iOpr[2]] + iSeq[3] + "))";
          str = "" + iSeq[2] + opr[iOpr[2]] + iSeq[3];
          if(iOpr[1]/2 < iOpr[2]/2 )
             str = "" + iSeq[1] + opr[iOpr[1]] + str;
          else if(iOpr[1]/2 == iOpr[1]/2 && iOpr[1] %2 == 0)
             str = "" + iSeq[1] + opr[iOpr[1]] + str;
          else
             str = "" + iSeq[1] + opr[iOpr[1]] + "(" + str + ")";
          if(iOpr[0]/2 < iOpr[1]/2 )
             str = "" + iSeq[0] + opr[iOpr[0]] + str;
          else if(iOpr[0]/2 == iOpr[1]/2 && iOpr[0] %2 == 0)
             str = "" + iSeq[0] + opr[iOpr[0]] + str;
          else
             str = "" + iSeq[0] + opr[iOpr[0]] + "(" + str + ")";
          break;
       }
       // check if there is already same entry in the list
       if (lst != null) {
          for (int i = 0; i < lst.size(); i++) {
             if (lst.get(i).equals(str))
                return;
          }
          lst.add(str);
       }
    }

    public boolean findAnswer() {
       boolean flag = false;
       int i1, i2;

       for (iPriority = 0; iPriority < 5; iPriority++) {
          // iPriority define priority as follow:
          // 0: ((a?b)?c)?d
          // 1: (a?b)?(c?d)
          // 2: (a?(b?c))?d
          // 3: a?((b?c)?d)
          // 4: a?(b?(c?d))
          for (i1 = 0; i1 < iComps; i1++)
             for (i2 = 0; i2 < 64; i2++) {
                iSeq[0] = iSeqs[i1][0];
                iSeq[1] = iSeqs[i1][1];
                iSeq[2] = iSeqs[i1][2];
                iSeq[3] = iSeqs[i1][3];
                iOpr[0] = iOprs[i2][0];
                iOpr[1] = iOprs[i2][1];
                iOpr[2] = iOprs[i2][2];
                if (Math.abs(calc() - 24.0) < 0.0001) {
                   // equal, set flag and add an entry in list
                   addList();
                   flag = true;
                }
             }
       }
       return flag;
    }
}

测试代码(利用junit实现单元测试本课程重点)

先把程序运行起来再测试!

首先要先写pom文件引入junit依赖,如果不写pom就要导入junit的jar包(麻烦)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.itcast</groupId>
    <artifactId>junitrc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <properties>
        <maven.compiler.source>22</maven.compiler.source>
        <maven.compiler.target>22</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>
  • assertTrue 是 TestCase 类提供的一个断言方法,用于验证一个布尔表达式是否为 true
  • assertEquals 是 TestCase 类提供的另一个断言方法,用于验证两个对象是否相等。
package test;

import junit.framework.TestCase;

import java.util.List;

public class Test24 extends TestCase{

    public void testAll() {
       Calc24New c24 = new Calc24New(3, 3, 8, 8);
       assertTrue("find answer",c24.findAnswer());//"findanser"是作为有错误时的提示信息显示
        
       List<String> answers = c24.getResult();
       assertEquals("correct answer", "8/(3-8/3)" ,answers.get(0));//"correct answer"提示信息
    }

}

 (1) assertTrue("find answer",c24.findAnswer());用于检查是否能找到答案

如果能找到答案则会显示测试通过(绿色)

如果找不到答案-->例如创建测试对象时第一个值用90就是:

Calc24New c24 = new Calc24New(90, 3, 8, 8);

 (2)   List<String> answers = c24.getResult();

这行代码作用是将找到的结果都放入列表里

(3)   assertEquals("correct answer", "8/(3-8/3)" ,answers.get(0));

这行代码作用是对比预期表达式8/(3-8/3)和第一个满足条件的表达式是否一样

如果一样就通过测试(绿色)

如果不相等会显示预期值8/(3-8/3),实际值:满足条件的第一个表达式

例如:改变测试对象Calc24New c24 = new Calc24New(2, 3, 8, 8);

 

posted @ 2025-04-06 09:10  Annaprincess  阅读(16)  评论(0)    收藏  举报