Jump to content

  • Log In with Google      Sign In   
  • Create Account

Josh Petrie

Member Since 11 Jun 2003
Offline Last Active Private

#5173940 C# While Statement

Posted by Josh Petrie on 15 August 2014 - 11:57 AM

What exactly are the errors?


The first line of code won't compile because "myPokemon[int parse(myChoice) - 1]" isn't a valid expression. You probably mean "int.Parse(myChoice)" not "int parse(myChoice)."

#5173706 Bashing my face against the ArcSynthesis.org brick wall.

Posted by Josh Petrie on 14 August 2014 - 03:45 PM

What is the purpose of a tutorial that just assumes you know what to do?


That's, um, exactly what a tutorial is for. It demonstrates how to do a specific thing, but assumes you are familiar with the supporting knowledge. It's why tutorials can very often be horrible ways to learn things.


That said, the Arcsynthesis site is a little broader than a tutorial. However, it's focus is still to teach you things about OpenGL, and not the subtle rigors of cross-platform C++ projects (which can be exceedingly complicated and a subject for their very own book). Providing source code and compilation instructions seems to be done more as a cursory favor than a really dedicated effort.


The errors you are listing are linker errors, not compiler errors. They indicate that the references libraries (glloadD and so on, which appear to be part of that Unofficial OpenGL tutorial) aren't being found in the linker search paths. You should do two things next:


First, verify that you actually have files named "gllloadD" and so on (probably with .lib or similar extensions) somewhere. Perhaps you acquired a bad copy of the tutorial source archive that is missing these files (the website claims they should be included in the distribution and do not need to be externally downloaded).


Then, look at the (premake-generated, it sounds like) project file in your IDE: specifically look for the section that defines the library search paths for the linker. Verify that one of the paths is the directory containing the glloadD, et cetera, files.


Nowadays: You have to convert sourcecode into an IDE-freindly format (because they're all read c++ in different ways), you have to compile OpenGL source code into a an ide freindly version that it can use. You also apparently have to have about 5 different versions of OpenGL (glew, gltut, freegl, glib and god knows what else) You then, presumably have to tell the IDE where this version is.... and who knows what crazy unintuitive stuff beyond that


You don't have to do that at all. The author has provided a premake-based setup for you to allow you to generate projects for your preferred IDE; this is hardly required for C++ and is done so as a convenience for you. In this case you've run into an issue with the convenience, but that doesn't mean you wouldn't run into different issues if the author just gave you the source code and told you to compile it and resolve the dependencies yourself.


The OpenGL issues are simply the way OpenGL works -- all of those things you mentioned are not, incidentally, OpenGL -- they are utilities for making OpenGL easier to deal with. If they were there, you'd have even more problems. I appreciate that you are frustrated because things aren't working right, but in this case the author has done a fairly commendable job of trying to simplify your life (cross-platform, cross-toolchain C++ is complicated), especially given that the purpose of his/her site is not to teach you about all the complex issues surrounding distributing C++ to an unknown target environment.

#5171917 My first Win32 Game

Posted by Josh Petrie on 06 August 2014 - 11:52 AM

Here are some comments:

  • You are missing some opportunities for const-correctness. For example, your accessor methods (like GetScore) could be declared "int GetScore() const;" since they do not require mutating the invoking object.
  • You should use constructor initializer lists; instead of setting mScore inside the body of the constructor, do "Player::Player() : mScore(0) { }" This is a good habit to get into because it is faster for some types (and certainly never slower) and required for some other types (such as references).
  • Use an enumeration for the field content instead of #define macros; in general, enumerations or const variables are preferable for constants. Macros should be used sparingly.
  • Use consistent naming. If "sign" in GetSign/SetSign refers to the field content (as I suspect it does just from looking at the header), adjust the names so "sign" and the "field content" enumeration are in sync (i.e., use one or the other).
  • You don't need to provide empty constructors/destructors, they will be generated for you by default (unless you do something to disable that, which are you not in these cases).
  • A common convention for "output parameters" (the results of GetCornerPoints) is to pass those parameters as pointers. That way, it is clearer at the call site that the parameters are potentially-modified (GetCornerPoints(&p1, &p2)). It also allows you to make some output parameters optional, in the case where the caller may not care about that particular parameter (and thus can pass a null pointer). Using non-const reference parameters is often a bad idea, because it can result in the violation of the principle of least-surprise.
  • Prior to C++11, "larger" non-POD types (possibly including point types, though not your specific point type) should be passed by const-reference, rather than by value (as in SetCornerPoints). This avoided extra copies. In C++11, move semantics alter this guidance: you can pass by value if you're just going to store, as you do in SetCornerPoints, since the compiler can use a move there. Otherwise, you may still want to consider passing by const-reference.
  • The corner points of the field are something you could mandate be provided by the constructor of Field; it's probably not a good idea to allow them to be mutated after the field is constructed, since that makes it easy to create nonsense boards. APIs should be easy to use in the correct fashion and hard to use in the incorrect fashion.
  • The field constructor should at least initialize the field to a good state (set the initial size, zero-out the points if you're not going to require them as constructor parameters).
  • DO NOT put "using namespace std;" in header files. This pollutes the global namespace for ever more, since you cannot undo a using declaration. Fully-qualify items in headers, or put the appropriate using directives in a tighter scope if necessary.
  • A tic-tac-toe board is a 2D grid. Consider altering the interface of your board to refer to cells by an row and column index, since that's more natural. You can still internally use a linear array of nine fields by doing some simple math on the row/column indices.
  • Try to avoid "dumb pass through" APIs when possible. An example of this is Board's GetFieldSign/SetFieldSign methods, which just forward to the field APIs to do the actual work. This technique can create a lot of boilerplate code that's not easy to maintain. Consider instead a design where the board can simply get a reference to a field at a given row and column: Field & GetField(std::size_t row, std::size_t column). Then you can leverage the API that is already present on the field class.
  • In a project this small, it's not too big of a deal, but in the future consider how you might separate game logic from rendering (your board class conflates them now). Keeping independent, single responsibilities allows for better maintainability and reusability.
  • Similarly, in a project this small it's not a big deal, but in larger projects consider looking at how you can hide implementation details against things like Windows and GDI. I don't mean stuffing things in the private access section of a class, I mean removing the header references to Windows and GDI entirely (thus preventing your clients from acquiring the build-time dependency of such a header. Things like the "private implementation" or "pimpl" pattern might be worth looking into once your projects get larger.
  • Use forward declarations when appropriate to avoid unnecessary header dependencies. You can, for example, forward-declare "class Player" in the Board header, and then you can avoid the player header include there (moving it to the .cpp file, where it's better because it won't cause as many files to recompile if it changes).
  • You can avoid the call to ResetFields in the board constructor if you instead ensure that a field default-constructs itself into a sane state (as above).
  • A tic-tac-toe board is a grid. You can do the initial computation of all the grid points in a loop, rather than nine individual manual sets.
  • The naming convention of the board member variables does not match that of the field member variables (no "m" prefix on the former). Consistency is important.
  • The board drawing function creates new GDI objects every call; this will eventually exhaust GDI handle resources and you'll crash. You should either create/destroy them every draw call, or create them once (in the board constructor), since you're also trying to destroy them in the destructor (which only actually cleans up the last pen and brush.
  • Your local member variable naming convention is also inconsistent.
  • There are lots of magic numbers in your drawing method; consider using named constants instead.
  • This: static_cast<ostringstream*>(&(ostringstream() << player[0].GetScore()))->str();  is horrible. Use std::to_string in C++11, or create a single stringstream on the stack and re-use it to do (stream << score; stream.str()) (or better yet, make it a utility function).
  • Think about how you can do many of the drawing steps -- the board lines, for example -- in fewer lines of code using loops and other ways to exploit the fact that you have a grid. It will make for fewer magic numbers and fewer places to adjust code when you want to change the overall look of the board.
  • The if statements in SetFieldSign are unnecessary. Just do: Fields[field_id].SetSign(sign); Check sign for validity prior to that if desired (if you switch to using an enumeration for the sign, it would be clearer).
  • Consider returning a field pointer out of GetClickedFieldID, so the user doesn't have to go re-lookup the field.
  • In your Game class, you pass the entire board by value to CheckWin. Pass it by constant reference.
  • "CheckWin" is a cumbersome name. Consider something like "CheckForWin" instead.
  • You can increase maintainability by factoring out entire-column and entire-row checking into utility functions (especially easy once you change the board API to do row/column queries). This reduces duplicate code.
  • You return magic numbers from CheckWin. Use an enumeration to indicate result state.
  • In SwitchActivePlayer, pass the objects by const reference. Consider a design that does not require passing seemingly-unrelated parameters to a function that sounds like it should just toggle internal state. What you have now produces a bad abstraction.
  • It's unclear to me why you need the "ghost player."
  • It does not make sense to call AllocConsole inside WM_PAINT. Move it to an initialization call site.

#5170730 Python IDE

Posted by Josh Petrie on 31 July 2014 - 05:04 PM

Not really the case. IDEs include compilers which may or may not differ. If they differ then it matters a lot.



IDEs do not always include compilers. Python IDEs in particular do not (as you note), since Python is interpreted, and toolsets that work with or extend Python often simply use your installed version of Python (or have the option to, in addition to a built-in version).\


What is the best IDE to use to start learning python on?


Personally I use vim for all my Python work. You can pretty easily just use your favorite text editor to get started -- if you have seven languages under your belt you should have already developed a favorite. Then maybe try out all the IDEs you can find and pick one that suits you the best.

#5170725 Snake code review request

Posted by Josh Petrie on 31 July 2014 - 04:37 PM

Here are some assorted thoughts gathered from a brief overview of each file, in order:


  • Functions that take several Boolean parameters are generally less-readable at the call site; ScanDirectory(true, false) makes it really hard to tell what the behavior of ScanDirectory is -- what does that second Boolean mean, exactly? Using enumerations instead can improve readability by making the call site read more like F(Options::Recursive | Options::IgnoreEmptyFolders).
  • Similarly, functions with tons of parameters can be daunting to read and maintain; consider encapsulating related parameters in a single structure. Your doEvents() function appears to mutate the up/down/left/right parameters, so consider wrapping them up into a structure representing button state and passing that by reference instead.
  • Passing mutable parameters by reference makes it harder to tell from the call site that they will potentially be changed. A common idiom is to pass mutable parameters by pointers instead, so the call-site has to include the address-of operator to indicate potential modification. Or, in the case of doEvents(), consider simply returning the new input state structure.
  • "intersect" is not as good of a name as "CheckIntersection" or "DoesIntersect." It's generally a good idea to have query functions like that named in a way that reflects the query they perform, and "intersect" doesn't.
  • "i" is a very poor name for a function parameter. What does it do? It should be obvious from the function prototype.
  • Something you may want to consider exploring next is the concept of data-driving your game; that way you don't have to have hard-coded strings referring to sound files, and so on, in your code (and thus won't require a re-compile to change them, among other benefits).
  • Similarly, something you may want to look at for future work is building a "map" structure that can be used to generically store and check for interaction with various game entities on the map; as it stands, if you were to add a new piece of food to the game you'd have to also hard-code all the intersection check logic and so on for it. A map structure and data-driven design will really elevate your project to the next level (I don't recommend you tackle both at the same time though; pick one).
  • On line 129 of main.cpp, you perform integer division by 3 against score; this truncates.
  • Take a look at patterns like "if up, snake.MoveUp()" At a basic level you can replace most of these with switch statements, and for some (like the snake movement) you can remove the individual checks entirely if you think a little more about how you might write a generic "moveSnake(direction)" method. Think about what exactly happens when the snake moves in each direction, and what that pattern translates to arithmetically. This will allow you to reduce the amount of very-similar code you have, increasing maintainability.
  • You mix #pragma once and #ifndef include guards; settle on one. Consistency is important.
  • Comments like "inline definition" next to the inline definition of some method are useless filler.
  • Several of your member functions can be made to support better const-correctness simply by appending "const" to the declaration; for example, all your accessors (int getPoints() const { return points; })
  • You conflate logic and rendering in your entity classes; this is reasonable for starting out and for such a small project, but as the scale of your project grows you should consider ways to keep them distinct responsibilities of distinct types. This will save you lots of code and lots of maintainence headache in the long run.
  • Entity has a method bloat problem: lots of ways to achieve apparently the same thing (lots of method overloads), and some of those ways are unclear. What does the setPos overload that takes another entity (and that badly-named "i" parameter again) do? It's not apparent from the prototype.
  • A lot of the behavior handled in the spawn() methods is probably something that should be handled elsewhere. For example, the map structure, when you add one.
  • Be consistent: your sound class uses both "file" and "path" parameters to refer to what appears to be the same thing.
  • It's very odd that you can reset the path of a sound. Why not just make a new sound object? Having the ability to externally mutate such basic state has implications that significantly increase the (eventual) amount of work you'd need to do in this class's implementation, especially since audio objects usually need to support multithreaded work contexts. Object immutability, where possible, is a good thing.
  • The RAND_COL macro is a bad idea; use an inline function to get a random color.

Overall, not too bad. There's definitely more to worry about, but the above is a pretty decent list of relatively low-hanging fruit. The biggest overall suggestion I'd give you is to try to do more with less. Early in one's programming career, one has a tendency to use more variables for tracking things and create more redundant copies of things than are necessary - this actually makes the code more complex and harder to follow and maintain. The fewer "moving parts" you have, the better. That's why I encourage you to look at things like data-driven approaches: they help you to generalize code, removing specialized cases and duplicate code/storage.

#5162870 Why do we need to iterate data structures as they are already in RAM

Posted by Josh Petrie on 25 June 2014 - 04:52 PM

I was thinking I'd use a geometric data structure that could morph from one data structure type to another.



This is amusing theorycrafting, and reminds me of the invention of the CAR compression algorithm. I'm very eager to see your implementation of such a feat.


But not here, this is not appropriate for For Beginners. Moving you to General Programming.

#5159529 Deciding to switch to C++

Posted by Josh Petrie on 10 June 2014 - 10:10 AM

Also, I'm not sure whether or not I should finish my current game(It's going to take a ton of time to finish) or just switch now.


Absolutely finish your game.


You can, as jbadams suggests, learn C++ at the same time. But the ability to finish a game project is a compelling one for a potential employer; the sooner you start on that habit the better.

#5159523 whats this? javscript/ga

Posted by Josh Petrie on 10 June 2014 - 09:43 AM

disagree, already said why

Unfortunately, whether or not your disagree turns out not to have much bearing on reality. You aren't being particularly respectful of the community of people who are trying to help you; you should take the advice they've given you about doing basic research on your own to heart. You can use it to answer your most-recent questions, and if you have follow-up questions you can post them separately (make sure to clearly explain the research you've done on your own), since this topic has strayed far from it's original question.


I am closing this thread now, since it has run its effective course. Have a nice day and good luck with your research.

#5134173 could someone help me on what to do? i have a little experience with c# c++

Posted by Josh Petrie on 24 February 2014 - 01:20 PM

Choose a language; I'd recommend C# or Python normally, but in this case you should probably choose the same one your classes are going to teach you. Learn basic programming. This will likely involve making programs in a console-based, text IO format for some time. The simplest game you are likely to be making early on is a "guess the number" game in a text console environment, which can be done with a few simple programming constructs and iterated on fairly well.

#5133691 Legacy code (what's it and how is related to c++)?

Posted by Josh Petrie on 22 February 2014 - 06:57 PM

Legacy code isn't always bad. It's just old. Changing old just because it's old isn't a good idea, especially on shipping products. For example, the code base of Guild Wars (and Guild Wars 2) doesn't use the standard C++ library for containers, et cetera. All the containers are hand-rolled. This was done (among other reasons) because in the formative years of the code base, the standard library wasn't very well implemented. The modern standard library is much better, and quite powerful, and while sure it would be nice to rip out all that old code and replace it with standard stuff... why? The existing code works and is tested, and introducing a change (especially on that scale, but not just on that scale) has a risk of breaking the functionality. 


Why take such a risk for no demonstrable benefit? Until there is a demonstrable benefit (and again, being "new" isn't one), taking that risk is usually a poor business and engineering decision.



Even legacy code that is bad carries that change risk. Bugs are routinely discovered in code that we've shipped; sometimes we don't fix them immediately because the ramifications of the change need analysis even if the change makes the code better from an engineering standpoint.


When you work on large projects with serious business implications, not every decision can be based on pure engineering.


Somebody mentioned Halo earlier on; Bungie still uses that very same code base in Destiny, and it's in the new Halo games as well. Much of has evolved over time but there are definitely files that retain much of the original code or comments from, for example, Aleph One's code (though you may need to go back a fair few years since the project has diverged).


There's little point (and lots of cost) to rewriting everything from scratch every time a studio starts a new game. It already takes man-decades of work to ship a AAA commercial title these days. We cannot afford to increase that.

#5133690 My goals! Programming trajectories.

Posted by Josh Petrie on 22 February 2014 - 06:44 PM

I guess a possible plan would be: 1. C# and unity (Make several games.) 2. learn Lua for Cry engine. 



I don't really understand the focus on CryEngine; you're quite a way off from being able to leverage it well and you're too inexperienced to even know if you really need anything it offers. It sounds like you're only looking at it because its popular.
Learn C#. It's a great first language. Unity is also a great tool for building games; that would be a good thing to learn as well. Get some basic programming experience with C# under your belt working on simple thing so you understand the basic concepts, then try your hand at making a game with Unity. Then re-evaluate your educational goals and plans at that time. There's little point in setting too firm a stake so far in the future -- lots of things will change by then.


Should I learn more languages?



Eventually. Good programmers know many languages. But for now, focus only on one.


P.S how do you make your own game engine? what is commonly used for this?



You build it with a programming language and related tools just like you'd build anything else. Don't worry about making engines now; that is a topic that is beyond your ken right now. You need to have built at least a few games to have a good idea of what actually needs to go into an engine. Make games first.
Good luck!

#5133689 Pros and cons of systems like GameMaker, GameSalad, etc?

Posted by Josh Petrie on 22 February 2014 - 06:39 PM


One programming language (GML) to master




True of Java (or any other one programming language) as well. Further, good programmers know many languages.




   - Not exactly resume material (if you're looking into developing professionally)




That isn't entirely true. A finished project will make a better portfolio piece than an unfinished one, usually. This is especially true if the position you are applying for is something more like a game design position rather than an engineering one. Further, you shouldn't judge the value of something only on the basis of its merit as a portfolio piece in a job interview. Building and completing games in GameMaker can still teach you valuable skills about logical thinking, structure, and problem solving. Even if you never put those games on your resume.

If there are memory or other system-related issues, debugging might be pretty tricky


I'm not entirely clear what you mean here.



If you want to be a programmer in the games industry, you're going to need to know how to program. Probably in C++. But if you're just a hobby developer who wants to make games quickly, something like GameMaker can be great if you can make your games within its constraints and you don't really care about learning other languages like C++, Java, C#, Objective-C, or what have you.


You can make pro and cons lists for days. But what really matters is what your goals are.

#5132676 straightup monogame/xna or readymade engines for beginners?

Posted by Josh Petrie on 19 February 2014 - 10:55 AM

Using some engine built on those frameworks should offer you higher-level services and allow you to get something more "game-like" up and running quicker. If that is your primarily motivation, I would take that approach.

#5128626 C If Statement Question

Posted by Josh Petrie on 03 February 2014 - 10:21 PM

This sort of thing is generally considered "bad" (using a ternary operator to wholly replace an if-statement):


(grade >= 60) ? printf("Passed!\n") : printf("Uh-ohhh...\n");


Generally, you should prefer an if statement to the ternary operator if the operands to the ?: are verbs or complex expressions with side-effects (as they are above: printing). 


The second example is a more acceptable use of the ternary operator:


puts(grade >= 60 ? "Passed!\n" : "Uh-ohhh...\n");


#5128625 The gaming industry, advice!

Posted by Josh Petrie on 03 February 2014 - 10:15 PM

However I have zero expirence with programming and little expirence with art design on computers. I do play a handful of games from triple A titles like bf4 on pc  to indie games like insurgency standalone and rising storm.



You should work on getting some experience with either or both of the first two topics. Making games is fundamentally different from playing them; while it's generally a nice perk that you are interested in playing games a hobby, it's not going to get you a job.


Through research I found many people to have worked long hours starting off as things like game testing were the pay is bad and the labour is intensive,


The industry has a reputation for being tough, but it's not a universal truth. You don't have to settle for extreme hours of unpaid overtime (and you shouldn't; when you do you only contribute to the problem). You also don't have to start in QA (and I don't generally recommend it), and it is not necessarily any easy to use QA as a stepping stone than it is to just get the job you actually want right off the bat (that is generally an exaggeration passed off as reality by clueless gaming press).


how easy it is to find a job, pay, hours of work, enjoyable, stressfull,  and is it a longterm career that is worth looking into, what education do I need.


It depends. If you are good, it's easy to get a job. If you are smart and self-confident (and not wholly risk-averse), the hours are normal. Whether or not it's enjoyable a stressful is very subjective, but it's certainly a viable long-term career path.


The education you'll want to get depends on your area of interest. If it's programming-related, you'll probably want a computer science degree. Art, probably some kind of art degree. Et cetera.


also a side note Is would it be good to start small and purchase game maker and create a 2d platformer, me and my freidn are interested in making a game like spelunky and possibly finding a way to sell it.


It is always a good idea to start small, and always a good idea to work on and finish game projects. It's highly educational and can eventually give you some awesome portfolio pieces. And maybe even make you some money along the way.


Be careful about spending money outright though; if a tool has a trial version, make sure you try it out completely before paying. You can make games without paying a single penny, so don't throw down your hard-earned money until you know you need (or want) to.