Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 07 Mar 2002
Online Last Active Today, 03:07 PM

#5308290 C++ 2048 game - movement function issue

Posted by on Yesterday, 06:50 PM

Well, I had a bit of time, so I wrote it.

#include <iostream>

void move_row(int *array, int step) {
  int write_i = 0;
  int previous = 0;

  for (int read_i = 0; read_i < 4; ++read_i) {
    int entry = array[step*read_i];
    if (entry == 0)
    if (entry == previous) {
      array[step*(write_i - 1)] *= 2;
      previous = 0;
    else {
      array[step*(write_i++)] = entry;
      previous = entry;
  for (; write_i < 4; ++write_i)
    array[step*write_i] = 0;

void print_row(int *a) {
  for (int i = 0; i < 4; ++i)
    std::cout << a[i] << ' ';
  std::cout << '\n';

int main() {
  int a[4] = {4, 1, 1, 0};

  move_row(&a[3], -1);

#5308224 C++ 2048 game - movement function issue

Posted by on Yesterday, 10:20 AM

Skipping over the empty entries of an array is a common algorithm. There is a neat way to do it using a loop with two indices, where you read using one index and write using the other one.

int write_i = 0;
for (int read_i = 0; read_i < n; ++read_i) {
  if (array[read_i] != Empty)
    array[write_i++] = array[read_i];

for (; write_i < n; ++write_i)
  array[write_i] = Empty;

A small modification of that code will do what you need for 2048. Also, instead of writing the loop four times, try to parametrize it so the same piece of code can do all four directions.

If you have trouble with it, I can post some code. But give it a try yourself first.

#5307460 I have an Idea..........

Posted by on 23 August 2016 - 01:12 PM


#5306259 Alternatives for std::heap?

Posted by on 16 August 2016 - 05:54 PM

I am sure what ApochPiQ said is right. Also, if you learn how a priority queue is implemented, you'll realize that std::heap is basically std::vector with some different interface thrown on top. You could very well reproduce that in Delphi.

#5305979 Point around point rotation

Posted by on 15 August 2016 - 08:43 AM

As others have said, floating-point numbers have limited precision and your results are normal. It would have been nice if you had told us what numbers you were getting as part of your initial report.

If you stop thinking in angles and start thinking of the rotation as the primary object to think about, you can get around this problem. If you use complex numbers, like in my code, you can use i as your rotation of 90 degrees. If you are not comfortable with complex numbers, you can still store the cosine and the sine in an object and call that a rotation. Then (0, 1) is exactly the rotation you want.

#5305907 Point around point rotation

Posted by on 15 August 2016 - 02:54 AM

I don't see a problem in your code. Perhaps you can provide a few more lines of code to turn this into a complete program that we can run ourselves to see the problem. If you could do so without depending on external libraries, it would be much better.

Here's one idea to make the code a bit simpler: If you have a function that rotates around the origin, you can write
glm::vec2 rotate_around_center(glm::vec2 point, glm::vec2 center, GLfloat angle) {
  return rotate_around_origin(point - center, angle) + center;
Another suggestion is to remove the conversion to radians and use radians consistently throughout your code. There is no reason to keep around degrees anywhere. If you need to display an angle in degrees, make the conversion just before displaying it, but don't pollute the rest of the program with degrees.

A slightly different mathematical approach is using complex numbers to represent both points on the plane and rotations. The point (x,y) becomes the number x+i*y, and the rotation of an angle alpha becomes cos(alpha)+i*sin(alpha). Now applying a rotation around the origin is achieved by simply multiplying the complex numbers corresponding to the point and the rotation.

EDIT: Here's some sample code:
#include <iostream>
#include <complex>

typedef std::complex<float> Complex;

float const Tau = std::atan(1.0f) * 8.0f;
float const Degree = Tau / 360.0f;

Complex rotate_around_origin(Complex point, Complex rotation) {
  return point * rotation;

Complex rotate_around_center(Complex point, Complex center, Complex rotation) {
  return rotate_around_origin(point - center, rotation) + center;

Complex rotation_from_angle(float angle) {
  return Complex(std::cos(angle), std::sin(angle));

int main() {
  Complex p(2.0, 5.0);
  Complex center(1.0, 0.0);
  Complex rotation = rotation_from_angle(90.0f * Degree);
  Complex rotated_p = rotate_around_center(p, center, rotation);

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

#5305691 Calculus Problem!

Posted by on 13 August 2016 - 10:35 PM

Does anyone know how to integrate this expression for x please?:
ln(ax^n + c)
a, n and c are of course constants, and bot a and c should be positive but n will tend to be negative.

Why are you trying to do that? Without context it's hard to know if using a numerical method would be acceptable, for instance.

#5305147 Fast Square Root For Distance Calculations?

Posted by on 10 August 2016 - 12:14 PM

You started with an instance of XY problem and now you have changed your question into something that I will call the XZ problem. How about you just tell us what it is you are trying to accomplish, what you have tried so far and how it has failed?

#5304404 Only 12 Enemies, And My Fps Drops To 30, Why Is That?

Posted by on 06 August 2016 - 02:22 PM

How many matrices are we talking about? Interpolating a few thousand 3x3 matrices per frame shouldn't be a problem at all. If you are doing a lot of interpolation, perhaps you should consider using quaternions to represent your rotations, because interpolating quaternions is really cheap, especially if you use nlerp.

#5304208 Only 12 Enemies, And My Fps Drops To 30, Why Is That?

Posted by on 05 August 2016 - 09:03 AM

The number one rule in optimization is that you need to measure the improvements. There are rules of thumb and some people that have done optimization for a long time might have some sense for what's likely to work and what isn't; but that's not a substitute for testing.

By now you could have tried it, tested it and posted here to tell us how well it worked.

#5304162 Quick Way To Invert Matrix

Posted by on 05 August 2016 - 05:13 AM

He use a determinant , who know what it is ?

I do. Think of a 3x3 square matrix as a linear mapping from a R^3 to R^3. Linear mappings have the feature that volumes are scaled by them. The determinant is the scale that the volumes are multiplied by.

And who can tell how to use it to compute inverse matrix?

The most obvious connection is Cramer's rule.

For advanced users: There are other ways in which the determinant is connected to the inverse. One I learned about recently is that the gradient of the determinant (as a function of n^2 variables) is the transpose of the inverse times the determinant squared, or something like that. It turns you can use that fact together with automatic differentiation to compute the inverse in a really whacky way.

#5303973 String To Char* :(

Posted by on 04 August 2016 - 07:38 AM

Alvaro my program by default uses char* without null terminator

Sure, but strcpy doesn't care what conventions you have in your head.

strcpy(p, str.c_str());

#5303960 String To Char* :(

Posted by on 04 August 2016 - 06:18 AM

p = new char[ (*len) ];

That's not enough space to store the string and a terminating zero.

if ((*len) > 0)

What's the point of that condition? What would you like to happen if str is an empty string?

#5303676 Only 12 Enemies, And My Fps Drops To 30, Why Is That?

Posted by on 02 August 2016 - 11:44 AM

void MMORPG::getBoneLocation(Shader& shader)
    for (unsigned int i = 0 ; i < 100 ; i++)
        char Name[128];
        memset(Name, 0, sizeof(Name));
        snprintf(Name, sizeof(Name), "gBones[%d]", i);
        boneLocation[i] = glGetUniformLocation( shader.programID, Name );

I can think of several problems with that piece of code, but I'll point out two:
* You don't need to call memset at all. Just erase that line.
* getBoneLocation is a pretty bad name for a function that doesn't get you the location of a bone. Perhaps computeBoneLocations or precomputeBoneLocations would do.

#5302362 How To Make My Crosshair Red When Over An Enemy?

Posted by on 24 July 2016 - 04:10 PM

I can't find any material on collision detection between a ray and a box in any of my books. This means that it should be easy, but nothing comes to mind, any ideas?

Figure out how to compute the intersection between a ray and a plane. You can do it in such a way that the result is expressed in a frame of reference in the plane such that both coordinates will be between 0 and 1 precisely when the rectangular face has been hit. Now use that six times.