1

I'm trying to make a html Sudoku gameboard that loads a different puzzle depending on the php $_GET['level'] and $_GET['puzzle'] values. Php variables $get_level and $get_puzzle are set to the $_GET values so they can be used in the javascript.

<?php
$default_level = 'medium';
$default_puzzle = 1;
$number_of_puzzles_per_level = 10;
if (isset($_GET['level']) && isset($_GET['puzzle'])) {
    if ($_GET['level'] == 'easy' || $_GET['level'] == 'medium' || $_GET['level'] == 'hard') {
        $get_level = $_GET['level'];
    } else {
        $get_level = $default_level;
    }
    if (is_int($_GET['puzzle'])) {
        if ($_GET['puzzle'] > 0 && $_GET['puzzle'] <= $number_of_puzzles_per_level) {
            $get_puzzle = $_GET['puzzle'];
        } else {
            $get_puzzle = $default_puzzle;
        }
    } else {
        $get_puzzle = $default_puzzle;
    }
} else {
    $get_level = $default_level;
    $get_puzzle = $default_puzzle;
}
?>

In the javascript, I have a bunch of arrays:

level_easy_puzzle_1 = [[0, 0, 0, 7, 0, 3, 0, 0, 0], [0, 2, 3, 5, 0, 0, 0, 0, 3], [0, 0, 0, 0, 4, 0, 0, 0, 9], [1, 0, 7, 0, 0, 0, 0, 4, 0], [0, 4, 0, 3, 0, 9, 0, 8, 0], [0, 8, 0, 0, 0, 0, 5, 0, 1], [7, 0, 0, 0, 6, 0, 0, 0, 0], [8, 0, 0, 0, 0, 1, 2, 5, 0], [0, 0, 0, 2, 0, 4, 0, 0, 0]];
//I will fill out the rest of the puzzles later
level_easy_puzzle_2 = [[], [], [], [], [], [], [], [], []];
level_easy_puzzle_3 = [[], [], [], [], [], [], [], [], []];
level_easy_puzzle_4 = [[], [], [], [], [], [], [], [], []];
level_easy_puzzle_5 = [[], [], [], [], [], [], [], [], []];
level_easy_puzzle_6 = [[], [], [], [], [], [], [], [], []];
level_easy_puzzle_7 = [[], [], [], [], [], [], [], [], []];
level_easy_puzzle_8 = [[], [], [], [], [], [], [], [], []];
level_easy_puzzle_9 = [[], [], [], [], [], [], [], [], []];
level_easy_puzzle_10 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_1 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_2 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_3 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_4 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_5 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_6 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_7 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_8 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_9 = [[], [], [], [], [], [], [], [], []];
level_medium_puzzle_10 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_1 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_2 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_3 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_4 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_5 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_6 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_7 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_8 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_9 = [[], [], [], [], [], [], [], [], []];
level_hard_puzzle_10 = [[], [], [], [], [], [], [], [], []];

Then, I want the javascript variable puzzle to be set to one of the puzzle arrays above depending on the values of the below variables get_level and get_puzzle.

var get_level = '<?php echo $get_level; ?>';
var get_puzzle = <?php echo $get_puzzle; ?>;

So, if get_level equals 'hard' and get_puzzle equals 3, I want a variable puzzle to equal the contents of the array level_hard_puzzle_3.

//Here's what I have right now, but it only gives me the name of the array not the contents
var puzzle = 'level_'+get_level+'_puzzle_'+get_puzzle;

Hope it is clear what I want, and thanks for any help.

BestAnswer
  • 136
  • 1
  • 18
  • To use dynamic variable names you must use either *eval* or the *Function* constructor, neither are particularly liked. The usual best solution is to use object properties and square bracket notation for access, such as: `var puzzle = {}; puzzel['level_'+get_level+'_puzzle_'+get_puzzle] = somevalule;`. – RobG Jun 24 '14 at 03:37

2 Answers2

2

You can use the eval Javascript function.

var puzzle = eval('level_' + get_level + '_puzzle_' + get_puzzle);

This will give you your puzzle.

Brendan
  • 2,777
  • 1
  • 18
  • 33
  • I'll be back to try out your answer – BestAnswer Jun 24 '14 at 03:37
  • Using *eval* is not a particularly good answer, it's the `GOTO` of javascript. If the variables are global, then `windw['level_' + get_level + '_puzzle_' + get_puzzle]` would be preferred, or better would be object properties. – RobG Jun 24 '14 at 03:43
  • 1
    @RobG I personally don't want to advocate for `eval`, however from the way the OP asked his question it seemed to be the only answer. I personally like Chad's answer (above) better, however (strictly speaking) it does modify the question to the answer. In addition, global variables are typically discouraged, and using object properties would probably force you to modify the question. – Brendan Jun 24 '14 at 03:56
  • @boboman13: Doesn't OP mean organic programming? I looked it up and I don't understand what it means – BestAnswer Jun 24 '14 at 04:19
  • @boboman13: eval() worked, but I'm going to try to do Chad's answer because it seems cleaner. – BestAnswer Jun 24 '14 at 04:40
  • 1
    @codeshackel OP means original poster. Good choice, I like Chad's answer better anyways. – Brendan Jun 24 '14 at 05:05
2

You could organize this into an object instead. Also, let array indexing take care of your numbering rather than assigning numbers to variable names. (If you decide to remove a puzzle, you'd have to rename all of them.)

var puzzles = {
    easy: [
            [//Puzzle 0
              [0, 0, 0, 7, 0, 3, 0, 0, 0],
              [0, 2, 3, 5, 0, 0, 0, 0, 3],
              [0, 0, 0, 0, 4, 0, 0, 0, 9],
              [1, 0, 7, 0, 0, 0, 0, 4, 0],
              [0, 4, 0, 3, 0, 9, 0, 8, 0],
              [0, 8, 0, 0, 0, 0, 5, 0, 1],
              [7, 0, 0, 0, 6, 0, 0, 0, 0],
              [8, 0, 0, 0, 0, 1, 2, 5, 0],
              [0, 0, 0, 2, 0, 4, 0, 0, 0]
            ],
            [//Puzzle 1
              [0, 0, 0, 7, 0, 3, 0, 0, 0],
              [0, 2, 3, 5, 0, 0, 0, 0, 3],
              [0, 0, 0, 0, 4, 0, 0, 0, 9],
              [1, 0, 7, 0, 0, 0, 0, 4, 0],
              [0, 4, 0, 3, 0, 9, 0, 8, 0],
              [0, 8, 0, 0, 0, 0, 5, 0, 1],
              [7, 0, 0, 0, 6, 0, 0, 0, 0],
              [8, 0, 0, 0, 0, 1, 2, 5, 0],
              [0, 0, 0, 2, 0, 4, 0, 0, 0]
            ]
    ], //end of the easy puzzles
    medium: [], //...and so on...
    hard: [],
}

I suggest making a function to retrieve puzzles, so you can control your logic neatly in one place:

function getPuzzle(difficulty, level){
    if(puzzles[difficulty] && puzzles[difficulty].length >= level -1){
        return puzzles[difficulty][level];
    }else{
        console.warn("That puzzle doesn't exist!");
        return;
    }
}

We can now do something like var puzzle = getPuzzle('hard', 2), but let's build on that and make a function that will get a random puzzle.

function getRandomPuzzle(level) {
  return getPuzzle(level, Math.floor(Math.random() * (puzzles[level].length)));
}

var puzzle = getRandomPuzzle('hard');
Chad Hedgcock
  • 11,125
  • 3
  • 36
  • 44