Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 165 166 [167] 168 169 ... 795

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 816281 times)

Nadaka

  • Bay Watcher
    • View Profile
    • http://www.nadaka.us
Re: if self.isCoder(): post() #Programming Thread
« Reply #2490 on: June 06, 2012, 03:11:21 pm »

Gatleos: You probably want to create a state pattern, rather than a raw tree.
Logged
Take me out to the black, tell them I ain't comin' back...
I don't care cause I'm still free, you can't take the sky from me...

I turned myself into a monster, to fight against the monsters of the world.

Gatleos

  • Bay Watcher
  • Mournhold... City of Light... City of MAGIC!
    • View Profile
    • Someone Sig This
Re: if self.isCoder(): post() #Programming Thread
« Reply #2491 on: June 06, 2012, 03:37:07 pm »

Thanks for the advice, kaijyuu! I'll probably be going the simple text document route at this point, and just have an escape character to tell when I'm giving a command rather than dialogue. That's really all I'll need, I think.
Gatleos: You probably want to create a state pattern, rather than a raw tree.
That was my other problem; I realized that just making a tree for the dialogue would bloat things tremendously. I need a way to have the same dialogue choices show up in different places without re-defining them for every conversation state where they appear, so I guess a state pattern would be the best thing here. Just a way to add or remove dialogue choices based on whatever variables I put in there. At least, I think that's what you mean.

The only problem is, I have no idea how I would go about doing that. I've never used a state pattern since, like I said, I've never coded something with huge conditional trees that I had to define manually.
Logged
Think of it like Sim City, except with rival mayors that seek to destroy your citizens by arming legions of homeless people and sending them to attack you.
Quote from: Moonshadow101
it would be funny to see babies spontaneously combust
Gat HQ (Sigtext)
++U+U++ // ,.,.@UUUUUUUU

GalenEvil

  • Bay Watcher
    • View Profile
    • Mac-Man Games
Re: if self.isCoder(): post() #Programming Thread
« Reply #2492 on: June 06, 2012, 03:58:16 pm »

you might be able to do something like this:

Code: [Select]
#000 <EndConversation>
#001 Hello -> #002, #003
#002 Sup? -> #numbers, #more numbers, ...
#003 Umm.. Bye! -> #000
#004 Want to ask more stuff -> #002, #003

Doing it that way you could have your state (the first #xxx sequence) which lead (via ->) to more options delineated by ", " to additional states depending on what directions you want the conversation to take after they say their peace. Or you could go further and have different sections for "call" and "response" lists
Code: [Select]
--Call List
#C000 Bye! -> #001
#C001 Hello -> #R001, #R002
#C002 ...
#C003 ...

--Response List
#R001 Hello! How are you? -> #C002, #C003, ...
#R002 Bye! -> #C000

--Start/End conversation tags
#000 <StartConversation> -> #C001
#001 <EndConversation>

It might be a bit of a hassle to set up every way that you might want a conversation to play out but it might make it a little easier to organize and should be easier to look up things just based on their C/R IDs or Generic IDs.
I hope that I didn't just make a really stupid suggestion. I have never done a conversation system for a game environment before so I have no idea how it/they actually work.
Logged
Fun is Fun......Done is Done... or is that Done is !!FUN!!?
Quote from: Mr Frog
Digging's a lot like surgery, see -- you grab the sharp thing and then drive the sharp end of the sharp thing in as hard as you can and then stuff goes flying and then stuff falls out and then there's a big hole and you're done. I kinda wish there was more screaming, but rocks don't hurt so I guess it can't be helped.

Nadaka

  • Bay Watcher
    • View Profile
    • http://www.nadaka.us
Re: if self.isCoder(): post() #Programming Thread
« Reply #2493 on: June 06, 2012, 03:59:44 pm »

A state pattern is a very specific thing. It is a design pattern consisting of directed graph of states and transitions based on a finite state machine.


You start at the starting state and progress through directed transitions (sometimes called edges) to other states until you reach an end state. In your case, you would have a list of conversation nodes. Each node would have 1 or more edges leading to 1 or more other states.

If you want edges more complex than a simple multiple choice menu, yes you will have to either enable some kind of scripting or hardcode those edges.

http://en.wikipedia.org/wiki/Finite-state_machine
Logged
Take me out to the black, tell them I ain't comin' back...
I don't care cause I'm still free, you can't take the sky from me...

I turned myself into a monster, to fight against the monsters of the world.

kaijyuu

  • Bay Watcher
  • Hrm...
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2494 on: June 06, 2012, 05:45:51 pm »

It's weird hearing technical terms for stuff I've been using forever. Patterns? Edges? I never even thought those things ever had names, and I only know the term "state machine" from a summer game development workshop I took back in high school.

Fun stuff. I'm going to drown in a real programming class despite knowing the methods just because I don't know the terminology. This fall/spring's gonna be interesting.
Logged
Quote from: Chesterton
For, in order that men should resist injustice, something more is necessary than that they should think injustice unpleasant. They must think injustice absurd; above all, they must think it startling. They must retain the violence of a virgin astonishment. When the pessimist looks at any infamy, it is to him, after all, only a repetition of the infamy of existence. But the optimist sees injustice as something discordant and unexpected, and it stings him into action.

Nadaka

  • Bay Watcher
    • View Profile
    • http://www.nadaka.us
Re: if self.isCoder(): post() #Programming Thread
« Reply #2495 on: June 06, 2012, 05:56:01 pm »

They don't teach you the terminology in "programming classes". They teach it in the design, theory and computer math classes starting in year 2 after you take the intro programming class, calculus and the standard collection of classes you must take for any university degree.
Logged
Take me out to the black, tell them I ain't comin' back...
I don't care cause I'm still free, you can't take the sky from me...

I turned myself into a monster, to fight against the monsters of the world.

Virex

  • Bay Watcher
  • Subjects interest attracted. Annalyses pending...
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2496 on: June 06, 2012, 06:13:46 pm »

Thanks for the advice, kaijyuu! I'll probably be going the simple text document route at this point, and just have an escape character to tell when I'm giving a command rather than dialogue. That's really all I'll need, I think.
Gatleos: You probably want to create a state pattern, rather than a raw tree.
That was my other problem; I realized that just making a tree for the dialogue would bloat things tremendously. I need a way to have the same dialogue choices show up in different places without re-defining them for every conversation state where they appear, so I guess a state pattern would be the best thing here. Just a way to add or remove dialogue choices based on whatever variables I put in there. At least, I think that's what you mean.

The only problem is, I have no idea how I would go about doing that. I've never used a state pattern since, like I said, I've never coded something with huge conditional trees that I had to define manually.
Why not use a directed graph? Though, I guess the suggested state pattern would be one implementation of a graph. Another way is to implement it like a tree, but without the restriction that nodes can only have one parent.
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2497 on: June 06, 2012, 09:25:17 pm »

Does anyone know what is wrong with this code? It's supposed to find whether a number is prime or not. It's from a book on C++ programming, so I would assume it would work.
Spoiler (click to show/hide)

The error I'm getting is:
Spoiler (click to show/hide)

Ninja'd. I was working on including this before you posted. It's supposed to find out if a given number is prime or not.

Well, you're trying to compare an int to sqrt(int). There's actually two issues there. The first one is, an int can be implicitly cast to all three of those types, double, long double, and float. You'll need to explicitly cast it to one when you pass the parameter (probably double).

Example: sqrt(double(n))

The second issue is that you're trying to compare an integer to an floating-point value. Since you only care about primality for integers, you can cast the result of sqrt to an integer type. It will be truncated, giving you the results you need.

Rewrite: while(i <= int(sqrt(double(n))))

Alternatively, the following will also work and is a bit nicer:

while(i*i <= n)

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2498 on: June 07, 2012, 08:34:24 pm »

By request, here is another installment to my C++ tutorial.

Lesson 2: Learning Conditionals and Variables with a Calculator

As per my usual format, I'm going to post some code, and then discuss the language features it utilizes. This is going to be a fairly simple program: a 4-function calculator that reads a command in two steps. The first step will read in the command for the function, and the second step will read in the 2 numbers that are to be applied to that function. For simplicity, this program will only deal with integer values. If you give it something other than an integer value, it will get mad and throw a chair at you and steal your lunch money. So, don't do it.

Code: (calc.cpp) [Select]
#include <iostream>
#include <string>

using namespace std;

int main() {
while(true) {
cout << "Enter the function you wish to use (add, sub, mul, or div): ";
string function;
cin >> function;
cout << endl;

int a, b;
cin >> a >> b;
if(function == "add") {
cout << a << " + " << b << " = " << a+b << endl;
}
else if(function == "sub") {
cout << a << " - " << b << " = " << a-b << endl;
}
else if(function == "mul") {
cout << a << " * " << b << " = " << a*b << endl;
}
else if(function == "div") {
cout << a << " / " << b << " = " << a/b << endl;
}
else {
cout << "That is not a valid option." << endl;
}

cout << endl;
}
return 0;
}

If you're a beginner with no knowledge other than what you learned in Lesson 1, you're probably staring at this code, wondering what magic I just used. Well, do not worry, because I'm about to teach you. It's time to learn some spells.

Piece 1: Including and Using
Code: [Select]
#include <iostream>
#include <string>

using namespace std;

Like in Lesson 1, we're including the iostream header and telling the compiler we want to use the standard namespace. But, this time, we're also including the string header! It lets us do cool things like work with strings (who would have guessed?), which are defined as sequences of characters.

Well, that exposition isn't very helpful without a basic knowledge of data types in C++, so let's get that out of the way. C++ has 8 (or 9; more on that later) data types that are called primitive data types. They are called primitive because they are defined by the compiler, and don't need any external libraries to use them. Those 8 are, in order of size: bool, char, short, int, long, float, double, and long double. In addition, there are two special modifiers that apply exclusively to these data types, signed and unsigned. Signed means that the data type can represent negative values, while unsigned means it cannot. So, now for some definitions:

Spoiler: Definitions (click to show/hide)

At this point, many of you are probably asking your monitors, "What about strings? Didn't you say something about them earlier? Where do they fit in?" Well, string is another data type, but it is not a primitive data type. Instead, we refer to string as being a class. A class is like a primitive data type in many ways, but has extra abilities. It's like a super data type. In the world of C++, primitive data types are normal people, going about their everyday lives, while classes are the superheroes (and super-villains, in some cases!), with their special abilities. That's silly, I know. But, it is a nice way to think about it for right now.

Alright, now that we know enough about data types for the moment, let's (finally) go back to the code.

Piece 2: The Main Function
Code: [Select]
int main() {

Yep, nothing new here. We're defining the main function, which runs when the program is run. Woohoo.

Piece 3: Introducing Flow Control, Part 1
Code: [Select]
while(true) {

Spoiler (click to show/hide)

Relax. This is pretty simple. The while-statement you see above is a type of loop. A loop is a block of code that executes multiple times, until a certain condition is reached. A while-statement does three things. First, it evaluates the expression in the parentheses to a boolean value. Second, if the expression evaluates to true, it makes the code between the following open-curly-brace and its matching close-curly-brace execute. Third, it repeats the first two steps until the expression evaluates to false.

Now take a close look at we have in the parentheses. Yes, that's right. The expression is simply 'true', which, of course, always evaluates to true. So, that means...

Spoiler (click to show/hide)

Stop that. Yes, the code between the braces will execute indefinitely, until the program is stopped. This is called an infinite loop. Most programming teachers will tell you that infinite loops are bad. I would agree for several situations. However, there are many, many situations where an infinite loop is exactly what we need. Why do we want our code running forever? Well, we want to be able to accept input to the calculator as long as the user is willing to give input. And, as we'll see, the program won't actually run forever. There are ways to break out of an infinite loop.

Piece 4: Printing Stuff to Standard Output
Code: [Select]
cout << "Enter the function you wish to use (add, sub, mul, or div): ";

Just like in Lesson 1, we're printing a string (ahahaha! strings!) to standard output. However, this time, we're not outputting a newline (endl), because we want the input to be on the same line as the output.

Piece 5: Accepting User Input
Code: [Select]
string function;
cin >> function;
cout << endl;

int a, b;
cin >> a >> b;

First, we're declaring a string named function (don't get confused here). Nothing too fancy. Next, we tell cin (a stream like cout, but an input stream instead) to put what it's holding into function. Well, what exactly is it holding? User input, that's what. Whatever the user types into the program gets put into cin. When the user presses Enter, the program stops reading the input and puts the line (without the newline inserted by pressing Enter) into function. So, now, function contains what the user typed in. Then, we output a newline, because we want our next output to be on the next line after the current one. Next, we declare two ints, named a and b, and take values given by the user and store them in the two ints. Because values are given to a and b from cin in the same statement, the program takes two numbers separated by a space (or any number of spaces) as input, and correctly stores them in a and b. How can it do that? Magic.

Piece 6: Introducing Flow Control, Part 2
Code: [Select]
if(function == "add") {
cout << a << " + " << b << " = " << a+b << endl;
}
else if(function == "sub") {
cout << a << " - " << b << " = " << a-b << endl;
}
else if(function == "mul") {
cout << a << " * " << b << " = " << a*b << endl;
}
else if(function == "div") {
cout << a << " / " << b << " = " << a/b << endl;
}
else {
cout << "That is not a valid option." << endl;
}

Here, we get introduced to what is known as conditional branching. Simply put, it means the program evaluates an expression to a boolean, and does something if it is true, or does something else if it is false. Conditional branching is a type of conditional statement, and is done using if-, else, and else-if-statements. An if-statement looks similar to a while-statement, and works similarly, too. The expression in parentheses is evaluated, and the code inside the curly braces is executed if the expression evaluates to true. Unlike a while-statement, an if-statement only executes the code once. An else-statement can follow an if-statement, and the code between the curly braces is executed if the expression in the if-statement evaluates to false. Finally, there are else-if-statements, which are really just else-statements that contain if-statements. It should be fairly easy to see what they do. Conditional statements and loops make up the portion of language features called flow control, because they allow you to control what your program does in different situations.

So, the code uses conditional branching to decide what to output. Next, let's look at the output itself. We see more compound statements, with the multiple data objects being put into cout. We saw earlier that, through compound statements, cin (as well as all other input streams) can make multiple data objects out of one source. Now, we see that cout (as well as all other output streams) can take multiple data objects and make one output. The reason it can do this is too complicated to explain fully at this point, but it deals with the data objects having certain properties that allow streams to do this. All primitive data types, as well as the string class, have these properties.

One thing we notice in the output code is the use of +, -, *, and / to calculate a sum, difference, product, and quotient, respectively. These are called operators, and these 4 are defined for use with all primitive data types, and can (in most cases) work with two different primitive data types. Operators will be a whole lesson in itself, because C++ provides some very neat things that you can do with operators.

Piece 7: The End
Code: [Select]
}
return 0;
}

First off, we have the close-curly-brace from the while-statement, way back in Piece 3. Next, we have our standard "return 0;". Finally, we have the close-curly-brace from the main function definition. Nothing much to say here.

Remember how I mentioned that you could break an infinite loop? Well, I'm about to teach you how. If you have something running in a console (Windows) or terminal (Linux/UNIX/Mac), you can use a key combination to kill the program, making it end immediately. In Windows, Linux, and UNIX, this key combination is Ctrl-C. For Mac, I'm not 100% sure (I don't own a Mac), but I believe it is Command-C.

Conclusion

We have make much progress in C++, but there is still much I have to teach you. I have left a lot of things unexplained (or said they were magic), but, as I said before, I will eventually go back and cover those details. Instead of considering what you don't know, let's look at what you do.

  • You know how to use #include to add standard headers to your program.
  • You know how to use the "using" directive to tell the compiler you want to use things defined in standard headers.
  • You know how to define a main function.
  • You know how to use cin and cout.
  • You know about primitive integral data types and how to use them.
  • You know a little bit about the string class, as far as using it for input and output.
  • You know how to use while loops.
  • You know how to use if-, else-, and else-if-statements for conditional branching.

Homework

The dreaded part of every lesson, homework! Don't worry, it's not too difficult. You have two assignments:

1. Play around with conditionals, loops, and primitive data types.
2. Learn why primitive data types have limitations on how large the ranges of values they can hold are.



I was feeling a bit silly, and I got a PM from a reader of this thread asking when I was going to do the next lesson in my tutorial, so the result is this silly-ish lesson. Again, if there's anything I didn't explain clearly enough and didn't attribute it to magic, ask me, and I'll explain it.

dreadmullet

  • Bay Watcher
  • Inadequate Comedian
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2499 on: June 07, 2012, 11:03:29 pm »

Excellent tutorial!

One thing I don't understand (I've done suprising little with C++ strings) is this:

Code: [Select]
if(function == "add")
I thought you had to do
Code: [Select]
if(function.compare(add) == 0)or else it wouldn't work.
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2500 on: June 07, 2012, 11:17:07 pm »

Excellent tutorial!

One thing I don't understand (I've done suprising little with C++ strings) is this:

Code: [Select]
if(function == "add")
I thought you had to do
Code: [Select]
if(function.compare(add) == 0)or else it wouldn't work.

That works, too (if you add quotes around add). The equivalence operator (==) is overloaded for strings, comparing the actual strings. It essentially does just that.


More information about string comparison operators here.

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2501 on: June 08, 2012, 02:18:19 am »

I thought you had to do
Code: [Select]
if(function.compare(add) == 0)or else it wouldn't work.
That is the Java way, where they didn't implement operator overloading because it might "confuse" people. Java is also a bad language, and yes, I have to mention that in every other post I make..
(Operator overloading means being able to re-interpret things like +, -, ==, >= etc with your own functions, so you can use those operators on your custom classes (And strings count as a custom class) ).
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

dreadmullet

  • Bay Watcher
  • Inadequate Comedian
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2502 on: June 08, 2012, 02:26:54 am »

Oh, Java, that must be where I heard it from; probably one of the programming threads on here. Also, with my forgetting the quotation marks, you can tell I rely on my F7 key too much...
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2503 on: June 08, 2012, 07:13:31 am »

Oh, Java, that must be where I heard it from; probably one of the programming threads on here. Also, with my forgetting the quotation marks, you can tell I rely on my F7 key too much...

Yeah, with Java, you'd use String.equals or String.compareTo for that, since the equivalence operator only ever checks memory value of the reference for objects. Or, at least, it's supposed to. Stargrasper investigated this and a lot of other stuff with Strings earlier in the thread. You can find his post in the OP, linked as "Wtf Java".

Mini

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #2504 on: June 08, 2012, 09:29:12 am »

stuff
A couple of things I don't like about what you've written there:

1) You defined things used in every loop iteration inside the loop, I have no data or references to back this up but to me it makes sense that defining them inside the loop means the memory for them needs to be reallocated every time, making the program overall slower (very slightly in this case, but still).

2) You used a while(true) when one wasn't needed. I do understand that it was for the tutorial (showing breaks and all that), but you didn't mention that you can put cin >> variable statements in whiles and have the loop stop when the input has finished, either because you're using a file for input (with pipes) or because you used the character for it (I can't remember what combination causes it, however), instead of just looping forever. Useful if you want to get all input before doing any processing on it, for example. And you could have shown boolean operators, but you'll probably do that in the operators tutorial. So I guess this is a null point?
Logged
Pages: 1 ... 165 166 [167] 168 169 ... 795