4
\$\begingroup\$

I think my code works pretty well, although I'm biased: http://jsfiddle.net/AHKb4/2/

Basic Overview: I'm working on building a math skill game, where the objective is to drag and drop div's to a container. Each div will have a value, likely set with classes. Each container must equal theSumNum to pass the level. Just giving this info so you can possibly understand better what I'm trying to achieve.

  1. Most importantly I think I've got my main function pickNumbers() ready to go. But I'd really appreciate any opinions and advice that you have for that function.

  2. I've made two classes so far, three and five. I'm planning though to have classes from two through ten. I'm thinking each class will have an amount of arrays equal to that class number. Likewise there will be x number of container divs for x number of arrays.

    So I think I could obviously improve how I do my classes by creating a for loop to generate the classes when needed, and use like myArray1 instead of myArrayOne. I'm just looking for a True or False answer for this question.

  3. Lastly, please take a look at the function pickFive(). So again I'm assuming I could just use a for loop for that as well? Just looking for a True or False here too, but if there's anything to look out for or be careful of in doing it that way, please let me know.

$(document).ready(function() {
var three = {
    myArrayOne: [],
    myArrayTwo: [],
    myArrayThree: [],
    myArraysCombined: []
}
var five = {
    myArrayOne: [],
    myArrayTwo: [],
    myArrayThree: [],
    myArrayFour: [],
    myArrayFive: [],
    myArraysCombined: []
}
// theArray is the array to push to  ~ ex(three.myArrayTwo)
// theNum is the amount of numbers that will be in the array  ~ ex(3)
// theSumNum is what the sum of all the numbers in the array will equal  ~ ex(20)
// theMaxNum is the largest number that can appear in the array, except the last number may be larger since its not random  ~ ex(10)
// theMinNum is the smallest number that can appear in the array  ~ ex(1)
// aRandNum is a temporary var for each number in the array, except for the last number in the array
// thePreSumNum is the sum of all the numbers in the array except for the last number
// theLastNum is the last number that will be pushed to the array, this number is not random
function pickNumbers(theArray, theNum, theSumNum, theMaxNum, theMinNum) {
    for (var x=0; x < theNum;) {
        var aRandNum = Math.floor(Math.random()*theMaxNum + theMinNum);
        if (theArray.indexOf(aRandNum) === -1) {
            if (theArray.length < (theNum - 1)) {
                theArray.push(aRandNum);
                x += 1;
            }
            if (theArray.length === (theNum -1)) {
                var thePreSumNum = 0;
                for (var e = 0; e < theArray.length; e += 1) { thePreSumNum += theArray[e]; }
                var theLastNum = theSumNum - thePreSumNum;
                    if (theArray.indexOf(theLastNum) > -1 || theLastNum < 1) {
                        theArray.length = 0;
                        x = theNum;
                        pickNumbers(theArray, theNum, theSumNum, theMaxNum, theMinNum);
                    }
                    else {
                        theArray.push(theLastNum);
                        x += 1;
                    }
            }
        }
    }
}

function pickThree() {
    pickNumbers(three.myArrayOne, 3, 20, 10, 1);
    pickNumbers(three.myArrayTwo, 3, 20, 10, 1);
    pickNumbers(three.myArrayThree, 3, 20, 10, 1);
    three.myArraysCombined = three.myArrayOne.concat(three.myArrayTwo, three.myArrayThree);
}

function pickFive() {
    pickNumbers(five.myArrayOne, 5, 40, 20, 1);
    pickNumbers(five.myArrayTwo, 5, 40, 20, 1);
    pickNumbers(five.myArrayThree, 5, 40, 20, 1);
    pickNumbers(five.myArrayFour, 5, 40, 20, 1);
    pickNumbers(five.myArrayFive, 5, 40, 20, 1);
    five.myArraysCombined = five.myArrayOne.concat(five.myArrayTwo, five.myArrayThree, five.myArrayFour, five.myArrayFive);
}

pickThree();
pickFive();
    
});
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Assumptions I made:

  • The 3 object will have 3 arrays, just as the 67 object will have 67 arrays
  • The "combined" array can be computed on demand
  • Each call to pickNumbers for a certain object will always have the same parameters

Firstly for your objects, I think they belong in a namespace and also a way to define which numbers you want to be in the game:

var Game = {}
Game.NUMBERS = [3, 5];

Next instantiate all the classes:

for (var i = Game.NUMBERS.length; i --) {
  Game[Game.NUMBERS[i]] = new GameNumber(Game.NUMBERS[i]);
}

Let's define what your class would look like:

var GameNumber = function(number) {
  this.number = number;
  this.arrays = [];
  for (var i = number; i --) {
    this.arrays.push([])
  }
}
GameNumber.prototype.combined = function() {
  Array.prototype.concat.apply([], this.arrays)
}
GameNumber.prototype.pick = function(arrayLength, sum, max, min) {
  for (var i = this.number; i --) {
    pickNumbers(this.arrays[i], arrayLength, sum, max, min);
  }
}

Cool, so now you can create your objects in a sufficiently general way and call pick or combined on any of them.

Game[3].pick(5, 40, 20, 1);
Game[3].combined() // Output: [...]

As for the pickNumbers function, I didn't look at the logic too heavily, I'm sure that's working how you want it to. The variable names I would simplify to array, arrayLength, sum, max, min for readability. You may also want to attach it to the Game object so you have less globals (ie Game.pickNumbers = function(...)). I'd also try and abstract the html from it so as to separate logic from presentation.

Note: I haven't tested this code, it's only to give you an idea of how to structure it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.