number munchers

Anyone who is familiar with the classic game number munchers:

Depending on the game mode, I'm trying to generate factors or multiples of a target number and push them into a container. From there, I'm randomly placing the contents of the container on the grid and then generating random nonsense numbers around the factors/multiples WITHOUT the random numbers being multiples/factors themselves.

When a player munches on a factor/multiples, it'd deleted from the container; so that when the container is empty, the game is over.

I'm having trouble succinctly and elegantly filling the grid with appropriate numbers based on those restrictions. I'm constantly checking to see if the player is playing "multiples" or "factors" and there is a bit of repeated code..

Its just a DOS version. . .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void NumberMunchers::findMultiples()
{
	container.clear();

	int randomRow;
	int randomColumn;

	for (signed int divisor = targetNumber; divisor <= targetNumber * 5; divisor++)
	{
		randomRow = 0 + rand() % grid.TOTALROWS;
		randomColumn = 0 + rand() % grid.TOTALCOLUMNS;

		if (isMultiple(divisor))
		{
			
			if (!isMultiple(grid.at(randomRow, randomColumn)))
			{
				container.push_back(divisor);
				grid.set(randomRow, randomColumn, divisor);
			}
				
			else
				divisor--;
		}
	}
}



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void NumberMunchers::fillGrid()
{
	int randomColumn, randomRow, randomNumber;

	for (int row = 0; row < grid.TOTALROWS; row++)
	{
		for (int col = 0; col < grid.TOTALCOLUMNS; col++)
		{
			randomNumber = 1 + rand() % 100;

			if (isMultiple(randomNumber) || isFactor(randomNumber))
			{
				continue;
				col--;
			}
				

			grid.set(row, col, randomNumber);
		}
	}
}
Last edited on
Its ugly, but I think I got it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

void NumberMunchers::fillGrid()
{
	int randomRow;
	int randomColumn;
	int randomNumber;

	for (int element = 0; element < container.size(); element++)
	{
		randomRow = rand() % grid.TOTALROWS;
		randomColumn = rand() % grid.TOTALCOLUMNS;

		if (grid.at(randomRow, randomColumn) == -1)
		{
			grid.set(randomRow, randomColumn, container.at(element));
		}
		else
			element--;
			
	}

	for (int row = 0; row < grid.TOTALROWS; row++)
	{
		for (int col = 0; col < grid.TOTALCOLUMNS; col++)
		{
			randomNumber = rand() % 100;

			if (grid.at(row, col) == -1)
			{
				if (isMultiple(randomNumber) && menuGameMode == 1)
				{
					container.push_back(randomNumber);
				}
				if (isFactor(randomNumber) && menuGameMode == 2)
				{
					container.push_back(randomNumber);	
				}

				grid.set(row, col, randomNumber);
			}
		}
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <iostream>
#include <iomanip>
#include <vector>
#include <random>
#include <functional>


using row_type = std::vector<unsigned>;
using grid_type = std::vector<row_type>;

std::function<unsigned()> get_rng(unsigned min, unsigned max)
{
    std::mt19937 generator((std::random_device())());
    return [=]() mutable
    {
        return std::uniform_int_distribution<unsigned>(min, max)(generator);
    };
}


// note that max_value is treated as a bit of a suggestion.
// modify rnd_non_multiple if that isn't satisfactory.
grid_type generate_grid(unsigned target, unsigned n_target_values,
    unsigned width, unsigned height, unsigned max_value)
{
    grid_type grid(height, row_type(width));

    // convenience functions
    auto rnd_width = get_rng(0, width - 1);
    auto rnd_height = get_rng(0, height - 1);

    auto factor = get_rng(1, max_value / target);
    auto rnd_multiple = [target, &factor] { return factor() * target; };

    auto lt_target = get_rng(1, target - 1);    // less than target
    auto rnd_non_multiple = [&rnd_multiple, &lt_target]
    { return rnd_multiple() + lt_target(); };

    {
        // place multiples randomly
        unsigned targets_assigned = 0;
        while (targets_assigned < n_target_values)
        {
            unsigned y = rnd_height();
            unsigned x = rnd_width();

            if (!grid[y][x])
            {
                grid[y][x] = rnd_multiple();
                ++targets_assigned;
            }
        }
    }

    // fill the rest of the grid with non-multiples
    for (auto& row : grid)
        for (auto & cell : row)
            if (!cell) cell = rnd_non_multiple();

    return grid;
}

void display(const grid_type& grid)
{
    for (auto& row : grid)
    {
        for (auto& cell : row)
            std::cout << std::setw(3) << cell;

        std::cout << '\n';
    }
}

void display(const std::vector<unsigned>& v)
{
    for (auto& e : v)
        std::cout << e << ' ';
    std::cout << '\n';
}

std::vector<unsigned> extract_multiples(const grid_type& grid, unsigned val)
{
    std::vector<unsigned> mults;

    for (auto& row : grid)
        for (auto& cell : row)
            if (cell % val == 0) mults.push_back(cell);

    return mults;
}

int main()
{
    unsigned target = 7;
    auto grid = generate_grid(target, 10, 5, 5, target * 9);
    display(grid);
    std::cout << "\nMultiples are:\n\t";
    display(extract_multiples(grid, target));
}


http://ideone.com/aL1Ib4
Topic archived. No new replies allowed.