SOURCE

console 命令行工具 X clear

                    
>
console
class operation {
    constructor(level, sign, a, b) {
        this.level = level;
        this.sign = sign;
        this.stra = a.toString();
        this.strb = b.toString();
        if (Number.isInteger(a)){
            this.a = a;
        } else {
            this.a = a.calc();
            if (a.level < level) {
                this.stra = `(&nbsp;${this.stra}&nbsp;)`;
            }
        }
        if (Number.isInteger(b)){
            this.b = b;
        } else {
            this.b = b.calc();
            if (b.level <= level) {
                this.strb = `(&nbsp;${this.strb}&nbsp;)`;
            }
        }
    }
    
    calc() {}

    toString() {
        return `${this.stra}&nbsp;${this.sign}&nbsp;${this.strb}`;
    }
}

class add extends operation {
    constructor(a, b) {
        super(1, '&plus;', a, b);
    }

    calc() {
        if (isNaN(this.a) || isNaN(this.b)){
            return NaN;
        } else {
            return this.a + this.b;
        }
    }
}

class minus extends operation {
    constructor(a, b) {
        super(1, '&minus;', a, b);
    }

    calc() {
        if (isNaN(this.a) || isNaN(this.b)){
            return NaN;
        } else {
            return this.a - this.b;
        }
    }
}

class minus_r extends minus {
    constructor(a, b) {
        super(b, a);
    }
}

class multiply extends operation {
    constructor(a, b) {
        super(2, '&times;', a, b);
    }

    calc() {
        if (isNaN(this.a) || isNaN(this.b)){
            return NaN;
        } else {
            return this.a * this.b;
        }
    }
}

class divide extends operation {
    constructor(a, b) {
        super(2, '&divide;', a, b);
    }

    calc() {
        if (isNaN(this.a) || isNaN(this.b) || this.b === 0){
            return NaN;
        } else {
            return this.a / this.b;
        }
    }
}

class divide_r extends divide {
    constructor(a, b) {
        super(b, a);
    }
}

class Permutation {
    constructor(arr) {
        this.arr = Array.from(arr);
        this.result = [];
        this.len = 0;
        this.run(0);
    }

    run(index) {
        if (index == this.arr.length - 1) {
            this.result.push(Array.from(this.arr));
            this.len++;
            return;
        }
        for(let i = index; i < this.arr.length; i++) {
            [this.arr[index], this.arr[i]] = [this.arr[i], this.arr[index]];
            this.run(index + 1);
            [this.arr[index], this.arr[i]] = [this.arr[i], this.arr[index]];
        }
    }
}

class Product {
    constructor(arr, len) {
        this.arr = arr;
        this.len = len;
        this.result = [];
        this.run();
    }

    run() {
        for (let i = 0; i < Math.pow(this.arr.length, this.len); i++) {
            this.result.push(this.convert(i, this.arr.length, this.len));
        }
    }

    convert(n, base, digits) {
        var result = [];
        for (let i = 0; i < digits; i++) {
            let m = n % base
            n = (n - m) / base;
            result.push(this.arr[m]);
        }
        return result;
    }
}

new Vue({
    el: "#app",
    data: {
        selected: [
            { data: "?" },
            { data: "?" },
            { data: "?" },
            { data: "?" }
        ],
        error: false,
        answers: [],
        showanswers: false,
        target: 24,
    },
    methods: {
        clickBtn(event) {
            for (i = 0; i < this.selected.length; i++) {
                if (this.selected[i].data === '?') {
                    this.selected[i].data = event.target.innerText;
                    break;
                }
            }
            this.error = false
        },
        reset() {
            this.selected = [
                { data: "?" },
                { data: "?" },
                { data: "?" },
                { data: "?" }
            ];
            this.error = false;
            this.showanswers = false;
            this.answers = [];
            this.showanswers = false;
        },
        remove(index) {
            this.selected[index].data = '?';
            this.showanswers = false;
        },
        calc() {
            var numbers = [];
            for (i = 0; i < this.selected.length; i++) {
                if (this.selected[i].data === '?') {
                    this.error = true;
                } else {
                    numbers.push(parseInt(this.selected[i].data));
                }
            }
            if (numbers.length < 4) {
                return;
            }

            this.answers = [];
            this.showanswers = true;
            //定义运算
            var operations = [add, minus, minus_r, multiply, divide, divide_r];
            //全排列选定的数字
            var numbers_permutation = new Permutation(numbers);
            //可重复全排列选定的运算
            var operations_product = new Product(operations, numbers.length - 1);
            for (let i = 0; i < numbers_permutation.result.length; i++) {
                for (let j = 0; j < operations_product.result.length; j++) {
                    var r = numbers_permutation.result[i][0];
                    for (let k = 0; k < numbers.length - 1; k++) {
                        r = new operations_product.result[j][k](r, numbers_permutation.result[i][k + 1]);
                    }
                    if (Math.abs(r.calc() - this.target) < 0.0001) {
                        var find = false;
                        for (let l = 0; l < this.answers.length; l++) {
                            if (r.toString() === this.answers[l]) {
                                find = true;
                                break;
                            }
                        }
                        if (find === false) {
                            this.answers.push(r.toString());
                        }
                    }
                }
            }
        }
    }
});
<!DOCTYPE html>
<html>

<head>
	<meta name="description" content="24-point game">
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width">

	<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
	 crossorigin="anonymous">
	
    <script src="https://unpkg.com/vue"></script>

	<title>24-Point Game</title>

	<style>
		.selected {
			width: 60px;
			height: 60px;
			display: flex;
			align-items: center;
			justify-content: center;
			font-size: 24px;
		}
	</style>
</head>

<body>
	<div id="app" class="container">
		<div class="jumbotron mt-2">
			<h2><span class="badge badge-warning mr-2"><big>24</big></span>点游戏</h2>
            <hr>
            <p class="lead">选择<big class="font-weight-bold mr-2 ml-2">4</big>个数字(可以重复),通过四则运算得到<big class="badge badge-pill badge-success mr-2 ml-2">24</big>,即为胜利。</p>
        </div>
        <div class="row">
            <div class="col">
                <h4>请选数字:</h4>
            </div>
        </div>
        <div class="row">
            <div v-for="bt in 10" class="col-1">
                <button  type="button" class="btn btn-success" @click="clickBtn">{{ bt - 1 }}</button>
            </div>
        </div>
        <hr>
        <div class="row">
            <div class="col">
                <h4>已选数字:</h4>
            </div>
        </div>
        <div v-if="error" class="alert alert-secondary">必须选择<span class="badge badge-warning mr-2 ml-2" style="font-size: 1.2rem">4</span>个数字才能计算!</div>
        <div class="row">
            <div v-for="(s, index) in selected" class="col-2">
                <span class="selected badge" :class="[s.data === '?' ? 'badge-secondary' : 'badge-danger']" @click="remove(index)">{{s.data}}</span>
            </div>
        </div>
        <hr>
        
        <div class="row">
            <div class="col">
                <h4>开始:</h4>
            </div>
        </div>
        <div class="row justify-content-center">
            <div class="col">
                <button type="button" class="btn btn-lg btn-success" @click="calc">计算</button>
                <button type="button" class="btn btn-lg btn-secondary" @click="reset">重选</button>
            </div>
        </div>
        <hr>

        <div class="row">
            <div class="col">
                <table v-if="answers.length > 0" class="table table-striped">
                    <thead class="thead-light">
                        <tr>
                            <th>#</th>
                            <th>答案</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(a, index) in answers">
                            <td>{{ index + 1 }}</td>
                            <td v-html="a"></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div v-if="showanswers === true && answers.length ===0" class="alert alert-secondary">您选的数字无法计算出24。</div>
    </div>
</body>
</html>
.selected {
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
}