一道保龄球积分算法(JavaScript版本)

973 阅读2分钟

稍微提一下题目

ps:嗯,没错,就是网上到处传的那个保龄球10瓶积分法 !!! 说一下,本题目输入的值为连续输入,所以不要想什么用空格之类特殊字符的分割字符串

按照题目所说,我做了一个npm包。

结构很简单,主要是涉及到了输入的分数字符串的格式化。
具体的话,看代码。
   /* 游戏规则
 *   1.一共10回合,每回合两次机会
 *   2.在一轮中,如果没有击倒所有保龄球,本轮他的分数为两次击倒的保龄球之和
 *   3.在一轮中,如果第一次就击倒所有保龄球,此次被称为‘spare’,本轮结束,他本轮分数为10分加上接下来两次击球之和
 *  4.在一轮中,第二次击球击倒第一次未击倒的球,则他的分数为10分加上下次击倒的数量
 *   5.最后一轮中,一次击倒所有的球,则增加两次击球机会,最后一轮的总分为10分加上额外两次击球,击倒数的总和。使用两次机会则仅增加一次机会。此种条件不会重复触发
 */
    class Game {
        constructor () {
            this.replaceArr = ['X','/','-']
        }
        //返回总和值
        getScore(inputStr) {
            let val = this.validateStr(inputStr)
            return !val? '输入有误':this.getSequence(inputStr).reduce((total,curr)=>{
                return total+=curr.thisTotalScore
            },0) 
        }

        校验输入的分数是否正确
        validateStr (inputStr) {
            console.log(inputStr)
            return inputStr && inputStr.length && inputStr.length<=21 
        }
        /*         
        *格式化输入的序列
        *@arguments splitArr:分割输入的字符串;
        *@arguments res:返回值
        *@arguments tempIndex:定位下一步应该读取的元素位置
        *@arguments splitArr:分割输入的字符串;
        *@arguments thisTotalScore:单轮成绩
        *@arguments doTimes:轮次 
        */
        getSequence (inputStr) {
           let splitArr = inputStr.split('')
           let res = []
           let tempIndex=0
           let thisTotalScore=0
           let doTimes = 1;
           splitArr.forEach((item,index) => {
               if(tempIndex === index && doTimes<=10) {
                doTimes++
                if(item === 'X') {
                    //获取当前轮次总分 (strike)
                     thisTotalScore = this.getItemToalScore(10,splitArr[index+1],splitArr[index+2])
                     thisTotalScore? res.push({
                        firstScore:10,
                        secondScore:0,
                        thisTotalScore
                    }):res.push({
                        firstScore:10,
                        secondScore:0,
                        thisTotalScore:10
                    })
                    tempIndex++
                } else {
                    /*               
                    *@args nextScore: 是否计入下一次击倒的成绩成绩
                    *desc: / 不可能为第一次的击中数据,所以不做判断
                    */           
                   let secondScore = this.getItemSecondScore(splitArr[index+1],Number(item))    
                    if(item === '-') {
                        let nextScore = secondScore === 10?splitArr[index+2]:0
                        thisTotalScore = this.getItemToalScore(0,splitArr[index+1],nextScore)
                        res.push({
                            firstScore:0,
                            secondScore,
                            thisTotalScore
                        })
                        tempIndex += 2
                    } else {
                        /*               
                        *@args tempThisval:一轮中 两次之和
                        *desc:击倒全部瓶子,会增加一次机会 (spare)
                        */   
                        let tempThisval = Number(item)+secondScore
                        if(tempThisval === 10) {
                            thisTotalScore = this.getItemToalScore(10,splitArr[index+2])
                            thisTotalScore =thisTotalScore?thisTotalScore:tempThisval;
                            res.push({
                                firstScore:Number(item),
                                secondScore,
                                thisTotalScore
                            })
                        } else {
                            res.push({
                                firstScore:Number(item),
                                secondScore,
                                thisTotalScore:tempThisval
                            })
                        }
                        tempIndex += 2
                    }
                }
               }
           });
            console.log(res)
          return res
        }
        getItemSecondScore (curr,item) {
         if(curr === '/') {
             return 10-item
         } else if(curr === '-') {
             return 0
         } else {
             return Number(curr)
         }
        }
        getItemToalScore(...args) {
            return [...args].reduce((total,curr,index,arr)=> {
                let tempVal;
                if(this.replaceArr.includes(curr)) {
                    switch(curr) {
                        case 'X':
                            tempVal = 10;
                            break;
                            case '/':
                            tempVal = 10-arr[index-1];
                            break;
                            case '-':
                                tempVal = 0;
                                break;
                    }
                } else {
                    tempVal = Number(curr)
                }
                return total += tempVal
            },0)
            }
    }
    class TimesGame extends Game {
        constructor() {
            super()
        }
        /*         
         *多人次,每人成绩分割,输入按 {a:'xxxxxx',b:'xxxxxx'}形式
         */ 
        timesGroupByName (inputStr) {
            let res = []
            for(let i in inputStr) {
                res.push({
                    name:i,
                    score: super.getScore(inputStr[i])
                })
            }
            return res
        }
                /*         
         *多局数比分总和,每局成绩以逗号分隔
         */        
        timesScore (inputStr){
            console.log(inputStr.split(','))
            return inputStr.split(',').reduce((total,curr)=>{
                return total +=  super.getScore(curr)
            },0)
        }
    } ```

## 具体流程我都写在上面了,有兴趣的朋友可以下载下来玩哈~
## 有bug,不要骂我!
## 可以讨论,或者告诉我问题在哪,共同讨论解决方式

`ps:npm i npm i blganme`
 
 - let Game =require('blganme')
 - let test = new Game()
 - console.log(test.getScore(STR))