0

I'm doing this slot machine game where a 3x3 2D-array is being generated with random letters. I have successfully made the game work as I want but I wonder if you have any tips on how I can optimize or improve my code.

What I've gotten my code to do:

  • Generate an 2D-array (3x3) and randomly assign chars out of 3 letters.
  • An "if" that will compare and see what elements in the array belong to each other (same char next to eachother for getting columns/rows/diagonals).
  • An "if else" that will take total amount of columns/rows/diagonals and make a prize out of it, depending on total amounts of row in the slot machine and the bet.

So I'm now wondering if you have any suggestions on how I can improve the "if" code where the program checks if there are any rows/columns/diagonals? The game works as it should but I just wonder if there's any way of optimizing it - Perhaps with a "for-loop"? I also wonder if you have any tips on the "prize" code where the code calculates total amout of rows/columns/diagonals and multiplies that with the bet.

I mean, there must be a way to optimize this. If I was to do a 100x100 array, the code where the elements are compared would be awfully long :) I'm new to C++ (this is a course) so I'm looking forward to optimize this.

PS! I'm not asking for a solution but rather suggestions/tips of methods I can use to optimize it. This is a homework so no solutions please, only suggestions/tips!

My code for the array comparison and prize calculation:

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
klefar
  • 65
  • 8

5 Answers5

0

Depends on the array size(s) as you mentioned. With small arrays the if statements may be more efficient than using a loop (or two nested) to iterate over all the elements (this is also called 'loop unrolling' and is considered a performance improvement).

To 'optimize' (I'd better say generalize) your code for any array sizes you should use for loops of course to iterate over the x/y indices.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
0

To optimize, running a profiler would give you a lot of information. If you're talking about general guidelines to optimizing your application, here are some:

1 - use threads to process in parallel

2 - reduce cache miss by keeping the data properly aligned depending on the processing done on it. For instance, if you need to use the speed to process the position, keeping them both near each other in memory will reduce cache-misses.

ie:

struct Particle 
{
   float position;
   float speed;
};
Particle particles[NUM_PARTICLES];

vs

float positions[NUM_PARTICLES];
float speeds[NUM_PARTICLES];

3- Don't process what you don't need to process or user can't see. For instance, some stuff may not affect the current states - no need to process it (in graphics, we use scene management like octtrees but the same applies to all - if you don't need it, don't process it).

4- Reduce the amount of floating point operations.

See this post as well - it provices with some good C++ references for optimizations: C++ Optimization Techniques.

Community
  • 1
  • 1
MasterPlanMan
  • 992
  • 7
  • 14
0

Completed code:

//Check all horiztonal and vertical locations
for(int i = 0; i <= 2; i++)
    {
    if(matris[i][0] == matris[i][1] && matris[i][1] == matris[i][2])
        rows++;
    if(matris[0][i] == matris[1][i] && matris[1][i] == matris[2][i])
        rows++;
    }

//Now check diagonals
if(matris[0][0] == matris[1][1] && matris[1][1] == matris[2][2])
if(matris[0][2] == matris[1][1] && matris[1][1] == matris[2][0])

//Calculate prize
prize = g_satsning*(1 << rows);
  • 1
    `2^rows` doesn't do what you think it does (it's bitwise XOR). – Blastfurnace Aug 14 '13 at 18:48
  • 1
    I think you meant `pow(2, rows)`. – Blastfurnace Aug 14 '13 at 18:51
  • @StaticCast Why not simply `g_satsning * (2 << rows)`? And shouldn't that be `pow(2, rows);` 'alrighty then'?? – πάντα ῥεῖ Aug 14 '13 at 18:52
  • @g-makulik: Now you have a little error, shouldn't it be `(1 << rows)`? – Blastfurnace Aug 14 '13 at 18:55
  • @Blastfurnace You're right it should be `g_satsning * (1 << rows)` to match `if (rows == 1 )` and the following correctly. – πάντα ῥεῖ Aug 14 '13 at 19:00
  • Thanks. This works but there's now a problem and it's my fault I guess. What I was asking for was suggestions/tips for other solutions, example (You could use a for-loop to check the elements). The reason I particulary asked not to get any direct solutions was because this is a homework and now I won't be able to use the code x) I guess it's my fault not tagging it as "homework" or something. Otherwise your code works. Thanks, I guess! :) – klefar Aug 14 '13 at 19:20
0

About optimizing:

  1. Don't optimize prematurely - it won't help anything. I'm too lazy to write about that, but search internet, read "Code Complete" and "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices" books.
  2. Don't waste - if optimization won't take more time and is at same readability level, than you can use it.
  3. Optimize AFTER a speed problem arise.

About your problem:

You are absolutely right that there should be better ways to write a code. What you wrote is what workers do, but you need to be smart programmer to make it more easy.

But what you need is more knowledge about language.

Yes, there is a looping possibility for C++. For example following code checks whether a line contains same values:

const int rowCount = 3; // Number of rows
const int colCount = 3; // Number of columns

// Variable for counting same rows
int sameRowsCount = 0;

// Following line is loop: first it sets variable row to 0
// and for each pass it increments it until rowCount is reached
for(int row = 0; row < rowCount; ++row)
{
    // This variable stores whether the row contains same values.
    // At beginning we assume that it does.
    bool isSame = true;

    // Now we will check each column in current row. Note that
    // we begin with 1 and not 0 - at 0 position is value which
    // we check against all others.
    for(int col = 1; (col < colCount) && isSame; ++col)
    {
        if(matrix[0] != matrix[col])
        {
            // We found different values
            isSame = false;
        }
    }

    // If row contains same values, isSame remained true and
    // we increment same-rows counter.
    if(isSame)
    {
        ++sameRowsCount;
    }
}

cout << "Number of same rows: " << sameRowsCount << "." << endl;
  • 1
    He wasn't asking for same values, he was looking for same rows and columns [+diagonals]. Also, his variable is not [matrix], it's [matris]. – Static Cast Aug 14 '13 at 19:03
  • Well, but my code does check how many rows contains same values, doesn't it? And about columns and diagonals: well, he also wasn't asking for us to rewrite his code, only to give him advices and I though it would be best to show something in code for rows and he can try implement columns and diagonals too, which is IMHO better way than just implementing it all. Also note that he attached code which was, for some reason, recently deleted. –  Aug 15 '13 at 16:00
  • I was unable to edit my code before I realized how this worked. I actually sat thinking how to change the size and came up with the same idea. The problem is with diagonals, which is basically 0,0, 0+1,0+1, 0+2,0+2 and so on... I would just use a simple for loop. – Static Cast Aug 15 '13 at 19:15
  • NVM. I guess I was wrong here too. [for loop going past bounds] – Static Cast Aug 15 '13 at 19:16
0

In terms of speed, what you have is not going to be inefficient. If you are looking to generalize the code and make it scalable (e.g. if you wanted to add 2 more rows/columns), there are several things you could do (e.g. looping and a more mathematical form of prize calculation).

The looping has already been discussed, but the prize calculation could be simplified a bit using something like the following:

if (rows > 0 && rows < SOMEMAXIMUMVALUE)
{
    prize = g_satsning * (1 << rows);
}
else
{
    prize = 0;
}

Since your multiplier is an exponent of 2, the math is fairly straight forward. SOMEMAXIMUMVALUE should be declared to be the maximum number of matching rows you expect. For a 3x3 setup, there would be 8 potential matches (3 rows, 3 columns, 2 diagonals), so SOMEMAXIMUMVALUE should be set to 8.

Zac Howland
  • 15,777
  • 1
  • 26
  • 42