Pointers, a brief view

Some weeks ago I was reading Pat Shaughnessy, Ruby Under a Microscope that is an excellent book about all the engineering behinds Ruby language, and when reading, sometimes I was feeling lost with myself when reading some C codes from Ruby implementation then I decided to stop reading the book and start a little review about C programming language because the last time that I wrote some C code that wasn’t on Arduino was ~3 years ago at my university. When I was at my first university, I clearly remember how some students feel lost and some students feel delighted with the theory and concept of pointers, and for me, it was fascinating.

In this post, I’ll try to explain in a simple and practical way all the theory behind C pointers, for on the next posts I write about topics like Static and Dynamic memory allocation and function pointers.

It’s easy to create programs impossible to read and alter if you don’t give the appropriate attention to the pointers that you’re creating.

This post talks about

  • What are pointers
  • How to use pointers
  • Strings and Arrays
  • Pass by reference and pass by value

The computer memory

To understand pointers correctly, first, we need to understand from a top-level view of how the computer memory works.

The computer memory is like an array, is a block of consecutively memory cells order by their addresses, that memory can be manipulated alone or in groups.

Computer Memory

When you create an integer for example:

int counter = 0;

The C Lang picks 4 consecutive memory cells (bytes) from the memory and stores the value that you assigned to the variable.

Memory with integer allocated

And remember each memory cells that you requested to store your integer have a memory address that can be referenced by hexadecimal.

Address of allocated memory

This address will vary on each execution of the program.

To see this address of a variable in C we can use the ampersand operator:

int counter = 0;

printf("Variable Address: %p\n", &counter);
Variable Address: 0x7ffeccd5f0d4

The %p is the correct specifier to an output the memory address.

Another good experiment to do is to create two variables and see the address of each one:

int counter = 0;
int age = 0;


printf("Variable Address: %p\n", &counter);
printf("Variable Address: %p\n", &age);
Variable Address: 0x7ffe3606fd60
Variable Address: 0x7ffe3606fd64

Pay attention to how C allocates the variable age exactly 4 bytes after the first one, this is because the integer needs 4 bytes to be stored.

The memory address is very interesting and it would be good that we can store it at variables and make nice operations this, and that’s is what pointers consist.

Pointers

Follow my blog to get notified every new post:

Pointers in computer science is an object (usually a variable) that stores the memory address of another value. In C you can declare a pointer using an asterisk before the name of the variable and store an address of a variable of the same type of the pointer.

int counter = 0;

int *pointerCounter = &counter;

Note: Pointers always point to a specific data type, we have one exception on type void.

In C we can see the value stored at the address of pointed memory too, for this, use the asterisk before the name of the pointer:

printf("Pointer value of the pointed memory: %i\n", *pointerCounter);

When a pointer is pointing to a value, the pointer only stores the address of the first byte of this value, when asked, C uses the data type of the pointer to walk over the next `n` bytes to see the full pointed value.

For example, if we’re pointing to an integer and the first byte of this integer is located on 0x7ffe3bc5e164 (see the previus image), the pointer will only store the 0x7ffe3bc5e164 and when asked for the vallue will know to walk +4 right because integer is a datatype of 4 bytes.

To understand better, is nice to examine and run the fallowing example:

int counter = 10;
int *pointerCounter = &counter;

printf("Variable counter address: %p\n", &counter);

printf("Pointer value: %p\n", pointerCounter);

printf("Pointer address: %p\n", &pointerCounter);

printf("Pointer vale of the pointed memory: %i\n", *pointerCounter);
Variable counter address: 0x7ffe19cd26fc
Pointer value: 0x7ffe19cd26fc
Pointer address: 0x7ffe19cd2700
Pointer vale of the pointed memory: 10

It is nice to note that the address of a counter variable is exactly the value pointed by the pointer.

You can do arithmetic and logic operations with pointers too, on this example I sum 10 to the value pointed by pointerCounter.

int counter = 10;
int *pointerCounter = &counter;

*pointerCounter = *pointerCounter + 10;

printf("Pointer vale of the pointed memory: %i\n", *pointerCounter);

printf("Pointer vale of the pointed memory: %i\n", counter);
Pointer vale of the pointed memory: 20
Pointer vale of the pointed memory: 20

“Ok, this is so cool but what can I do with that? I’m only storing the address of some value into one kind of variable.”

With pointers we can do a lot of things, one of the main things is pass values by reference to functions.

Pass by reference and pass by value

When you pass a something to a function in C and make changes to it, that changes won’t exist outside of that function scope, what its means?

void sum(int counter, int age) {
    counter = counter + age;

    printf("counter value: %i\n", counter);
}

int main() {
    int counter = 10;
    int age = 5;

    sum(counter, age);

    printf("response value: %i\n", counter);
}
counter value: 15
response value: 10

On this example, we send the counter variable to the void function sum that stores at counter the sum of counter and age, after this, we print the value of counter inside the function an we see the value 15 printed, but on the printf outside the function at main, we got 10, why? This is what we call pass by value and C passes arguments to function by value, almost all languages pass by value (Java, C#, Ruby, Python), and there isn’t a direct way for the called function to alter a variable in the calling function.

Pass by value

But in C we can do what we call pass by reference, we call the function passing variable address and receiving as a pointer, doing this you’re saying to function “Hey, that’s the value memory address, pick this and alter as you want”.

Pass by reference

void sum(int *counter, int age) {
    *counter = *counter + age;

    printf("counter value: %i\n", *counter);
}

int main() {
    int counter = 10;
    int age = 5;

    sum(&counter, age);

    printf("response value: %i\n", counter);
}

If you run this code you’ll realize that on the last printf the counter is 15, that’s why we’ve passed the counter address to sum function, and at the function, we do the operation directly on the counter address on memory. This is what we call pass by reference, we aren’t passing the value to function but it’s a reference at the memory.

What’s next?

On this post we talked about all the basics behind pointers in C, it’s not a simple topic and if you don’t understand keep trying and run the examples of this post on your own machine, you can also read the sections 5.1 and 5.2 of the legendary K&R C Programming Language that’s, in my opinion, is the best book of ANSI C.

On next three posts I’ll talk more about pointers, I will write about pointers in arrays and strings, dynamic and static memory allocation and function pointers.

Feel free to ask any questions at my twitter, email or comment on this post.

Follow my blog to get notified every new post:

Simple Enemy AI System for Unity3D

In this post I am going to explain how I have developed a simple AI system for the enemies of my final project on technical college. The idea is a simple script that made the enemy’s walks randomly on the on the scene, chase and attack the player.

The IA script that I developed is based on several games, especially in stealth games. The enemy will select a random destination when the game is started and will walking in this direction when he comes close to the selected random destination, and another random destination is selected and it starts all the process again. If while he is walking toward a point he sees the player, he starts chasing the player and if he reaches the player, he is going to attack him.

For this example, I will use Unity 5 game engine but you can easily make changes and use it in other engines like Unreal.

I will not explain the basics features of Unity in this post or programming logic, If you have any questions please read the reference links or ask me here or on my Twitter.

1. Build Scene

For this example I have build a simple maze using 3D blocks and positioned the enemy(blue sphere) on the right top corner and our player on lower left corner (red sphere). Our player its a simple FPSController (You can find this script on Unity Standard Assets), read more [here].

2. Create Navigation Mesh

For our enemy walk on the scene the easiest method is create a navigation mesh on the scene and add a Nav Mesh Agent on the components of our enemy (3D sphere).

“The navigation system allows you to create characters that can intelligently move around the game world, using navigation meshes that are created automatically from your Scene geometry.“

Pay atention on your navigation mesh, it must be bypassing all walls, if not your enemy will not work correctly.

This simple step will make the next things easy.

3.Script

To start we need to declare and define our random destination using Random.range function and get navMeshAgent component. After this our code looks like this:

public int currentRandomPoint;
private NavMeshAgent navMesh;

void Start () {
    currentRandomPoint = Random.Range(
        0, 
        randomPoints.Length
    );
    navMesh = transform.GetComponent<NavMeshAgent>();
}

If you will use annimator component to use animations on the enemy you should declare and use on the void start too, like this:

protected Animator animator;

animator = GetComponent<Animator>();

On void update the first thing we need to do is calculate player distance and the random point distance, for this we use Vector3.

playerDist = Vector3.Distance(Player.transform.position, transform.position);
irandomPointDist = Vector3.Distance(randomPoints[currentRandomPoint].
transform.position, transform.position)

And declare a RaycastHit, this raycasthit will will ensure that our enemy does not see the player behind walls.

RaycastHit hit;

You can read about Physics.Raycast here.

if (Physics.Raycast (transform.position, direction, out hit, 1000) &&
playerDist < perceptionDistance ) {
  if (hit.collider.gameObject.CompareTag("Player")) {
    seeingPlayer = true;
  } else {
    seeingPlayer = false;
  }
}

And walk while our player distance is greater than perception distance.

if ( playerDist > perceptionDistance)
    walk();

And our walk method is basically set navMesh acceleration, speed and destination, like this:

void walk () {
  if (chasing == false) {
    navMesh.acceleration = 1;
    navMesh.speed = walkVelocity;
    navMesh.destination = randomPoints[currentRandomPoint].position;
  } else if (chasing == true) {
    chaseTime = true;
  }
}

And now with RaycastHit, player distance and random point distance our script is making something like this:

The orange dotted thick line it’s our script calculating the player distance, the blue dotted line it’s the random point distance and the green arrow is our RaycastHit.

And here the other 3 behaviors of our enemy:

void look () {
  navMesh.speed = 0;
  transform.LookAt (Player);
}

void chase () {
  navMesh.acceleration = 5;
  navMesh.speed = chaseVelocity;
  navMesh.destination = Player.position;
}

void attack () {
  navMesh.acceleration = 0;
  navMesh.speed = 0;
  attacking = true;
}

If you are working with animator and animations you can call your animator variables here, like this example:

animator.SetFloat("Speed", 0.5f);

The next steps is make a lot of checkings to attack, chase, stop chasing and all that stuffs, I will not going into details, but if you have doubts you can contact me as I told above.

Here’s the next checkings:

if ( playerDist <= perceptionDistance && playerDist > chaseDistance) {
  if (seeingPlayer == true)
    look();
  else
    walk();
}

if ( playerDist <= chaseDistance && playerDist > attackDistance) {
  if (seeingPlayer == true) {
    chase();
    chasing = true;
  } else {
    walk();
  }
}

if (playerDist <= attackDistance && seeingPlayer == true)
  attack();

if (randomPointDist <= 8) {
  currentRandomPoint = Random.Range(0, randomPoints.Length);
  walk();
}

if (chaseTime == true)
  chaseStopwatch += Time.deltaTime;

if (chaseStopwatch >= 5 && seeingPlayer == false) {
  chaseTime = false;
  chaseStopwatch = 0;
  chasing = false;
}

if (attacking == true)
  attackingStopwatch += Time.deltaTime;

And the attack checking:

if (attackingStopwatch >= attackTime && playerDist <= attackDistance) {
    attacking = true;
    attackingStopwatch = 0;
}

if (attackingStopwatch >= attackTime && playerDist > attackDistance) {
    attacking = false;
    attackingStopwatch = 0;
}

If you want to cause damage on player you should add something like this:

playerLife = playerLife - enemyDamage;

if (playerLife <= 5) {
  Application.LoadLevel(GameOverSceneName);
} else if (attackingStopwatch >= attackTime && playerDist > attackDistance) {
  attacking = false;
  attackingStopwatch = 0;
}

I really recommend your playerLife be a variable of an script of the player.

Finally, if you want that’s your player can attack the enemy you can add rigidBody component to your enemy and make this:

void OnCollisionEnter (Collision col) {

  if(col.transform.tag == "Bullet"){
    enemyLife -= 10;
    if (enemyLife <= 0) {
      Destroy (gameObject);
    }
  }
}

And now we finished our simple artificial intelligence script and you can use for your simple game, study and improve, in a few months I will post the second part explaining how to improve this script, adding field of vision, sounds and etc..

You can view the full script/project on my github, and sorry for the quality of the project/code, I was 16 years old when I wrote this.

And ask me on my Twitter. Thank you guys, see you soon.

Simple Enemy AI System for Unity3D, check on