Jump to content

  • Log In with Google      Sign In   
  • Create Account


Álvaro

Member Since 07 Mar 2002
Offline Last Active Today, 12:17 PM

#5175480 So... C++14 is done :O

Posted by Álvaro on 22 August 2014 - 08:21 AM

A good example of a change is the addition of . I rarely if ever use int or short anymore, its now all uint16_t or int64_t. I know what I'm getting and I know their limits. I can use them without tons of asserts to std::numeric_limits. Apart from little-big endian issues, which only really crops up when serializing data, they are portable.


And your code is thus non-portable to a platform with a different native word size. Cuts both ways.


Is this of any practical relevance? Do you know of any platforms where those types are not available? Any platform that matters? I mean, maybe there is a washing machine somewhere that won't be able to run my game, but I can live with that.


#5175369 So... C++14 is done :O

Posted by Álvaro on 21 August 2014 - 06:15 PM

I believe right-shifting a negative integer is implementation defined, but I know signed-integer overflow is undefined behavior.

Nasal dragons and other funny expressions are a way of drilling in the idea that you cannot make any assumptions as to what the compiler might do with your code. The description I prefer is this: Undefined behavior sometimes means your program compiles without warnings, runs without crashing and does exactly what you expect it to do, right until you show it to your boss or your most important customer.


#5175144 So... C++14 is done :O

Posted by Álvaro on 20 August 2014 - 05:55 PM

I like it, Erik. But when I started reading your code, I thought you were going for the following, which is useful in computer chess when using bitboards:
typedef unsigned long long u64;

struct BitIter {
  BitIter(u64 number) : number(number) {
  }
  
  BitIter operator++() {
    number &= number + ~0ull;
    return *this;
  }
  
  bool operator!=(const BitIter &other) const {
    return (other.number != number);
  }
  
  int operator*() const {
#ifdef __GNUG__
    return __builtin_ctzll(number);
#else
    /*
      Based on
      @author Martin Läuter (1997)
              Charles E. Leiserson
              Harald Prokop
              Keith H. Randall
      "Using de Bruijn Sequences to Index a 1 in a Computer Word"
    */
    static const int index64[64] = {
      0,  1, 48,  2, 57, 49, 28,  3,
      61, 58, 50, 42, 38, 29, 17,  4,
      62, 55, 59, 36, 53, 51, 43, 22,
      45, 39, 33, 30, 24, 18, 12,  5,
      63, 47, 56, 27, 60, 41, 37, 16,
      54, 35, 52, 21, 44, 32, 23, 11,
      46, 26, 40, 15, 34, 20, 31, 10,
      25, 14, 19,  9, 13,  8,  7,  6
    };
    
    return index64[((number & -number) * 0x03f79d71b4cb0a89ull) >> 58];
#endif
  }
  
private:
  u64 number;
};

namespace std {
  BitIter begin(const u64 &number) {
    return BitIter(number);
  }
  
  BitIter end(const u64 &) {
    return BitIter(0ull);
  }
}

#include <iostream>

int main() {
  u64 knights = 0x4200000000000042ull;

  for(auto square : knights)
    std::cout << square << ' ';
  std::cout << '\n';
}



#5175141 How to make a AI choose?

Posted by Álvaro on 20 August 2014 - 05:27 PM

"Utility" > "fuzzy"

;)


#5175021 How to get rid of camera z-axis rotation

Posted by Álvaro on 20 August 2014 - 09:20 AM

If you rotate around the X axis, then rotate around the Y axis, then undo the rotation around the X axis, and finally undo the rotation around the Y axis, the resulting transformation is a rotation around the Z axis. This is a feature of rotations in 3D space, and you will observe it regardless of whether you use quaternions or anything else to represent them.

Perhaps instead of rotating around the X and Y axes, you meant to control pitch and yaw. If that's the case, use those angles to build the rotation from scratch every time.


#5174736 So... C++14 is done :O

Posted by Álvaro on 19 August 2014 - 08:34 AM

You should be using vector::size_type, if you're iterating vectors, or the appropriate type for whatever container you're iterating. Not int. Not size_t.


`vector::size_type' is not a type. `std::vector<SomeComplicatedType<PossiblyWithTemplateParametersOfItsOwn>>::size_type' is, and now we are back in unreadable-mess land.

You could do this, but it looks horrible:
for (auto end = v.size(), i = decltype(end)(0); i != end; ++i) {

Since indices are just numbers, and you are not likely to have 2^31 or more things in a vector, I don't think there is anything particularly wrong with using `int'. But the compiler will complain if you compare an `int' with some unsigned integer, and there is the thing with `int' being potentially just a 16-bit type (not that it keeps me up at night), so `size_t' fits the bill here.

This is not a strong argument, but I can't imagine a situation where `size_t' wouldn't work.


#5174702 So... C++14 is done :O

Posted by Álvaro on 19 August 2014 - 06:14 AM

Here's another one:

for (size_t i = 0, end = vValues.size(); i != end; ++i) {
if (i > 0)
std::cout << ", ";
std::cout << *vValues[i];
}
std::cout << '\n';

 
Oh yeah, if you want to test on the index^^ You threw me a bit off with your example by using the direct "vValues[i]" value in the test. I actually got used to writing
unsigned int i = 0;
for(auto pValue : vValues)
  if (i > 0)
    std::cout << ", ";
  std::cout << *pValue;
}
std::cout << '\n';
but I quess this is rather questionable as well. Range-based for loop that also gives the current index? Now I quess I'm thinking too crazy ;)

You are missing a "++" somewhere, or i will always be 0 in that code.


#5174698 So... C++14 is done :O

Posted by Álvaro on 19 August 2014 - 05:55 AM

You can do that with the range-based loop too.

for(auto pValue : vValues)
{
	if(some_test(pValue))
		pValue->DoSomething)
}
Loop-modification is really the only perfect reason where range-based loops totally don't work.


Here's another one:
for (size_t i = 0, end = vValues.size(); i != end; ++i) {
  if (i > 0)
    std::cout << ", ";
  std::cout << *vValues[i];
}
std::cout << '\n';



#5174687 So... C++14 is done :O

Posted by Álvaro on 19 August 2014 - 05:31 AM

Regarding the different ways of writing a loop that iterates through a vector, I prefer using indices most of the time, because it's the easiest to modify in the future.

For instance, let's start with code similar to Hodgman's:
for (size_t i = 0, end = vValues.size(); i != end; ++i)
  vValues[i]->DoSomething();

What if I only want to DoSomething on elements that pass some test?
for (size_t i = 0, end = vValues.size(); i != end; ++i) {
  if (some_test(*vValues[i]))
    vValues[i]->DoSomething();
}

What if I need to add more elements to the vector in some circumstances?
for (size_t i = 0; i != vValues.size(); ++i) {
  vValues[i]->DoSomething();
  if (some_circumstances(*vValues[i]))
    vValues.push_back(some_new_thing); // Iterators are now invalid, but indices still work just fine
}

Try to do that with any of the other styles. smile.png

For very simple loops, the range-based format is very clean and I sometimes use it.


#5174422 Calculating Relative Height and Angle

Posted by Álvaro on 18 August 2014 - 05:52 AM

A) distance to surface = distance to center - radius (as Lactose! said).
B) Compute the dot product of the vector from center to craft and the forward vector and convert to an angle using the inverse cosine function, then take Pi/2 - that angle.
C) You don't need to do anything special: Compute gravity, lift, drag, thrust and any other forces acting on the plane, add them together to compute the total force and let integration do the work.

As a general comment, it looks like your math skills might not be up to snuff. Perhaps you could reduce the scope of the project? Have you tried to make a flight simulator where the land is a rectangle? That might be a good stepping stone between where you are and where you want to be.


#5174244 Best way to traverse a 2d array to dertermine the winner in Tic-Tac-Toe

Posted by Álvaro on 17 August 2014 - 05:08 AM

While the solutions posted here are really interesting, is it really the best thing to tell a beginner to use low level bit operations to check if someone wins at tic-tac-toe?  I would recommend just iterating through the board, checking each of the possibilities (as already mentioned, 3 horizontal, 3 vertical, and two diagonal).  Once that is working, then you can start to try to optimize the solution (i.e. create separate functions for each type of check, build incremental lists of winning moves, or whatever). 
 
However, all of those are just for learning - I can't believe that a check that is done once for each of the 9 moves in a game is really a candidate for doing abstract optimizations...


I have written code for a lot of board games. The first thing I do is come up with a board representation, a move representation, and functions to make moves, undo moves, generate moves and check for end-of-game conditions.

If you are writing a GUI where these things will only be needed once per move in a game, you normally don't have to think about it too hard, and any naive implementation will do.

But if you are writing any type of AI, you are going to have to consider gazillions of moves internally, whether you are using minimax, MCTS or something else. The performance of those basic routines really does matter, and there are clever implementations to be found for pretty much every game I can think of.

Tic-tac-toe is a learning tool, and it's a good opportunity to learn how to think of these clever implementations as well.


EDIT: One more thing: This is not the "For Beginners" forum. The thread I linked to was in "For Beginners", and I was reluctant to describe the fancy bit-manipulation method there.


#5173764 Best way to traverse a 2d array to dertermine the winner in Tic-Tac-Toe

Posted by Álvaro on 14 August 2014 - 08:16 PM

With bitboards, it would look like this (remember you only need to check the side that just moved):
// The assignment of bit numbers to squares goes like this:
// 8 7 6
// 5 4 3
// 2 1 0

bool three_in_a_line(unsigned x) {
  if (x & (x>>1) & (x>>2) & 0111)
    return true;
  if (x & (x>>3) & (x>>6) & 0007)
    return true;
  if (x & (x>>4) & (x>>8) & 0001)
    return true;
  if (x & (x>>2) & (x>>4) & 0004)
    return true;
  return false;
}
Disclaimer: I didn't test the code.


#5173603 3D Line Equation?

Posted by Álvaro on 14 August 2014 - 08:44 AM

It looks like the book is missing a second equation in that system. It's probably this one:

-x + 3*y = 2

Someone said that the book is known to have mistakes. If this bothers you, perhaps you should get a different book.


#5173584 Best way to traverse a 2d array to dertermine the winner in Tic-Tac-Toe

Posted by Álvaro on 14 August 2014 - 07:19 AM

More sophisticated would be to use a bitboard but Alvaro will probably be along in a minute to boggle your mind with that idea ;)


Coming through! smile.png But not with bitboards. For tic-tac-toe, I posted a much better solution a couple of years ago.


#5173571 3D Line Equation?

Posted by Álvaro on 14 August 2014 - 06:48 AM

What Paradigm Shifter posted is a parametric equation. What you seem to be looking for is an implicit equation. The problem is that a single linear equation in R^3 describes a plane, not a straight line. You can use two equations to describe your line, for instance like this:

4*x -13*y +8*z = 0
      3*y -2*z = 2





PARTNERS