Learning C/C++ - Tutorial

Discussion in 'Programming & Scripting' started by Fallen, Jun 14, 2012.

  1. Fallen

    Fallen Freelancer

    Joined:
    Aug 21, 2009
    Messages:
    3,714
    Likes Received:
    260
    Best Answers:
    0
    After years of studying how OpenTibia works and how the community look like, I finally decided to write tutorials on how to code and understand the structure of OpenTibia
    using C NOT C++. Since there's not many people over here who know how to edit source code or fix a simple bug themselves (This tutorial does not explain that ofcourse, but
    it should give you a start on how to). I used C because it's a good start to programming.

    Programming in C (basics)- Part 1.
    After reading this tutorial, you'll be able to create simple console programs that's like any other console program (i.e get output/input from a user, etc.).

    Some QA anyone would like to know before learning (Psuedo-code-like):
    Q: How does a C program look like?
    A: a simple C program would like this:
    Code (C++):
    1. // A Comment.
    2. /* a
    3. multi
    4. line
    5. comment
    6. */
    7. include "somefile.h"
    8. int main() {
    9.     // ...
    10.     return 0;
    11. }
    Q: How do I compile a C program?
    A: By downloading any C/C++ IDE (i.e DEV-C++, Code::Blocks, etc.) or if you prefer using command line, download MinGW. (protip: stick to IDEs for now if youre not using linux)
    Please read Evan's post, he wrote a nice tutorial on how to get started with Microsoft Visual C++ which is the best IDE for C++ : Learning C/C++ - Tutorial

    Now, let's begin:
    A simple console program to start with
    Code (C++):
    1. #include <stdio.h>
    2. int main() {
    3.     printf("Hello world!\n");
    4.     return 0;
    5. }
    Explanation of each line of the previous program:
    Code (C++):
    1. #include <stdio.h>
    This line tells the compiler that we'll be using the functions from the file "stdio.h" which is input/output library in C.
    Code (C++):
    1. int main()
    A C program contains functions and variables. This is the main function of our program (basically the overall logic of the program), if this function is not found, the program will fail to compile, ofcourse there are command line parameter's passed but I don't want to make it complicated yet.
    Code (C++):
    1. {
    This is a paranthesis, it's important to have opening paranthesis at every start of a function.
    Code (C++):
    1. printf("Hello world!\n");
    This function is from the included file "stdio.h" prints out "Hello world!" to our console. the \n prints out new line.
    Code (C++):
    1. return 0;
    Exits the program with code 0.
    Code (C++):
    1. }
    Function paranthesis end.

    Now, that was a good start how to create a simple console program that outputs stuff on console, yes you can call this function many times and test it out ;-)
    Variables
    A variable is just a named area of storage that can hold a single value (numeric or character). The C language demands that you declare the name of each variable that you are going to use and its type, or class, before you actually try to do anything with it.
    NOTE: the variable name is case-sensitive, that means, i is NOT the same as I, and k is NOT the same as K.
    Psuedo code example:
    data_type var_name;


    Data Types
    Code (C++):
    1. int (integer numbers) -> int i = 5;
    2. float (floating point numbers) -> float f = 5.0;
    3. double (big floating numbers) -> double d = 500000000;
    4. char (character) -> char c = 'c';
    Every data type of the has have modifiers which are: short, long, signed, unsigned. The modifier defines the storage allocated to the variable:
    Ranges:
    Code (C++):
    1. Type      ->  from    -> to
    2. short int ->  -32,768 -> +32,767
    3. unsigned short int -> 0 -> +65,535
    4. unsigned int -> 0 -> +4,294,967,295
    5. int -> -2,147,483,648 -> +2,147,483,647
    6. long int -> -2,147,483,648 -> +2,147,483,647
    7.  
    8. signed char -> -128 -> +127
    9. unsigned char -> 0 -> +255
    10. float ->
    11. double ->
    12. long double ->
    13.  
    Every data type of the above has qualifier(s) which is const (constant), const can be written in many ways i.e:
    Code (C++):
    1. const int i = 5;
    2. int const i = 5;
    The const qualifier tells the compiler that the variable will NOT be modified after the initialization, that means you cannot do:
    i = 10;

    Functions in C
    Full functions explanation, how to make your own function and make use of it.

    A Psuedo function would look like:
    Code (C++):
    1. data_type function_name(parameter1, parameter2)
    2. {
    3.     function_body, you write stuff here.
    4. }
    A real function would look like:
    Code (C++):
    1. int add(int first, int second)
    2. {
    3.     int _add = first + second;
    4.     return _add;
    5. }
    A function has a return value depends on what data type it uses, for example, a function declared with datatype int, then it must return int or the compiler will complain.

    Using the function you've made in the main routine (calling it!):
    Code (C++):
    1. #include <stdio.h>
    2. int add(int first, int second)
    3. {
    4.     return first + second;
    5. }
    6.  
    7. int main()
    8. {
    9.     int a = add(5, 6); // a now is 11.
    10.     printf("Adding 5 to 6: %d\n", a); // Try reading documentation of these C library functions to understand how exactly they work ;-)
    11.     return 0;
    12. }
    Operators in C
    C Operators are (That's not everything, just what you need for now!):

    Comparison operators/relational operators
    Code (C++):
    1. a == b -> if a is equal to b.
    2. a != b -> if a is not equal to b.
    3. a > b -> if a is greater than b.
    4. a < b -> if a is smaller than b.
    5. a >= b -> if a is greater than or equal to b.
    6. a <= b -> if a is smaller than or equal to b.
    Arithmetic operators:
    Code (C++):
    1. a =[/color] b -> basic assignment.
    2. ++a -> increment a
    3. --a -> decrement a
    4. a + b -> add
    5. a - b -> substract
    Compound assignment operators:
    Code (C++):
    1. a +=[/color]b -> same as a = a + b;
    2. a -= b -> same as a = a - b;
    3. a *= b -> same as a = a * b;
    4. a /= b -> same as a = a / b;
    Pointers and Strings in C
    First i'm going to discuss what a pointer is, as a string depends on pointers.
    Pointer is 2 things:
    1. Reference:
    A reference is represented by the (&) operator.
    Say we have the following psuedo code:
    Code (C++):
    1. first = &second;
    "first" now is the address of "second" that means we are no longer talking about the content of "first" itself but about its reference,
    (i.e, it's address in memory) - Don't worry if you don't understand yet.
    2. Dereference:
    A dereference is represented by the (*) operator.
    Say we have the following psuedo code:
    Code (C++):
    1. second = *first;
    And say we have the following real code:
    Code (C++):
    1. int a;
    2. int *deref;
    3.  
    4. deref = &a; // store the address of a in a deref pointer.
    5. *deref = 1; // a = 1; how? we stored the address before in the dereference pointer.
    6. printf("a = %d\n", a); // outputs "a = 1"
    Yet again, don't worry if you don't understand it fully.

    Strings in C:
    A String type-name is "char". I explained before in the data types:
    char c = 'c'; // that's only a single char! not a full string.
    To assign a single character, you must use: ' and not " just like what I did above.
    To assign a string, you must use " and not '.
    A String in C looks like this:
    Code (C++):
    1. char *string = "hello world"; // able to reassign it
    can also be const:
    Code (C++):
    1. const char *string = "hello world"; // cannot be re-assigned
    For more information on strings, see: C Tutorial - Strings and Text Handling

    Using the "if", "else if", "else", "for", "do", "break", "continue", "switch", and "while"
    The "if", "else", and "else if" statements:
    Let's see some psuedo-code:
    Code (C++):
    1. if (I didnt write this tutorial) {
    2.     some people wouldnt know how to do their own programs.
    3. }
    Real code:
    Code (C++):
    1. int main() {
    2. int num = 2;
    3. if (num == 1) {
    4.     // false!
    5. } else if (num == 0) {
    6.     // false!
    7. } else {
    8.     // true.
    9. }
    10. return 0;
    11. }
    The "for", "do", "while", and "while" statements;
    These statements are used for looping with conditions.
    Let's see examples:

    The for loop:
    Code (C++):
    1. int main() {
    2.     int i;
    3.     for (i = 0; i < 5; i++) { // increment i by 1, each time it loops.
    4.     printf("i now is: %d\n", i);
    5.     }
    6.  
    7.     // let's try something else to do with i:
    8.     for (i = 0; i < 100; i += 10) { // increment i by 10 each time it loops.
    9.         printf("i now is: %d\n", i);
    10.     }
    11.  
    12.     // set i's value to 100, and check everytime it loops if i reached 0 as well as decrease i by 10 each time.
    13.     for (i = 100; i == 0; i -= 10) {
    14.         printf("i now is: %d\n", i);
    15.     }
    16.     return 0;
    17. }
    Basically the for loop psuedo would look like this:
    Code (C++):
    1. for (start value; condition; increase/decrease value) {
    2.     // do work
    3. }
    an infinite loop would look like this:
    Code (C++):
    1. for (;;) {
    2.     // do work
    3. }
    The while loop:
    Code (C++):
    1. int main() {
    2.     int i = 100;
    3.     while (i > 0) {
    4.         --i;
    5.         printf("i now is: %d\n", i);
    6.     }
    7.  
    8.     i = 100; // reassign i, since we changed it in the previous loop!
    9.     int j = 200;
    10.     while (j > i) {
    11.         ++i;
    12.         printf("i: %d, j: %d\n", i, j);
    13.     }
    14.  
    15.     return 0;
    16. }
    Basically the while loop psuedo would look like this:
    Code (C++):
    1. while (condition) {
    2.     // code.
    3. }
    an infinite loop would look like this:
    Code (C++):
    1. while (1) {
    2.     // code.
    3. }
    The do-while loop:
    Code (C++):
    1. int main() {
    2.     int i = 0;
    3.     do {
    4.         ++i;
    5.         printf("i now is: %d\n", i);
    6.     } while (i < 100);
    7. }
    The break and continue statements:
    Code (C++):
    1. int main() {
    2.     int i;
    3.     for (i = 0; i < 20; ++i) {
    4.         if (i == 19) {
    5.             break; // break loop here, makes it not continue anymore.
    6.         } else if (i == 17) {
    7.             ++i; // increment i
    8.             continue; // stop it here and then re-run the loop, so i now is 19 because we incremented it manually and the loop will do the same aswell.
    9.         }
    10.  
    11.         // here we write some useless stuff that will be excuted if i < 17 and < 19.
    12.         printf("i is: %d\n", i);
    13.     }
    14. }
    The switch statement:
    Code (C++):
    1. int main() {
    2.     int i = 5;
    3.  
    4.     switch (i) {
    5.     case 1:
    6.         printf("i is 1.");
    7.         break;
    8.     case 2:
    9.         printf("i is 2.");
    10.         break;
    11.     default:
    12.         printf("i is not 1 or 2.");
    13.         break;
    14.     }
    15.     return 0;
    16. }
    Basically the switch statement psuedo would look like this:
    Code (C++):
    1. switch (variable) {
    2.     incase var is 1:
    3.         // do work.
    4.         break;
    5.     default: // var is not any of the cases above.
    6.         // do work.
    7.         break;
    8. }
    Getting input from user in a C program.
    Using the function scanf is the best way for C beginners to get inputted stuff from user, Let's see an example:
    Code (C++):
    1. #include <stdio.h>
    2. int main() {
    3.     int input = 0;
    4.  
    5.     // loop until the user has guessed the right number which is 5.
    6.     while (input != 5) {
    7.         printf("Write a random number between 1 and 10: ");
    8.         scanf("%d", &input);
    9.         printf("\n"); // write a newline to seperate text written on console.  printf does not write it by default.
    10.     }
    11.  
    12.     printf("You guessed it right!\n");
    13.     return 0;
    14. }
    Logical Operators
    In order to learn how logical operations work, have a look at these tables:
    Considering A and B are inputs and out is the output:

    1. operator AND (&)
    A B out
    1 1 1
    0 1 0
    1 0 0
    0 0 0

    That may have looked alittle weird, but to make it simple the AND operator is more like a multiplication operation.
    Example usage in C or C++:
    Code (C++):
    1.  
    2. int i = 1;
    3. printf("%d\n", i & 0); // 0
    2. operator OR (|):

    A B out
    1 1 1
    0 1 1
    1 0 1
    0 0 0

    Therefore, operator OR loves ones, so whenever it finds a 1 it steals it.
    Example usage:
    Code (C++):
    1.  
    2. int i = 1;
    3. printf("%d\n", i | 0); // 1
    4.  
    Some excersies to do based on what you have learned:
    Excersie 1: Write a program that asks the user for his name, age, city, etc. and output them on console!
    Excersie 2: Write a program that asks the user for your 5 favourite drinks (coca-cola, beer, ...), note that he must write his choice by entering a number between 1 and 5.
    If your program uses if statements, try and use switch.
    Modify your program so that if the user enters a choice other than 1 and 5 then it will output some error.
    Excersie 3: Write a program that asks the user the numbers he want to calculate & using what operation (+, -, /, *, ...) - can be done with switch statements and characters.

    I am open to questions and suggestions. Everyone is welcome to post his opinion.
     
    nevix, Wirless, _Arthur and 4 others like this.
  2. Cykotitan

    Cykotitan Experienced G'

    Joined:
    Nov 4, 2008
    Messages:
    16,897
    Likes Received:
    809
    Best Answers:
    1
    Can't wait for the next part :p ! :p
     
    lord5 likes this.
  3. Fallen

    Fallen Freelancer

    Joined:
    Aug 21, 2009
    Messages:
    3,714
    Likes Received:
    260
    Best Answers:
    0
    Learning C/C++ - Tutorial (Advanced) - Part 2

    Programming in C (advanced) - Part 2.

    Note: Try to read the comments I make on my example codes, they're useful ;-)
    Contents:
    1. Data Structures
    2. Using Preprecessors
    3. Data Structure arrays (using data types)
    4. Creating own data type (using typedef)
    5. String-plays, tips & tricks
    6. Getting familiar with C Standard library (opening files, creating files, etc.)

    1. Data Structures
    A data structure is an arrangement of data in a computer's memory or even disk storage. An example of several common data structures are arrays, linked lists, queues, stacks, binary trees, and hash tables.
    A data structure is used in C by the keyword "struct", ex:
    [cpp]struct mydata {
    // data...
    }[/cpp]

    Assuming you have read and understood the basics of C, let's check out an example of storing data in your structure named "person":
    Code (C++):
    1. struct person {
    2.     int age;
    3.     char *name;
    4.     char *city;
    5. };
    Using your structure in a real code would be something like this:
    Code (C++):
    1. // define our structure
    2. struct person {
    3.     int age;
    4.     char *name;
    5.     char *city;
    6. };
    7.  
    8. int main() {
    9.     struct person axel; // creating new person
    10.     // asign data to it:
    11.     // the "." operator is a new one here, we use it for setting/getting values in a data structure, like this:
    12.     axel.age = 16;
    13.     axel.name = strdup("Axel");
    14.     axel.city = strdup("Some city");
    15.  
    16.     printf("age: %d, name: %s, city: %s\n", axel.age, axel.name, axel.city); // "age: 16, name: Axel, city: Some city"
    17.     return 0;
    18. }
    Using structure with a dereferencing operator "*" as described in the previous tutorial.
    Code (C++):
    1. #include <stdlib> // new header! this header allows us to allocate memory to our structure, so that the pointer can be valid.
    2. #include <stdio.h>
    3. #include <string.h>
    4. // define out structure
    5. struct person {
    6.     int age;
    7.     char *name;
    8.     char *city;
    9. };
    10.  
    11. int main() {
    12.     struct person *axel;
    13.     axel = (struct person *)malloc(sizeof(struct person)); // Read more about malloc by hovering on the function!
    14.  
    15.     // the "->" operator is a new one here, we use it for setting/getting values in a data structure, like this:
    16.     axel->age = 16;
    17.     axel->name = strdup("Axel");
    18.     axel->city = strdup("Some city");
    19.  
    20.     printf("age: %d, name: %s, city: %s\n", axel->age, axel->name, axel->city); // "age: 16, name: Axel, city: Some city"
    21.     return 0;
    22. }
    2. Using preprecessors
    Preprecessors in C begin with "#" and are: #define, #if, #ifdef, #endif, #ifndef, #if !defined, #pragma, etc (I believe there are more but I don't remember any at the moment as they're not used alot)

    #if and #ifdef must always end with #endif, i.e:

    The following code checks if the linker has TESTING_DIRECTIVES = 1
    Code (C++):
    1. #if TESTING_DIRECTIVES
    2. #define USING_DIRECTIVES 1 // constant value.
    3. #endif
    The following code checks if the linker has TESTING_DIRECTIVES defined, doesn't matter what it's value is:
    Code (C++):
    1. #ifdef TESTING_DIRECTIVES
    2. #define USING_DIRECTIVES // constant value.
    3. #endif
    Checking if the linker has something undefined is by simply using #ifndef (which is if not defined or #if !defined(VARIABLE)). i.e:
    Code (C++):
    1. #ifndef CROX_H
    2. #define CROX_H
    3. // ...
    4. #endif
    or:
    Code (C++):
    1. #if !defined(CROX_H)
    2. #define CROX_H
    3. // ...
    4. #endif
    using #pragma:
    Code (C++):
    1. #pragma message("Hai there") // Outputs "hai there" during compilation.
    Using #define - the most effecient way
    #define can be used for defining constant values and also defining constant functions
    Some examples:

    The following code defines "some_value" as an integer constant that cannot be edited later on:
    Code (C++):
    1. #define some_value 15
    The following code defines a function:
    Code (C++):
    1. #define add(x, y, z)    x + y + z;
    The following code defines usage of strings in a define macro:
    Code (C++):
    1. #define output(string)    puts(##string);
    The following code defines how to get variable name in a define macro:
    Code (C++):
    1. #define get_var_name(var)    #var;
    Still don't get it? Let's see a real example:
    Code (C++):
    1. #include <stdio.h>
    2.  
    3. #define getVarNamePassed(var)    #var
    4. #define DEBUG_PRINT(msg)    puts("Debug: "); puts(##msg)
    5.  
    6. #ifndef USE_SOME_LIB
    7. #define NO_LIB
    8. #endif
    9.  
    10. void _(const char *variable) { DEBUG_PRINT(getVarNamePassed(variable)); }
    11.  
    12. int main() {
    13. #ifdef _WIN32 // builtin variable defined for windows.
    14.     DEBUG_PRINT("Windowsfag detected");
    15. #elif defined(__APPLE__) // builtin variable defined for OS X
    16.     DEBUG_PRINT("Youre using OS X");
    17. #else
    18.     DEBUG_PRINT("Youre using linux");
    19. #endif
    20.  
    21. #ifdef NO_LIB
    22.     DEBUG_PRINT("Not using lib X");
    23. #endif
    24.     _("ha");
    25.     return 0;
    26. }
    3. Data Structure arrays (using data types)
    A Data array is declared like this:
    type_name variable_name[array_size_is_int];

    Let's have a look at a real example:
    Code (C++):
    1. #include <stdio.h>
    2.  
    3. int main() {
    4.     char names[10];
    5.     // Let's assign some values to our array "names".
    6.     // Syntax is:
    7.     // array[index] = key;
    8.     // Samething as LUA but here index starts at 0 and not 1.
    9.     names[0] = "Fallen";
    10.     names[1] = "Talaturen";
    11.     names[2] = "Three Magic";
    12.     names[3] = "Cykotitan";
    13.     names[4] = "Chojrak";
    14.     names[5] = "Korrex";
    15.     names[6] = "NewCFag";
    16.     names[7] = "Someone";
    17.     names[8] = "Hello.png";
    18.  
    19.    
    20.     int i = 0;
    21.     for (/* exclude the i = 0; since we already initialised it, just put a semicolon */; i < 8; ++i)
    22.         puts(names[I]);
    23.  
    24.     int numbers[5];
    25.     numbers[0] = 1;
    26.     numbers[1] = 2;
    27.     numbers[2] = 3;
    28.     numbers[3] = 4;
    29.     numbers[4] = 5;
    30.  
    31.     i = 0; // reset i's value.
    32.     for (; i < 5; ++i)
    33.         printf("%d\n", i);
    34.  
    35.     return 0;
    36. }
    [/I]
    4. Creating own data type (using typedef)
    Creating own data types is very easy. The syntax of typedef is:
    typedef existing_type_name new_type_name_of_your_choice;

    In C, typedef is mostly used for structures, just to shorten the name from using it, i.e:
    instead of:
    Code (C++):
    1. struct data d;
    you do:
    Code (C++):
    1. typedef struct data data;
    2. data d;
    A real example for using typedef would be:
    Code (C++):
    1. typedef unsigned int u_int;
    So instead of typing such a long typename, "unsigned int var;", you do: "u_int var;".

    5. String-plays, tips & tricks
    Now for some tips and tricks with strings, playing around with strings is very easy and fun at the same time. Let's get to code!

    The following code replaces all the spaces in a string with an empty char:
    Code (C++):
    1. #include <stdio.h>
    2. #include <ctype.h>
    3.  
    4. int main() {
    5.     char *str = "hello, my nick name is fall en";
    6.     char *tmp = str;
    7.     char *tmp1 = str;
    8.     tmp = str;
    9.  
    10.     puts(str);
    11.     while (*tmp) { // loop each character in the string and search for spaces.
    12.         // you can also use "if (*str == 'c') { where 'c' is the character, in this situation ' ' and ','.
    13.         if (ispunct(*tmp) || isspace(*tmp)) // punct/space?
    14.             ++tmp;
    15.         else
    16.             *tmp1++ = *tmp++;
    17.     }
    18.  
    19.     *tmp1 = 0;
    20.     puts(str);
    21. }
    Will be adding more as soon as I come up with some ideas ;-)

    6. Getting familiar with C Standard library (opening files, creating files, etc.)
    C Standard library has very good & useful libraries, i.e time, IO (input/output) etc. Read more here: The C Standard Library
    In this section, I'll explain how to use important functions and how to make a good use of them.

    Code (C++):
    1. #include <assert.h>
    assert(expr):
    Assert performs a check on the expression expr, if debug mode is enabled, the program immediately exits with a message like "Asseration failed <expression>, file: somefile.c, line: 10".

    Ex:
    Code (C++):
    1. assert(pointer != NULL);
    Code (C++):
    1. #include <signal.h>
    signal(signal_name, handler)
    signal is a very useful function. Usage of the function:
    * Handling segmentation faults
    * Handling abnormal termination
    and alot more that are not used alot.

    Usage in real code:
    Code (C++):
    1. #include <signal.h>
    2. #include <stdio.h>
    3.  
    4. void handler(int sig)
    5. {
    6.     puts("Seg fault received.");
    7.     // handle it here.
    8. }
    9.  
    10. int main() {
    11.     // try some bugged code that raises a seg fault (can use raise(SIGSEGV) aswell for testing)
    12.     struct buggedstruct { int x; };
    13.     struct buggedstruct *unallocated;
    14.  
    15.     // setup signal.
    16.     if (signal(SIGSEGV, handler) == SIG_ERR)
    17.         puts("Failed to setup signal SIGSEGV!");
    18.  
    19.     unallocated->x = 5; // "Seg fault received".
    20.     return 0;
    21. }
    Code (C++):
    1. #include <stdarg.h>
    void va_start(va_list ap, ...);
    void va_end(va_list ap);

    This library is useful for making your own string formatter function, like printf() from stdio.h and such

    Code (C++):
    1. #include <stdarg.h>
    2. #include <stdio.h>
    3.  
    4. void strformat(const char *format, ...) {
    5.     va_list arg;
    6.     va_start(arg, format);
    7.     char buffer[1024]; // random size, try and make an exact size ;-)
    8.     vsprintf(buffer, format, arg);
    9.     va_end(arg);
    10. }
    11.  
    12. int main() {
    13.     char *str[1024]; // random size, try and make an exact size ;-)
    14.     strformat("Hi, this is a %s string, learn how to format %s", "Test", "String");
    15.     puts(str);
    16.     return 0;
    17. }
    tip: go and read more about the "%" stuff in strings.

    Code (C++):
    1. #include <stdio.h>
    Now for the input/output header library. I'll explain the important parts you should know only.
    FILE *fopen(const char *filename, const char *mode)
    filename: string, file name to open.
    mode: i.e, read only ("r"), write only ("w"), etc...


    int fclose(FILE *stream);
    close and free memory of "stream"


    int fprintf(FILE *stream, const char *format, ...);
    int rename(const char *oldname, const char *newname);
    int remove(const char *filename);
    size_t fread(void *ptr, size_t size, size_t nobj, FILE *stream); binary reading.
    char *fgets(char *s, int n, FILE *stream);


    Usage:
    Code (C++):
    1. #include <stdio.h>
    2.  
    3. int main() {
    4.     FILE *f;
    5.     char buffer[1024];
    6.  
    7.     f = fopen("file.txt", "r");
    8.     if (!f)
    9.         // failed to open file, handle error.
    10.  
    11.     while (fgets(buffer, sizeof(buffer), f))
    12.         // read new stuff, parse it.
    13.  
    14.     // close file (free memory)
    15.     fclose(f);
    16.     return 0;
    17. }
    Code (C++):
    1. #include <errno.h>
    Useful for errors (error numbers).
    Tip: Have a look at "strerror(int errno)" in string.h for error strings.
    Tip: Have a look at "perror()" in stdio.h for printing out error strings with custom messsages.

    Code (C++):
    1. #include <string.h>
    Now this is the most useful header library after stdio.h to study, it's too long to explain here! read a documentation instead.

    Code (C++):
    1. #include <stdlib.h>
    One more useful library file, for allocating memory etc. Too long to explain aswell.
     
    lord5 likes this.
  4. Fallen

    Fallen Freelancer

    Joined:
    Aug 21, 2009
    Messages:
    3,714
    Likes Received:
    260
    Best Answers:
    0
    Learning C/C++ - Tutorial (Advanced-the beginning of understanding OpenTibia) Part 3.

    Sorry if the title is confusing, couldn't post the full name because it's too long. I hope someone can make use of the set of tutorials i'm making... Here goes part 3 of the tutorial:

    Programming in C and C++ (Advanced - the beginning of understanding OpenTibia codes)- Part 3.

    Contents:
    1. C/C++ - Header files. how do they work?
    2. C/C++ - Switching from C to C++ (Types difference, declarations, defintions)
    3. C/C++ - Main function parameters
    4. C/C++ - The type qualifer: volatile
    5: C++ - New type name: bool
    6. C++ - classes
    7. C++ - STD
    8. C++ - STL
    9. C++ - Own operators
    10. C++ - Subclassing abstract classes and re-defining virtual functions.
    11. C++ - The meaning of a static variable/function.
    12: C++ - templates
    13. C++ - Exceptions
    14. C++ - iterators
    15. A Brief idea of how OT code work (we'll be using TFS).

    1. C/C++ - Header files. how do they work?
    C/C++ headers suffix usually is ".h" or ".hpp", using header files is pretty simple process, all you do there is declare stuff and then define them in the source file.
    Simple header file declaration:

    myheader.h:
    Code (C++):
    1. #ifndef MYHEADER_H
    2. #define MYHEADER_H
    3.  
    4. // define a data structure.
    5. typedef struct m_struct {
    6.     int index;
    7.     char *str;
    8. } MyStruct;
    9.  
    10. extern void setIndex(MyStruct *s, int index);
    11. extern void setString(MyStruct *s, char *str);
    12.  
    13. int index(MyStruct *s);
    14. char *string(MyStruct *s);
    15. #endif // MYHEADER_H
    mysource.c:
    Code (C++):
    1. #include "myheader.h"
    2. #include <string.h> // strdup()
    3.  
    4. void setIndex(MyStruct *s, int index) {
    5.     if (!s)
    6.         return;
    7.  
    8.     s->index = index;
    9. }
    10.  
    11. void setString(MyStruct *s, char *str) {
    12.     if (!s)
    13.         return;
    14.  
    15.     s->str = strdup(str);
    16. }
    17.  
    18. int index(MyStruct *s) {
    19.     if (!s)
    20.         return -1;
    21.  
    22.     return s->index;
    23. }
    24.  
    25. char *string(MyStruct *s) {
    26.     if (!s)
    27.         return -1;
    28.  
    29.     return s->string;
    30. }
    main.c:
    Code (C++):
    1. #include "myheader.h"
    2. #include <stdio.h>
    3. #include <stdlib.h>
    4.  
    5. int main() {
    6.     MyStruct *s = (MyStruct *)malloc(sizeof(MyStruct));
    7.     setIndex(s, 1);
    8.     setString(s, "hello world");
    9.  
    10.     // do some stuff ;)
    11.     return 0;
    12. }
    2. C/C++ - Switching from C to C++ (Types difference, declarations, defintions)
    Switching from C to C++ is an easy process, they're both same thing but ill be explaining the difference.

    3. C/C++ - Main function parameters
    Have you ever wondered how a program like apt-get on linux parses the command line parameters passed to it? Well, here goes, this is how but ofcourse not the same thing, just
    an example on how it works, do the rest yourself! There are also another way of parsing command line parameters but stick with this one for now! ;-)

    myprogram.c:
    Code (C++):
    1. #include <stdio.h>
    2. #include <string.h>
    3.  
    4. int main(int argc, char **argv)
    5. {
    6.     // argc -> argument count
    7.     // argv -> argument values (char array).
    8.  
    9.     if (argc > 1) { // the user has passed other parameters than the program name, confused? The operating system automatically sends the program name to the command line parameters
    10.         // say we want to get the program name:
    11.         printf("%s: You've passed an argument to the command line!", argv[0]);
    12.  
    13.         // Now, let's parse the arguments the user has passed, we'll be accepting "-install" and "-uninstall" for now.
    14.         for (int i = 1/* 1 for escaping program name!*/; i < argc; ++i) {
    15.             char *currentArgument = argv[I];
    16.             if (!currentArgument) {
    17.                 puts("currentArgument == NULL");
    18.                 return 1;
    19.             }
    20.  
    21.             if (strcmp(currentArgument, "-install") == 0) {
    22.                 char *programToBeInstalled = (argc >= i+1 ? argv[i+1] : NULL);
    23.             } else if (strcmp(currentArgument, "-uninstall") == 0) {
    24.                 char *programToBeUnInstalled = (argc >= i+1 ? argv[i+1] : NULL);
    25.             } else {
    26.                 printf("Invalid argument passed!  Accepting only -install and -uninstall, what you passed is: %s", currentArgument);
    27.                 return 1;
    28.             }
    29.         }
    30.     }
    31.  
    32.     return 0;
    33. }
    That's it.[/I]
    4. C/C++ - The type qualifer: volatile
    Soon to come, I find no use for it now.

    5: C++ - New type name: bool
    Before i've explained what a type name in C is, there's a new one in C++ called boolean, a boolean type name can only be "true" or "false".
    i.e:
    Code (C++):
    1. bool _bool = true;
    2. if (_bool) {
    3.     // success
    4. }

    6. C++ - classes
    Classes in C++ is a long thing to discuss, I'll try to explain it as short and clear as possible.

    Classes in C++ are like struct in C, but classes in C++ allow you to make the function either private/protected (not accessiable outside the class) or public (accessible outside).
    The word "this" in C++ classes refer to the class itself, a pointer in the class, that can only be used inside the class functions.
    A C++ Class consists of a constructor, destructor, public/private/protected functions:
    1. Can have multiple constructors but only 1 destructor
    2. Can have no constructor and no destructor.
    3. A constructor can be private or public.
    4. Destructor must be public.
    5. using delete on the class with no destructor should throw an errow (As far as I remember correctly).

    An example how a C++ class would look like:
    Code (C++):
    1. class Person {
    2. public:
    3.     // multiple constructor example
    4.     Person(int age);
    5.     Person(char *name);
    6.     Person(char *city);
    7.  
    8.     // Just 1.
    9.     Person(int age, char *name, char *city);
    10.  
    11.     // Destructor.
    12.     ~Person();
    13.  
    14.     // example of some public functions.
    15.     int age() const;
    16.     char *name() const;
    17.     char *city() const;
    18.  
    19.     void setAge(int age);
    20.     void setName(char *name);
    21.     void setCity(char *city);
    22.  
    23. private: // private members
    24.     int m_age;
    25.     char *m_name, *m_city;
    26. };
    27.  
    28. // definition of a class.
    29. Person::person(int age)
    30.     : m_age(age)
    31. {}
    32.  
    33. Person::person(char *name)
    34.     : m_name(name)
    35. {}
    36.  
    37. Person::person(char *city)
    38.     : m_city(city)
    39. {}
    40.  
    41. Person::person(int age, char *name, char *city)
    42.     : m_age(age),
    43.       m_name(name),
    44.       m_city(city)
    45. {}
    46.  
    47. int Person::age() const
    48. {
    49.     return m_age;
    50. }
    51.  
    52. char *Person::name() const
    53. {
    54.     return m_name;
    55. }
    56.  
    57. char *Person::city() const
    58. {
    59.     return m_city;
    60. }
    61.  
    62. void Person::setAge(int age)
    63. {
    64.     m_age = age;
    65. }
    66.  
    67. void Person::setName(char *name)
    68. {
    69.     m_name = name;
    70. ]
    71.  
    72. void Person::setCity(char *city)
    73. {
    74.     m_city = city;
    75. }
    Simple, isn't it?
    7. C++ - STD
    C++ Standard Library consists, of alot of stuff (converted from C Standard library to fit with the C++ style), i.e: C time.h, C stdio.h, to include them:
    Code (C++):
    1. #include <c(standard c lib)>
    i.e:
    Code (C++):
    1. #include <cstdio>
    Also has the C++ string, easier to use than C strings, class name is apart of the C++ standard namespace which is (std). Let's check it out an example of how C++ strings work:
    Code (C++):
    1. #include <string>
    2.  
    3. int main() {
    4.     std::string str = "hello world";
    5.     // can also be declared like this:
    6.     std::string str;
    7.     str = "hello world";
    8. }
    C++ STD also has it's own IO (Input/output) Library, which provides us useful, easier to use functions for outputting/inputting stuff to/from the console. (the header file is iostream).
    Let's see an example for output stream:
    Code (C++):
    1. #include <iostream> // C++ STD input output.
    2. #include <string> // C++ STD string.
    3.  
    4. int main() {
    5.     std::cout << "Hello world!"; // print out "Hello world!"
    6.     // using C++ STD strings:
    7.     std::string str = "Hello world!";
    8.     std::cout << str;
    9.     return 0;
    10. }
    for input stream:
    Code (C++):
    1. #include <iostream>
    2. #include <string>
    3.  
    4. int main() {
    5.     std::string inputstring;
    6.     std::cout << "Enter your name: ";
    7.     std::cin >> inputString; // std::cin is the function for inputting! note the operator >> aswell!
    8.     std::cout << "Hello, " << inputString;
    9.     return 0;
    10. }
    The Normal C++ String does not support an operator to concat integers to it by default. But the C++ STD library provides us a class called "stringstream". A stringstream
    is a class for strings to put stuff into it (including strings, integers, floats, doubles, etc...).
    Example:
    Code (C++):
    1. #include <sstream> // stringstream.
    2. #include <string>
    3. #include <iostream>
    4.  
    5. int main() {
    6.     std::stringstream stringsteam;
    7.  
    8.     // Let's put some numbers into the stream and output it to console.
    9.     stringstream << "Hello world " << 1 << " " << 2 << " "<< 3 << " " << 4 << " " << 5;
    10.     std::cout << stringstream.str(); // -> "Hello world 1 2 3 4 5".
    11.  
    12.     // You can also make a new c++ string and assign the data of stringstream to it:
    13.     std::string str;
    14.     stringstream >> str;
    15.     // str = "Hello world 1 2 3 4 5"
    16.     return 0;
    17. }

    That's all for now.

    8. C++ - STL
    I'll be explaining only STL containers (vector, map, hashmap, hash, set, stack, list, bitset, ...) and not STL algorithms for now.
    Let's start off with vector (
    Code (C++):
    1. #include <vector>
    ): Vector is a template class for creating data storage instead of using C style structures, read more at:
    vector - C++ Reference (functions etc.)

    Initialising a C++ vector:
    Code (C++):
    1. std::vector<type_name> my_vector;
    A vector is stored like this:
    Code (C++):
    1. type_name vec[] = {
    2.     stuff
    3. };
    Real example:
    Code (C++):
    1. #include <vector>
    2. #include <iostream>
    3.  
    4. int main() {
    5.     std::vector vec<int> position(3);
    6.     // assign some integers to it.
    7.     position[0] = 1000; position[1] = 1024; position[3] = 8;
    8.  
    9.     // output the values of the vector.
    10.     for (int i = 0; i < position.size(); ++i)
    11.         std::cout << position; // -> 1000, 1024, 8
    12.  
    13.     return 0;
    14. }
    --
    C++ Map (
    Code (C++):
    1. #include <map>
    ):
    Init a C++ map:
    Code (C++):
    1. std::map<typename_key, typename_value>
    Example:
    Code (C++):
    1. #include <map>
    2. #include <iostream>
    3.  
    4. int main() {
    5.     std::map<int, int> positionMap;
    6.  
    7.     for (int x = 0; x < 100; ++x) {
    8.         for (int y = 0; y < 200; ++y)
    9.             positionMap.insert(std::make_pair(x, y));
    10.     }
    11.  
    12.     // iterating through the map.
    13.     for (std::map<int, int>::const_iterator it = positionMap.begin();
    14.             it != positionMap.end(); ++it) {
    15.         // output values.
    16.         std::cout << "x: " << (*it).first() << " y: " << (*it).second();
    17.     }
    18.  
    19.     return 0;
    20. }
    More to come soon.
    9. C++ - Own operators
    Making own class operators or editing an existing class operator. for example let's edit the "<<" operator std::cout to output some typename that is not builtin or supported by
    STD IO.

    Syntax of outter-class operator is:
    Code (C++):
    1. typename operator[actual operator here](typename varname, newtype var);
    Real example:
    Code (C++):
    1. std::eek:stream &operator<<(std::eek:stream &os, const MyPosition &p);
    Assuming MyPosition is a class like this:
    Code (C++):
    1. class MyPosition {
    2. public:
    3.     MyPosition(int x, int y, int z)
    4.         : _x(x), _y(y), _z(z)
    5.     {}
    6.     // no destructor.
    7.  
    8.     int x() const { return _x; }
    9.     int y() const { return _y; }
    10.     int z() const { return _z; }
    11.  
    12. private:
    13.     int _x, _y, _z;
    14. };
    Now for the operator definition body:
    Code (C++):
    1. std::eek:stream &operator<<(std::eek:stream &os, const MyPosition &p) {
    2.     os << "[x: " << p.x() << ", y: " << p.y() << ", z: " << p.z() << "]";
    3.     os << std::endl; // new line! in STD.
    4.     return os;
    5. }
    Usage of our new operator:
    Code (C++):
    1. #include <iostream>
    2.  
    3. // definition of our operator goes here.
    4. int main() {
    5.     MyPosition pos(100, 200, 7);
    6.     std::cout << pos; // -> [x: 100, y: 200, z: 7]
    7.     return 0;
    8. }
    Try make your own, if it doesn't work, have a look at mine and compare:
    Code (C++):
    1. #include <iostream>
    2.  
    3. class MyPosition {
    4. public:
    5.     MyPosition(int x, int y, int z)
    6.         : _x(x), _y(y), _z(z)
    7.     {}
    8.     // no destructor.
    9.  
    10.     int x() const { return _x; }
    11.     int y() const { return _y; }
    12.     int z() const { return _z; }
    13.  
    14. private:
    15.     int _x, _y, _z;
    16. };
    17.  
    18. std::eek:stream &operator<<(std::eek:stream &os, const MyPosition &p) {
    19.     os << "[x: " << p.x() << ", y: " << p.y() << ", z: " << p.z() << "]";
    20.     os << std::endl; // new line! in STD.
    21.     return os;
    22. }
    23.  
    24. int main() {
    25.     const MyPosition pos(100, 200, 7);
    26.     std::cout << pos; // -> [x: 100, y: 200, z: 7]
    27.     return 0;
    28. }
    --
    Making an operator for your own class
    Code (C++):
    1. class Point2D {
    2. public:
    3.     Point2D(int x, int y)
    4.         : _x(x), _y(y)
    5.     { }
    6.  
    7.     // copy-constructor.
    8.     // so it can be used like this:
    9.     // Point2D point(1, 1);
    10.     // Point2D anotherPoint(point)
    11.     Point2D(const Point2D &p) {
    12.         operator=(p); // calls the operator.
    13.     }
    14.  
    15.     // no need for destructor.
    16.  
    17.     int x() const { return _x; }
    18.     int y() const { return _y; }
    19.  
    20.     // operator =
    21.     // usage:
    22.     // Point2D point(1, 1);
    23.     // Point2D anotherPoint(2, 2);
    24.     // point = anotherPoint; // point = {2, 2}
    25.     Point2D &operator=(const Point2D &p) {
    26.         _x = p.x();
    27.         _y = p.y();
    28.  
    29.         return *this;
    30.     }
    31.  
    32. private:
    33.     int _x, _y;
    34. };
    35.  
    36. // create a simple addition operator:
    37. static Point2D operator+(const Point2D &p1, const Point2D &p2) { return Point2D(p1.x() + p2.x(), p1.y() + p2.y()); }
    Try making your own stuff, if it doesn't work compare it to my code:
    Code (C++):
    1. #include <iostream>
    2.  
    3. class Point2D {
    4. public:
    5.     Point2D(int x, int y)
    6.         : _x(x), _y(y)
    7.     { }
    8.  
    9.     // copy-constructor.
    10.     // so it can be used like this:
    11.     // Point2D point(1, 1);
    12.     // Point2D anotherPoint(point)
    13.     Point2D(const Point2D &p) {
    14.         operator=(p); // calls the operator.
    15.     }
    16.  
    17.     // no need for destructor.
    18.  
    19.     int x() const { return _x; }
    20.     int y() const { return _y; }
    21.  
    22.     // operator =
    23.     // usage:
    24.     // Point2D point(1, 1);
    25.     // Point2D anotherPoint(2, 2);
    26.     // point = anotherPoint; // point = {2, 2}
    27.     Point2D &operator=(const Point2D &p) {
    28.         _x = p.x();
    29.         _y = p.y();
    30.  
    31.         return *this;
    32.     }
    33.  
    34. private:
    35.     int _x, _y;
    36. };
    37.  
    38. // outside class operator.
    39. static Point2D operator+(const Point2D &p1, const Point2D &p2) { return Point2D(p1.x() + p2.x(), p1.y() + p2.y()); }
    40.  
    41. std::eek:stream &operator<<(std::eek:stream &os, const Point2D &p) {
    42.     os << "[x: " << p.x() << ", y: " << p.y() << "]";
    43.     os << std::endl; // new line! in STD.
    44.     return os;
    45. }
    46.  
    47. int main() {
    48.     Point2D p1(100, 200);
    49.     p1 = p1 + Point2D(100, 200); // add to it another {100, 200} point.
    50.     // overall result: {200, 400}.
    51.  
    52.     std::cout << "[operator+]" << p1;
    53.  
    54.     // using copy-constructor.
    55.     Point2D p2(p1); // p2 is now a copy of p1.
    56.     std::cout << "[copy-constructor]p2 now is: " << p2;
    57.  
    58.     // using operator =
    59.     Point2D p3 = p2; // p3 is now a copy of p2 which is a copy of p1.
    60.     std::cout << "[internal-operator=]p3 now is: " << p3;
    61.     return 0;
    62. }
    10. C++ - Subclassing abstract classes and re-defining virtual functions.
    Coming soon.
    11. C++ - The meaning of a static variable/function.
    Coming soon.
    12: C++ - templates
    Coming soon.
    13. C++ - Exceptions
    Coming soon.
    14. C++ - iterators
    Coming soon.
    15. A Brief idea of how OT code work (we'll be using TFS).
    Coming soon.
     
  5. NilssoN

    NilssoN ¯\(º o)/¯

    Joined:
    Jun 15, 2007
    Messages:
    1,464
    Likes Received:
    4
    Best Answers:
    0
    Good jobb folen :)
     
  6. Fallen

    Fallen Freelancer

    Joined:
    Aug 21, 2009
    Messages:
    3,714
    Likes Received:
    260
    Best Answers:
    0
  7. Znote

    Znote <?php echo $title; ?> Staff Member Global Moderator Premium User

    Joined:
    Feb 14, 2008
    Messages:
    6,201
    Likes Received:
    933
    Best Answers:
    106
    great tutorials! :D
     
  8. SpiderOT

    SpiderOT ™ツʂριԃҽɾσƚ➽ ٩(•‿•)۶★彡

    Joined:
    Sep 29, 2008
    Messages:
    985
    Likes Received:
    80
    Best Answers:
    1
    Best tutorial
    thanks for your effort :D
     
  9. Three Magic

    Three Magic u aint shit

    Joined:
    Aug 25, 2009
    Messages:
    8,633
    Likes Received:
    496
    Best Answers:
    0
    Gonna learn from this :)

    I'll repost in 10 years time and let you know how great your tutorial was <3
     
    Xinax likes this.
  10. Three Magic

    Three Magic u aint shit

    Joined:
    Aug 25, 2009
    Messages:
    8,633
    Likes Received:
    496
    Best Answers:
    0
    after many fucking fails
    and alot of help from fallen
    i created this simple shit
    from dust
    yes, dust
    [​IMG]
     
  11. Three Magic

    Three Magic u aint shit

    Joined:
    Aug 25, 2009
    Messages:
    8,633
    Likes Received:
    496
    Best Answers:
    0
    Exercise 2 complete;
    [​IMG]
     
  12. Fallen

    Fallen Freelancer

    Joined:
    Aug 21, 2009
    Messages:
    3,714
    Likes Received:
    260
    Best Answers:
    0
    Bomping this up, 440 views and few replies?! only Three Magic has interest in learning?!!!!

    P.S: If you encourage an english mistake or some error in code, let me know, I written this when semi-sleepy (bored basically)!
     
  13. Korrex

    Korrex Well-Known Member

    Joined:
    Jan 19, 2008
    Messages:
    2,749
    Likes Received:
    116
    Best Answers:
    0
    Have interest, but too lazy. T_T
     
  14. Jetro

    Jetro jangeldev

    Joined:
    Aug 1, 2011
    Messages:
    452
    Likes Received:
    67
    Best Answers:
    0
    Really nice tutorial, thanks for sharing with us :$
    btw what mean these compound assignment operators: "|=", "&="?
     
  15. Fallen

    Fallen Freelancer

    Joined:
    Aug 21, 2009
    Messages:
    3,714
    Likes Received:
    260
    Best Answers:
    0
    I'm 100% sure I haven't explained how those work yet (note that the tutorial is incomplete, more to come later)
     
  16. Ninja

    Ninja 「Speedwagon Foundation」 Staff Member Global Moderator

    Joined:
    Apr 6, 2010
    Messages:
    5,887
    Likes Received:
    1,488
    Best Answers:
    15
    I'm looking forward to learn, great contribution Fallen! :)
     
  17. Chuck88

    Chuck88 Member

    Joined:
    Nov 3, 2011
    Messages:
    107
    Likes Received:
    10
    Best Answers:
    0
    Great tutorials!
     
  18. HalfAway

    HalfAway Well-Known Member

    Joined:
    Sep 3, 2011
    Messages:
    3,538
    Likes Received:
    2,286
    Best Answers:
    15
    Really nice!
    Thanks! :D
     
  19. Evan

    Evan A splendid one to behold Premium User

    Joined:
    May 6, 2009
    Messages:
    7,011
    Likes Received:
    923
    Best Answers:
    0
    I'm well experienced, I just don't have any interest in using C++ in OpenTibia.

    Here's something I made a very very long time ago:

    main code:
    Code (Text):
    1. #include <stdio.h>
    2. #include <iostream>
    3. #include "gameMazeTestHeader.h"
    4. #include <Windows.h>
    5. using namespace std;
    6.  
    7. void printMap(int readMap[15][15], int mapValue)
    8. {
    9.     for (int x = 0; x < 15; x++)
    10.     {
    11.         for (int y = 0; y < 15; y++)
    12.         {
    13.             if (readMap[x][y] == 1) // MOUNTAIN
    14.             {
    15.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), DARKGREY);
    16.                 cout << "#";
    17.             }
    18.             else if (readMap[x][y] == 0) // WALKABLE SPACE
    19.             {
    20.                 cout << " ";
    21.             }
    22.             else if (readMap[x][y] == 3) // TREE
    23.             {
    24.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), GREEN);
    25.                 cout << "^";
    26.             }
    27.             else if (readMap[x][y] == 4) // CHEST
    28.             {
    29.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CYAN);
    30.                 cout << "+";
    31.             }
    32.             else if (readMap[x][y] == 5) // EMPTY CHEST
    33.             {
    34.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CYAN);
    35.                 cout << "-";
    36.             }
    37.             else if (readMap[x][y] == 2) // DOOR
    38.             {
    39.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CYAN);
    40.                 cout << "|";
    41.             }
    42.             else if (readMap[x][y] == 9) // USER
    43.             {
    44.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
    45.                 cout << "&";
    46.                 posStoreY = y;
    47.                 posStoreX = x;
    48.             }
    49.         }
    50.         cout << endl;
    51.     }
    52.     cout << endl << "X: " << posStoreY << ", Y: " << posStoreX << " ON MAP: " << mapValue << endl;
    53. }
    54.  
    55. void movePlayer(int direction, int readMap[15][15], int &prePosX, int &prePosY)
    56. {
    57.     switch (direction)
    58.     {
    59.     case UP:
    60.         {
    61.             // UP -------------------------------------------------------
    62.             if (readMap[prePosX - 1][prePosY] == 2)
    63.             {
    64.                 if (keyValue == 1000)
    65.                 {
    66.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    67.                     cout << "You see:" << endl;
    68.                     readMap[prePosX][prePosY] = 0;
    69.                     mapValue = 2;
    70.                 }
    71.                 else
    72.                 {
    73.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTRED);
    74.                     cout << "You see: LOCKED DOOR" << endl;
    75.                     return;
    76.                 }
    77.             }
    78.             else if (readMap[prePosX - 1][prePosY] == 1 || readMap[prePosX - 1][prePosY] == 3 || readMap[prePosX - 1][prePosY] == 4
    79.                 || readMap[prePosX - 1][prePosY] == 5)
    80.             {
    81.                 if (readMap[prePosX - 1][prePosY] == 3)
    82.                 {
    83.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    84.                     cout << "You see: TREE" << endl;
    85.                     return;
    86.                 }
    87.                 else if (readMap[prePosX - 1][prePosY] == 4)
    88.                 {
    89.                     readMap[prePosX - 1][prePosY] = 5;
    90.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), GREEN);
    91.                     cout << "You see: CHEST [you found a key]" << endl;
    92.                     keyValue = 1000;
    93.                     return;
    94.                 }
    95.                 else if (readMap[prePosX - 1][prePosY] == 5)
    96.                 {
    97.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTRED);
    98.                     cout << "You see: EMPTY CHEST" << endl;
    99.                     return;
    100.                 }
    101.                 else
    102.                 {
    103.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    104.                     cout << "You see:" << endl;
    105.                     return;
    106.                 }
    107.             }
    108.             else
    109.             {
    110.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    111.                 cout << "You see:" << endl;
    112.                 readMap[prePosX][prePosY] = 0;
    113.                 prePosX -= 1;
    114.                 readMap[prePosX][prePosY] = 9;
    115.             }
    116.             break;
    117.         }
    118.     case DOWN:
    119.         {
    120.             // DOWN -------------------------------------------------------
    121.             if (readMap[prePosX + 1][prePosY] == 2)
    122.             {
    123.                 if (keyValue == 1000)
    124.                 {
    125.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    126.                     cout << "You see:" << endl;
    127.                     readMap[prePosX][prePosY] = 0;
    128.                     mapValue = 2;
    129.                 }
    130.                 else
    131.                 {
    132.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTRED);
    133.                     cout << "You see: LOCKED DOOR" << endl;
    134.                     return;
    135.                 }
    136.             }
    137.             else if (readMap[prePosX + 1][prePosY] == 1 || readMap[prePosX + 1][prePosY] == 3 || readMap[prePosX + 1][prePosY] == 4
    138.                 || readMap[prePosX + 1][prePosY] == 5)
    139.             {
    140.                 if (readMap[prePosX + 1][prePosY] == 3)
    141.                 {
    142.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    143.                     cout << "You see: TREE" << endl;
    144.                     return;
    145.                 }
    146.                 else if (readMap[prePosX + 1][prePosY] == 4)
    147.                 {
    148.                     readMap[prePosX + 1][prePosY] = 5;
    149.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), GREEN);
    150.                     cout << "You see: CHEST [you found a key]" << endl;
    151.                     keyValue = 1000;
    152.                     return;
    153.                 }
    154.                 else if (readMap[prePosX + 1][prePosY] == 5)
    155.                 {
    156.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTRED);
    157.                     cout << "You see: EMPTY CHEST" << endl;
    158.                     return;
    159.                 }
    160.                 else
    161.                 {
    162.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    163.                     cout << "You see:" << endl;
    164.                     return;
    165.                 }
    166.             }
    167.             else
    168.             {
    169.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    170.                 cout << "You see:" << endl;
    171.                 readMap[prePosX][prePosY] = 0;
    172.                 prePosX += 1;
    173.                 readMap[prePosX][prePosY] = 9;
    174.             }
    175.             break;
    176.         }
    177.     case RIGHT:
    178.         {
    179.             // RIGHT -------------------------------------------------------
    180.             if (readMap[prePosX][prePosY + 1] == 2)
    181.             {
    182.                 if (keyValue == 1000)
    183.                 {
    184.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    185.                     cout << "You see:" << endl;
    186.                     readMap[prePosX][prePosY] = 0;
    187.                     mapValue = 2;
    188.                 }
    189.                 else
    190.                 {
    191.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTRED);
    192.                     cout << "You see: LOCKED DOOR" << endl;
    193.                     return;
    194.                 }
    195.             }
    196.             else if (readMap[prePosX][prePosY + 1] == 1 || readMap[prePosX][prePosY + 1] == 3 || readMap[prePosX][prePosY + 1] == 4
    197.                 || readMap[prePosX][prePosY + 1] == 5)
    198.             {
    199.                 if (readMap[prePosX][prePosY + 1] == 3)
    200.                 {
    201.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    202.                     cout << "You see: TREE" << endl;
    203.                     return;
    204.                 }
    205.                 else if (readMap[prePosX][prePosY + 1] == 4)
    206.                 {
    207.                     readMap[prePosX][prePosY + 1] = 5;
    208.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), GREEN);
    209.                     cout << "You see: CHEST [you found a key]" << endl;
    210.                     keyValue = 1000;
    211.                     return;
    212.                 }
    213.                 else if (readMap[prePosX][prePosY + 1] == 5)
    214.                 {
    215.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTRED);
    216.                     cout << "You see: EMPTY CHEST" << endl;
    217.                     return;
    218.                 }
    219.                 else
    220.                 {
    221.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    222.                     cout << "You see:" << endl;
    223.                     return;
    224.                 }
    225.             }
    226.             else
    227.             {
    228.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    229.                 cout << "You see:" << endl;
    230.                 readMap[prePosX][prePosY] = 0;
    231.                 prePosY += 1;
    232.                 readMap[prePosX][prePosY] = 9;
    233.             }
    234.             break;
    235.         }
    236.     case LEFT:
    237.         {
    238.             // LEFT -------------------------------------------------------
    239.             if (readMap[prePosX][prePosY - 1] == 2)
    240.             {
    241.                 if (keyValue == 1000)
    242.                 {
    243.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    244.                     cout << "You see:" << endl;
    245.                     readMap[prePosX][prePosY] = 0;
    246.                     mapValue = 2;
    247.                 }
    248.                 else
    249.                 {
    250.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTRED);
    251.                     cout << "You see: LOCKED DOOR" << endl;
    252.                     return;
    253.                 }
    254.             }
    255.             else if (readMap[prePosX][prePosY - 1] == 1 || readMap[prePosX][prePosY - 1] == 3 || readMap[prePosX][prePosY - 1] == 4
    256.                 || readMap[prePosX][prePosY - 1] == 5)
    257.             {
    258.                 if (readMap[prePosX][prePosY - 1] == 3)
    259.                 {
    260.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    261.                     cout << "You see: TREE" << endl;
    262.                     return;
    263.                 }
    264.                 else if (readMap[prePosX][prePosY - 1] == 4)
    265.                 {
    266.                     readMap[prePosX][prePosY - 1] = 5;
    267.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), GREEN);
    268.                     cout << "You see: CHEST [you found a key]" << endl;
    269.                     keyValue = 1000;
    270.                     return;
    271.                 }
    272.                 else if (readMap[prePosX][prePosY - 1] == 5)
    273.                 {
    274.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTRED);
    275.                     cout << "You see: EMPTY CHEST" << endl;
    276.                     return;
    277.                 }
    278.                 else
    279.                 {
    280.                     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    281.                     cout << "You see:" << endl;
    282.                     return;
    283.                 }
    284.             }
    285.             else
    286.             {
    287.                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), LIGHTGREY);
    288.                 cout << "You see:" << endl;
    289.                 readMap[prePosX][prePosY] = 0;
    290.                 prePosY -= 1;
    291.                 readMap[prePosX][prePosY] = 9;
    292.             }
    293.             break;
    294.         }
    295.     default:
    296.         {
    297.             return;
    298.         }
    299.         return;
    300.     }
    301. }
    302.  
    303. int main()
    304. {
    305.     map[a][b] = 9; // Set first location
    306.  
    307.     cout << "You see:" << endl;
    308.     printMap(map, mapValue);
    309.  
    310.     HANDLE OutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    311.     SMALL_RECT windowSize = {0, 0, 35, 20};
    312.     SetConsoleWindowInfo(OutHandle, TRUE, &windowSize);
    313.  
    314.     while(GetAsyncKeyState(VK_ESCAPE) == false)
    315.     {
    316.         if (GetAsyncKeyState(VK_UP))
    317.         {
    318.             if (mapValue == 1)
    319.             {
    320.                 system("CLS");
    321.                 movePlayer(UP, map, a, b);
    322.                 printMap(map, mapValue);
    323.                 Sleep(50);
    324.             }
    325.             else
    326.             {
    327.                 system("CLS");
    328.                 //map2[map2DoorLoc1][map2DoorLoc2] = 9;
    329.                 movePlayer(UP, map2, map2DoorLoc1, map2DoorLoc2);
    330.                 printMap(map2, mapValue);
    331.                 Sleep(50);
    332.             }
    333.         }
    334.         if (GetAsyncKeyState(VK_DOWN))
    335.         {
    336.             if (mapValue == 1)
    337.             {
    338.                 system("CLS");
    339.                 movePlayer(DOWN, map, a, b);
    340.                 printMap(map, mapValue);
    341.                 Sleep(50);
    342.             }
    343.             else
    344.             {
    345.                 system("CLS");
    346.                 //map2[map2DoorLoc1][map2DoorLoc2] = 9;
    347.                 movePlayer(DOWN, map2, map2DoorLoc1, map2DoorLoc2);
    348.                 printMap(map2, mapValue);
    349.                 Sleep(50);
    350.             }
    351.         }
    352.         if (GetAsyncKeyState(VK_RIGHT))
    353.         {
    354.             if (mapValue == 1)
    355.             {
    356.                 system("CLS");
    357.                 movePlayer(RIGHT, map, a, b);
    358.                 printMap(map, mapValue);
    359.                 Sleep(50);
    360.             }
    361.             else
    362.             {
    363.                 system("CLS");
    364.                 //map2[map2DoorLoc1][map2DoorLoc2] = 9;
    365.                 movePlayer(RIGHT, map2, map2DoorLoc1, map2DoorLoc2);
    366.                 printMap(map2, mapValue);
    367.                 Sleep(50);
    368.             }
    369.         }
    370.         if (GetAsyncKeyState(VK_LEFT))
    371.         {
    372.             if (mapValue == 1)
    373.             {
    374.                 system("CLS");
    375.                 movePlayer(LEFT, map, a, b);
    376.                 printMap(map, mapValue);
    377.                 Sleep(50);
    378.             }
    379.             else
    380.             {
    381.                 system("CLS");
    382.                 //map2[map2DoorLoc1][map2DoorLoc2] = 9;
    383.                 movePlayer(LEFT, map2, map2DoorLoc1, map2DoorLoc2);
    384.                 printMap(map2, mapValue);
    385.                 Sleep(50);
    386.             }
    387.         }
    388.     }
    389.     system("PAUSE");
    390. }
    .h addition:
    Code (Text):
    1. // This header file is used to store definitions
    2.  
    3. /* Map number definitions
    4. 0 = empty space (walkable)
    5. 1 = wall
    6. 2 = door
    7. 3 = tree
    8. 4 = chest
    9. 5 = empty chest
    10. 9 = player
    11. */
    12.  
    13. // Key value storage
    14. int keyValue = 0;
    15.  
    16. // Color definitions
    17. #define BLACK 0
    18. #define BLUE 1
    19. #define GREEN 2
    20. #define CYAN 3
    21. #define RED 4
    22. #define MAGENTA 5
    23. #define BROWN 6
    24. #define LIGHTGREY 7
    25. #define DARKGREY 8
    26. #define LIGHTBLUE 9
    27. #define LIGHTGREEN 10
    28. #define LIGHTCYAN 11
    29. #define LIGHTRED 12
    30. #define LIGHTMAGENTA 13
    31. #define YELLOW 14
    32. #define WHITE 15
    33. #define BLINK 128
    34.  
    35. // Direction definitions
    36. #define UP 0
    37. #define DOWN 1
    38. #define RIGHT 2
    39. #define LEFT 3
    40.  
    41. // Integer definitions
    42. int getX;
    43. int getY;
    44. int newX;
    45. int newY;
    46. int a = 12; // Beginning location
    47. int b = 1; // Beginning location
    48. int posStoreX;
    49. int posStoreY;
    50.  
    51. // Specified map door locations
    52. int mapValue = 1;
    53. int mapDoorLoc1 = 2;
    54. int mapDoorLoc2 = 13;
    55. int map2DoorLoc1 = 3;
    56. int map2DoorLoc2 = 13;
    57.  
    58. int map[15][15] = {
    59.     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
    60.     {1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1},
    61.     {1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 3, 0, 1},
    62.     {2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1},
    63.     {1, 0, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3, 0, 1},
    64.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1},
    65.     {1, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 3, 1},
    66.     {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1},
    67.     {1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    68.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
    69.     {1, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 1},
    70.     {1, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 3, 0, 1},
    71.     {1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1},
    72.     {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
    73.     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
    74. };
    75.  
    76. int map2[15][15] = {
    77.     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
    78.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    79.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    80.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    81.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    82.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    83.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    84.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    85.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    86.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    87.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    88.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    89.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    90.     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    91.     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
    92. };
    93.  
    [​IMG]

    NOTE: I made this a long time ago, I could make this code a lot simpler and faster
     
  20. Fallen

    Fallen Freelancer

    Joined:
    Aug 21, 2009
    Messages:
    3,714
    Likes Received:
    260
    Best Answers:
    0
    Well, TFS is written in C++ (actually most of Ot Projects, if you're up-to-date, Otclient, RME, etc.). I seen some Ot members over here who were trying to edit TFS's source code and were not able to, so I don't see why not make a "simplified" tutorial like this one to read? I mean there are alot of longass tutorials over the interwebs that explain stuff like this but alot longer. correct me if I'm wrong.
     

Share This Page

Loading...