How do I get the enemy to follow me?

Hello!

I'm having so much trouble understanding how to create this code...

Recently I found out how to make the enemies move randomly on the screen, but how can I make them pursue and attack me?

Every player has to have 2 moves per turn, but I haven't figured that out either. I've been trying to integrate code from examples like chess but that's not really making sense to me.

I'm just using code blocks, but I've seen a few vids of people using the sfml-dev library... but my prof wants us to work with raw code. The below is NOT my final project (I've changed and removed a lot since I'm paranoid about being accused of plagiarism)

Any insight?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>


using namespace std;

struct pos
{
    int x;
    int y;
};
struct Player1
{
    bool UP;
    bool RIGHT;
    bool DOWN;
    bool LEFT;

    char symbol;
    int LIVES; 
    int weapon;
    int kills;
    int deaths;
    pos position;

    void initPlayer1 ()
    {
        symbol = '@';
        LIVES = 5; 
        weapon = 1;
        kills = 0;
        deaths = 0;
        position.x = 1;
        position.y = 1;
    }

};

struct poss
{
    int x;
    int y;
};
struct EnemyNPC
{
    int symboll;
    int livesh; 
    int weaponn;
    pos enemypos;

    void initEnemyNPC ()
    {
        symboll = 'K';
        livesh = 5; 
        weaponn = 2;
    }
};

const int CLMN = 15;
int Gamespeed = 100;
void movePlayer1(Player1&, char[][CLMN], char, int, int, int&, int);
void menu (int);
void initBoard(char[][CLMN], int, int);
void showBoard(char[][CLMN], int, int);
void instructions();
void userOption (int);
void EnemyNPCPos (char[][CLMN], EnemyNPC, Player1, int, int);
void scoreBoard(Player1, int, int);



int main()
{
    int opt;
    const int MAX_LIVES = 5;
    const int MIN_LIVES = 0;
    const int HUNGER = 10; 
    const int RW = 15;
    const int MAX_ACTIONS = 10;
    int counterr = 0;
    char board[RW][CLMN];
    char movement;

    cout << "\t\tWelcome \n"
                << "Will you choose play?\n\n"
                << endl;
    cout <<  "1. play\n"
                 << "2. quit\n"
                 << "Enter your option (1 or 2): ";
    cin >> opt;

    userOption (opt);

    switch (opt)
    {
        case 1:
            cout <<  "EASY MODE\n" << endl;
                EnemyNPC dead;
                dead.initEnemyNPC();
                Player1 zombiePlayer1;
                zombiePlayer1.initPlayer1();
                initBoard(board, RW, CLMN);
                EnemyNPCPos (board, dead, zombiePlayer1, RW, CLMN);
                board[zombiePlayer1.position.x][zombiePlayer1.position.y] = zombiePlayer1.symbol;
            while(movement != 'q')
            {
                instructions();
                showBoard(board, RW, CLMN);
                scoreBoard(zombiePlayer1, counterr, MAX_ACTIONS);
                cout << "Move your Player1" << endl;
                cin >> movement;
                movePlayer1(zombiePlayer1, board, movement, RW, CLMN, counterr, MAX_ACTIONS);

            }
            break;

        case 2:
            cout << "R.I.P.";

    }
    return 0;
}



void initBoard(char array[][CLMN], int rwSize, int clmnSize)
{
    for(int rw = 0; rw < rwSize; rw++)
    {
        for(int clmn = 0; clmn < clmnSize; clmn++)
        {
            array[rw][clmn] = 250;
        }
    }
    for(int clmn = 0; clmn < clmnSize; clmn++)
    {
        array[0][clmn] = 205;
        array[rwSize-1][clmn] = 205;
    }
    for(int rw =0; rw < rwSize; rw++)
    {
        array[rw][0] = 186;
        array[rw][clmnSize-1] = 186;
    }
    array[0][0] = 201;
    array[0][clmnSize-1] = 187;
    array[rwSize-1][0] = 200;
    array[rwSize-1][clmnSize-1] = 188;
}

void showBoard(char array[][CLMN], int rwSize, int clmnSize)
{
    cout << endl;
    for(int rw = 0; rw < rwSize; rw++)
    {
        for(int clmn = 0; clmn < clmnSize; clmn++)
        {
            cout << array[rw][clmn];
        }
        cout << endl;
    }
}

void movePlayer1(Player1& userposition, char arrays[][CLMN], char actions, int rw, int clmn, int& counter, int maxActions)
{
   if(counter < maxActions)
    {
        if(actions == 's' && userposition.position.x < rw-2)
        {
            arrays[userposition.position.x][userposition.position.y] = 250;
            userposition.position.x += 1;
            arrays[userposition.position.x][userposition.position.y] = userposition.symbol;
             counter++;
            system("cls");

        }
        else if(actions == 'a' && userposition.position.y > 1)
        {

            arrays[userposition.position.x][userposition.position.y] = 250;
            userposition.position.y -= 1;
            arrays[userposition.position.x][userposition.position.y] = userposition.symbol;
             counter++;
            system("cls");
        }
        else if(actions == 'd' && userposition.position.y < clmn-2)
        {
            arrays[userposition.position.x][userposition.position.y] = 250;
            userposition.position.y += 1;
            arrays[userposition.position.x][userposition.position.y] = userposition.symbol;
            counter++;
            system("cls");

        }
        else if(actions == 'w' && userposition.position.x > 1)
        {
            arrays[userposition.position.x][userposition.position.y] = 250;
            userposition.position.x -= 1;
            arrays[userposition.position.x][userposition.position.y] = userposition.symbol;
             counter++;
            system("cls");
        }
    }
    else if(actions == 'q')
    {
            cout << "\n\t\tTOO BAD!" << endl;
            system("cls");
    }
    else
    {
            cout << "You've entered the wrong input" << endl;
            system("cls");
    }
    if(counter == maxActions)
        cout << "You have used up all your actions!\n";
}

void instructions()
{
     cout << "Player1 Movement:\n"
               << "\t\tw = UP\n"
               << "\t\ta = LEFT\n"
               << "\t\ts = DOWN\n"
               << "\t\td = RIGHT\n"
               << "\t\tq = QUIT\n"<< endl;
}

void userOption (int option)
{
    if(option != 1 || option != 2)
        cout << "\nYou much choose to fight or face your doom\n";
}

void scoreBoard(Player1 userposition, int counter, int maxActions)
{
    cout << "Kills: " << userposition.kills << endl;
    cout << "Deaths: " << userposition.deaths << endl;
    cout << "Ammo: " << userposition.ammo << endl;
    cout << "Tuna of Lives cans: " << userposition.LIVES << endl;
    cout << "Your move: " << counter << "/" << maxActions << endl;
}

void EnemyNPCPos (char arrays[][CLMN], EnemyNPC z, Player1 w, int rw, int clmn)
{
    srand(time(0));
    z.enemypos.x = rand() % 13 + 1;
    z.enemypos.y = rand() % 13 + 1;

    while(z.enemypos.x == w.position.x && z.enemypos.y == w.position.y && z.enemypos.x > rw-2 && z.enemypos.y < 1 && z.enemypos.y > clmn-2 && z.enemypos.x < 1)
    {
        z.enemypos.x = rand() % 13 + 1;
        z.enemypos.y = rand() % 13 + 1;
    }

    arrays[z.enemypos.x][z.enemypos.y] = z.symboll;

}
There are basically three ways to go (orientation): horizontal, vertical, and diagonal.

horizontal: x +/- 1, y +/- 0
vertical: x +/- 0, y +/- 1
diagonal: x +/- 1, y +/- 1

Further there are four quadrants: They determine the sign (+/-).

For your enemy to follow:

[- choose randomly orientation]
- choose quadrant: relative where the player is.

For example:

player.x < enemy.x -> x - 1
player.y < enemy.y -> y - 1
hey man, I have made a few games that do this up to now. I actually posted one on this site when I was trying to get it more organized. If you want to see it I can send you it. I also managed to put an awareness in so that the enemies will only follow if you are so many blocks away or closer

BUT, what you can do is something similar to this

int distance.x = player1.pos.x - enemypos.x;
int distance.y = player1.pos.y - enemy.pos.y;
if (distance.x > 0)
enemy.pos.x += 1;
else if /*could also be else*/ (distance < 0)
enemy.pos.x -= 1;

if (distance.y > 0)
enemy.pos.y += 1;
else if (distance.y <0)
enemy.pos.y -= 1;


of course doing it this way will allow the enemy to move diagonally, you'll have to add some sort of condition that if the enemy moves in one direction then the other will not be met. hope this helps man
for some reason i really can't get it right. i think i need to see similar cases. we have not done classes at all, so i guess i have to stick to structures which are not the best... i'd really appreciate to see the one you posted if thats cool.

idk why i can't get the enemy to follow properly. i tried:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
int newX, newY;

	if (!z.smart) {
		
		newX = z.positionn.x + rand() % 3 - 1;
		newY = z.positionn.y + rand() % 3 - 1;
	} else {
	
		newX = z.positionn.x + position(w.position.x - z.positionn.x);
		newY = z.positionn.y + sign(w.position.y - z.positionn.y);
	}

	if (newX >= 0 && newX < row) {
		z.positionn.x = newX;
	}
	if (newY  >= 0 && newY < row) {
		z.positionn.y = newX;
	}

    board[z.positionn.x][z.positionn.y] = z.SYMB;
Last edited on
What are you trying to do? What is z/w?

For X you have position(...) and for Y sign(...). What are this functions doing and why the difference?
oh jeeze, you havent done classes yet? Thats a little more difficult haha. When I only knew up to arrays (without classes) I made a digimon game (the bare minimum) and it was over 1k lines just for leveling up, battling, getting exp. With classes and a little more programming knowledge I was able to do same and more in like 400 lines. I would HIGHLY suggest a game like this to be made after knowing classes. I can send a link to the code for a game i made called peasant crawler (after a c++ beginner challenge, but made way more of it then was challenged to) the only thing is I dont think you would be able to understand much of it at all. Also one of the most important things I have learned from this site is to organize your code as much as possible. Sacrifice shorter text for more understandable text. For example I am working on a simulator where bunnies get born and get infected and I have a function called something similar to void find_bunny_by_location(int col, int row); you can see what it does easily, and I could have made it void find_bunny, but you dont understand what its REALLY doing. so when you have newX = z.position.x I have no idea why that z is there, and while x and y works I have always found that using col and row is a little easier since you are using a gameboard for it. I know I haven't helped with your code, but following this advice will help you personally more than just giving you the code to make the same mistakes again. Hope I have helped, and you can always message back with other questions
I'm trying to learn classes on my own, but it's due tomorrow now :/ I feel like classes are the way to go, but I just don't know how to use them... I know the prof isn't looking for that either.

as for what I was trying to do.. I tried to kill quite a bit of my code to remake it.

What I tried:
-added a Boolean to the struct to differentiate between a random zombie from a smart zombie and then tried the int newX, newY formula above. (I think I did the bool wrong :/ because that should work...)
- I tried adding a new struct to BE the smart zombie, making a total of three structs for characters... so I thought I couldn't use x and y for so many and started using z :/

Obviously, I'm very lost. I'm overcomplicating this and I can't seem to stop.

what I need:

I need the EnemyNPCPos function to:
1)generate at least 6 enemies
2)of those 6, some should be smart (based on random generation)
3) the smart zombie will seek the user
4)the regular zombie will attack and move randomly

I just can't understand how to put this into working code. It's frustrating because up until now everything was so straightforward. I'm reading chapter after chapter and it is just not adding up.
Topic archived. No new replies allowed.