Well, L.Spiro has a version that will at least trigger at all (when one coordinate is getting close enough), while the other version looks like in the end the ball will reach one coordinate first, then start jittering around on one axis, move only along the other axis and finally find a new destination. It also means that if one coordinate is reached, the balls will effectively move at only half the speed.
So obviously I second the approach of using vectors, simply because the other code only allows for 45° steps in motion and I doubt that sudden changes of direction while heading towards a destination are intended.
I think you will get the most in terms of learning experience and better design by not assuming a fixed board size and hard coding every possible win condition. After all, the real core of programming isn't knowing language X or memorizing whole libraries, but about problem solving.
How would you write it, if the board size can be configured to 4 or 5? Ironically, you should find that your code will get a lot shorter, cleaner and contain way fewer messy if-else and switch-case constructs.
Once that is working, how would you handle the win condition not being n in a row (where n equals the board size), but a value that can be configured independently? You should find this to be a very small adjustment to your existing code (okay, I'm lying, unless you didn't realize that only two diagonals need to be checked for n = board size).
What if the board doesn't have to be square? Again, this should end up being only a minor change.
That's a bit too general, don't you think? Without using switch or a bunch if-else statements, what does an event dispatcher look like? How do you implement a factory function?
Event dispatchers can use runtime type information or simply strings and just forward events to all handlers that registered themselves for certain message types. I'd actually be a bit sceptical if my event dispatcher starts switch/casing over event types. Same for a factory. A factory using a big switch/case is usually considered the "naive" approach and while typically good enough, it's probably the least desirable implementation. Generally you do not want to touch your factory (or event dispatcher) every single time a new class/message is added.
It also avoids all the other bugs and issues in the C-style implementation above (loop too short, calling strlen on every single iteration, passing pointer by value, the dreadful "function internally allocating memory" thing).
Of course now you have to ask yourself who is responsible for cleaning it up and when should that happen. Rule of thumb: for every "new" that isn't assigned to a smart pointer, there must be one (and only one) "delete".
This piece of code: "rand() % 9 + 1"generates a number between 1 and 10. In C++, arrays begin at 0, so you may not want the +1 there. (An array with 10 elements, goes from 0 to 9)
Nitpick: the number will be between 1 and 9.
About the implementation of the second option. You actually fooled me, as my first impression was you determine a number between 0 and emptySpaces, then make as many steps from the start (skipping filled spots). In that case you should never have to wrap around. But with your approach of starting at the selected spot and then skipping ahead until the first free cell, is the first part even necessary (as in: does it produce better randomized results)?
My impression would be that it might make it less random. If the first 4 spots are filled, you would ways end up with the 5th spot: 5 spots are empty, so spot = rand() % 5 = 0-4. In each case you get spot = 4.
So I think you should either always create numbers 0-8 and skip empty spots as above, or if you do create a number using only the free spots, it would probably be something like this:
int steps = rand() % numberOfEmptySpaces;
int spot = -1;
while (steps >= 0)
//If free, decrease step count
if (board[spot] != 'O' && board[spot] != 'X')
I believe that should create an equal probability for each spot.
Alternatively (and somewhat more cumbersome) you could add an extra layer of indirection by keeping a list of empty spots and randomly picking an index from that list.
//Declared somewhere and initialized with the board
vector<int> freeSpots; //Fill with 0 - sizeOfBoard
const int idx = rand() % freeSpots.size();
freeSpots.erase(freeSpots.begin() + idx);
Since erasing from anywhere but the end of a vector requires moving stuff in memory, a common method is to not remove a value, but swap it with the end and reducing the size of the vector.
By not removing the last element and instead keeping track of the size yourself, you can keep reusing the same vector and just need to reset the size
vector<int> freeSpots(SIZE_OF_BOARD); //Initialize once when starting up
//When placing a marker
//When resetting the game
numberOfFreeSpots = SIZE_OF_BOARD;
Since all random numbers should be equally likely, it doesn't matter in which order the numbers are stored in freeSpots.
Personally I like this approach for simulating a deck of cards, as you don't need to do any initial "shuffling".
Maybe he forgot to mention something like "for 1 billion test runs". In either case it doesn't really matter, since it has little to nothing to do with the actual topic. It's not about converting string<->int, but essentially about subtracting one number from another (while skipping values outside a certain range and using a different offset depending on which range you're in).
At no point should stringstream, atoi, etc. have anything to do with it.
Basically it doesn't matter where your binary ends up, as long as you start it from the debugger. The only thing that matters is what you configured as your working directory. Once you want to run it manually, you have to make sure the binary is located in that same directory.
Considering that your binary will most likely be in POOA when you're done, you may want to change the debugger settings to use that as your working directory (something like $(ProjectDir)/..) and stick with "data/tiles.png" as your path.
The way I consider safe to a persons sanity is to handle the "camera" like any other object. Since scaling the camera doesn't make much sense, all you got are rotation (in the top left 3x3 "sub matrix" and translation in the last column -corresponding to the last 4 floats in the memory layout used for OpenGL-). This means the first three columns are basically the cameras x,y,z (typically "right", "up" and "forward") axes expressed in world coordinates with the last column being it's position. It's convenient and easy to read.
To use it as view matrix, you obviously need to move everything "the opposite way", so you need the inverse of your matrix. Since you didn't scale, your matrix can be inverted in a simple way. The rotation part is transposed (which explains why it's rows, not columns) and the translation is negated along the original axes (which is better explained by showing the result.
So if your camera matrix (using r,u,f,p as right, up, forward, position instead of uvn) is:
So: keep your camera matrix around, don't recalculate from scratch every frame and for heavens sake, stay as far away from Euler angles as possible (ego shooter style camera is about the only thing they can handle without a lot of head ache).
I'm not sure why Kaptein makes rotating an object around itself so complicated. If you want the camera to rotate around itself, you use camera_matrix * rotation_matrix. If you want it to rotate around the origin you use rotation_matrix * camera_matrix (or the other way around). If you are in fact feeling lazy, you can abuse OpenGL to do the matrix math. Translation and rotation are always applied in object coordinates, so objects already rotate around themselves (using their current right/up/forward axes), no matter where they are and always translate along their local axes as well.
Point is: OpenGL is not doing anything "backwards" unless you insist on thinking in world coordinates instead of object coordinates.
-Strafe right is always glTranslate(1,0,0) What people often do: calculating some "right" vector (instead of 1:1 extracting it from the objects transformation matrix) and then going to the trouble of translating along that vector in global coordinates by forcing things to be done "backwards".
-"Pitch around self" is always glRotate(angle, 1,0,0) What people often do: calculate some "right" vector (again), then do stuff backwards (including translating stuff to the origin and back)
If you want to mix things, like rotate around "global up" but around your current position, you still don't need to start translating. You just need to adjust your axis by multiplying the "global" axis with the transposed rotation part of the object (basically you cancel out the existing rotations, so your objects "up" is the same as the worlds "up"):
'and' is not a C++ keyword. If you have a macro named 'and' that is defined as '&&', get rid of it!
Actually it is and it is the same as &&. However, absolutely nobody uses it to the point where I didn't even know about it after almost 10 years of C++. Maybe it's because && is easier to type or simply because it sticks out a lot better than 'and'. Basically, use && and || instead of 'and' and 'or', unless you are extremely paranoid of accidentally using & and | instead.
Minecraft in particular is having a very specific lighting where each cell has two lighting values ranging from 0-15 (one for sunlight and one for artificial light). Sunlight is propagated downwards at full intensity, but loses intensity "sideways" (reduced by 1 per cell). Artificial light is always reduced by 1 per cell. Also, the lighting value of a call is not the brightness of the cell (or geometry in that cell), but the brightness used for adjacent faces. In fact, all cells filled with a solid have lighting values of 0.
Daytime doesn't matter (sunlight doesn't change direction and is always straight down). Darkness (at night) isn't applied by updating and recalculating all sunlight values, but by simply deducting a darkness value from the existing sunlight value.
There is no easy way to recreate that system with basic 3D API functions and it only makes sense for a grid/block based world like Minecraft.
Not to mention that you better make sure that there is absolutely no location in your code that creates a copy of the map or calls a function where you pass it by value. It at any point you create a temporary copy of that map, all your pointers will be invalid and your walls deleted.
If that is the case, it might be time to google for the Rule of Three.
Did you place a breakpoint in the destructor and make sure it only gets called once? Debug output might actually work better, as some debuggers are notoriously bad with breakpoints in destructors.
If in doubt, place a breakpoint in the destructor of your Wall class and check the call stack when you hit it to see where it's getting called.
Things don't get magically deleted on their own. A more far fetched explanation would be writing out of bounds and screwing up the internal pointer of the vector.