案例一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>
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);


浙公网安备 33010602011771号