(JS) 重构帮助 - Farkle 评分 JavaScript

(JS) Refactoring Help - Farkle Scoring with JavaScript

我用 React 创建了一个应用程序来玩骰子游戏 Farkle。我通过手动输入每个组合来在 javascript 对象中组织组合及其点值(保存一些我确定我错过了)。我想重构一些更高效的东西,并用我可能错过的组合填补空白。我是编码新手,不知道从哪里开始或如何着手,所以我想我会在这里征求任何建议。

游戏是关于掷 6 个骰子并根据点值选择骰子。这是我的应用使用的评分规则:


得分

1 - 10 分
5 - 5 分
三个 1 - 10 分
三个 2 - 20 分
三个 3 - 30 分
三个 4 - 40 分
三个 5 - 50 分
三个 6 - 60 分
1-2-3-4-5-6 - 300 分
3对150分(含4对1)

请注意,得分组合仅在单次投掷时有效。
(示例:如果玩家掷出一个 1 并将其放在一边,然后在下一次掷出两个 1 时,他们只能得到 30 分,而不是 100 分。)

有时一次掷骰会提供多种计分方式。
例如,掷出 1-2-4-5-5-5 的玩家可能会得到以下其中一项:

10 分
1 和 5 得 15 分
三个 5 得 50 分
1和三个5的60分


这是我的 js 对象在我的应用程序中的样子:

#combinations.js
const combinations = {
      '1':10,
      '5':5,
      '1, 1':20,
      '5, 5':10,
    //triplets
      '1, 1, 1':10,
      '2, 2, 2':20,
      '3, 3, 3':30,
      '4, 4, 4':40,
      '5, 5, 5':50,
      '6, 6, 6':60,
    //triplets + one offs
      '1, 2, 2, 2':30,
      '1, 3, 3, 3':40,
      '1, 4, 4, 4':50,
//.. so on and so forth
}
export default combinations

任何关于如何更有效地管理这些组合的正确方向的推动都将不胜感激。

我搜索了 GitHub JS farkle 应用程序并发现了这个解决方案:

// check array for all score combinations
function combinations(array) {
    // this array stores unused dice
    var unused = [];
    
    // make a copy of array, to avoid changing it (theseKeepers and thisRoll are global variables)
    for (var i = 0; i < array.length; i++) {
        unused.push(array[i]);
    }
    
    // store number of dice in array
    var l = unused.length;
    
    // stores score to return (in case of multiple combinations)
    var score = 0;
    
    // if there are 6..
    if (l == 6) {
        // check for six of a kind
        for (var x = 1; x <= 6; x++) {
            var contains = containsAll([x,x,x,x,x,x], unused);

            // retrieve result from structured array
            if (contains.result == true) {
                // return score and empty array
                return {score: 600,
                        extra: []
                };
            }           
        }
        
        // check for a straight
        var contains = containsAll([1,2,3,4,5,6], unused);

        // retrieve result from structured array
        if (contains.result == true) {
            // return score and empty array
            return {score: 150,
                    extra: []
            };
        }
        
        // check for 2 three of a kinds
        for (var x = 1; x <= 6; x++) {
            for (var y = 1; y <= 6; y++) {
                var contains = containsAll([x,x,x,y,y,y], unused);
                
                // retrieve result from structured array
                if (contains.result == true) {
                    // return score and empty array
                    return {score: 200,
                            extra: []
                    };
                }
            }
        }
        
        // check for a full house
        for (var x = 1; x <= 6; x++) {
            for (var y = 1; y <= 6; y++) {
                var contains = containsAll([x,x,y,y,y,y], unused);
                
                // retrieve result from structured array
                if (contains.result == true) {
                    // return score and empty array
                    return {score: 250,
                            extra: []
                    };
                }
            }
        }
        
        // check for three pairs
        for (var x = 1; x <= 6; x++) {
            for (var y = 1; y <= 6; y++) {
                for (var z = 1; z <= 6; z++) {
                    var contains = containsAll([x,x,y,y,z,z], unused);
        
                    // retrieve result from structured array
                    if (contains.result == true) {
                        // return score and empty array
                        return {score: 150,
                                extra: []
                        };
                    }
                }
            }
        }
    }
    
    // if there are five or more..
    if (l >= 5) {
        // check for five of a kind
        for (var x = 1; x <= 6; x++) {
            var contains = containsAll([x,x,x,x,x], unused);
        
            // retrieve result from structured array
            if (contains.result == true) {
                score += 300;
            
                // retrieve unused array from structured array
                unused = contains.array;
    
                // reset length
                l = unused.length;
            }
        }
    }
    
    // if there are four or more..
    if (l >= 4) {
        // check for four of a kind
        for (var x = 1; x <= 6; x++) {
            var contains = containsAll([x,x,x,x], unused);
        
            // retrieve result from structured array
            if (contains.result == true) {
                score += 200;
            
                // retrieve unused array from structured array
                unused = contains.array;
    
                // reset length
                l = unused.length;
            }
        }
    }
    
    //  if there are three or more..
    if (l >= 3) {
        // check for three of a kind
        for (var x = 1; x <= 6; x++) {
            var contains = containsAll([x,x,x], unused);
        
            // retrieve result from structured array
            if (contains.result == true) {
                // if they are 2s, 3s, 4s, 5s, or 6s..
                if (x > 1) {
                    // multiply by 100
                    score += x * 10;
                } else { // otherwise..
                    // they are 1s
                    score += 100;
                }
            
                // retrieve unused array from structured array
                unused = contains.array;

                // reset length
                l = unused.length;
            }
        }
    }
    
    // if there are two or more..
    if (l >= 2) {
        // check for two ones
        var contains = containsAll([1,1], unused);
        
        // retrieve result from structured array
        if (contains.result == true) {
            score += 20;
            
            // retrieve unused array from structured array
            unused = contains.array;
    
            // reset length
            l = unused.length;
        }
    }
    
    // if there are still two or more..
    if (l >= 2) {
        // check for two fives
        var contains = containsAll([5,5], unused);
        
        // retrieve result from structured array
        if (contains.result == true) {
            score += 10;
            
            // retrieve unused array from structured array
            unused = contains.array;
    
            // reset length
            l = unused.length;
        }
    }
    
    // if there is one or more..
    if (l >= 1) {
        // check for a one
        var contains = containsAll([1], unused);
        
        // retrieve result from structured array
        if (contains.result == true) {
            score += 10;
            
            // retrieve unused array from structured array
            unused = contains.array;
    
            // reset length
            l = unused.length;
        }
    }
    
    // if there is still one or more..
    if (l >= 1) {
        // check for a five
        var contains = containsAll([5], unused);
        
        // retrieve result from structured array
        if (contains.result == true) {
            score += 5;
            
            // retrieve unused array from structured array
            unused = contains.array;
    
            // reset length
            l = unused.length;
        }
    }
    
    // return additive score and array with unused dice
    return {score: score,
            extra: unused
    };
}

// takes in score combination and unused array; determines whether combination exists in unused array
function containsAll(combination, unused) {
    // l is defined up front for speed
    var l = combination.length;
    
    // stores unused dice
    var un = [];
    
    // make a copy of unused array, to avoid changing it
    for (var i = 0; i < unused.length; i++) {
        un.push(unused[i]);
    }
    
    // this array stores used dice
    var used = [];
    
    for (var i = 0; i < l; i++)  {
        // store index of combination die in unused array
        var c = un.indexOf(combination[i]);
        
        // if unused doesn't contain this combination die..
        if (c == -1) {
            return false;
        } else { // otherwise..
            // add die to used array
            used.push(un[c]);
            
            // remove die from unused (since most combinations contain multiples)
            un.splice(c,1);
        }
    }
    
    // take out scored dice
    unused = difference(unused, used);
    
    // score combination exists in array; return true and unused array
    return {
        result: true,
        array: unused
    };
}
// takes in unused and used arrays; returns difference
function difference(unused, used) {
    // this array stores unused dice
    var un = [];
    
    // make a copy of unused array, to avoid changing it
    for (var i = 0; i < unused.length; i++) {
        un.push(unused[i]);
    }
    
    // this array stores used dice
    var u = [];
    
    // make a copy of used array, to avoid changing it
    for (var i = 0; i < used.length; i++) {
        u.push(used[i]);
    }
    
    for (i = 0; i < u.length; i++) {
        // store first index of used number in unused
        var j = un.indexOf(u[i]);
        
        // if used number is found (indexOf() returns -1 if no match is found)..
        if (j > -1) {
            // remove it from unused
            un.splice(j, 1);
        }
    }
    
    // return unused (which now only has values that aren't in used array)
    return un;
}

向 GitHub 用户 @danielbmckay

大喊大叫