Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

10.03.2014, 20:08

Wie kann man zwei Schleifen zusammen laufen lassen ?

Hallo, ich bin gerade dabei ein Consolen Spiel in C++ zu Programmieren. worum es indem Spiel geht ist erstamal egal. Ich habe den Quellcode so strukturiert das ich eine Funktion geschrieben habe die alle wichtigen Funktionen zusammenführt. zum Beispiel: eine Funktion die das Feld zeichnet oder eine die den Player im Feld bewegt... Auf jeden fall wird diese, ich nenne es mal Hauptfunktion in der Main geöffnet. So und jetzt das Problem in der Hauptfunktion ist noch die sogenante Bot-Funktion, die einfach nur den Bot mit Künstlicher Intelliegenz steuert. Nur jetzt das Problem inder Player-Funktion gibt es einen (CIN) Befehl der, (für die es nicht wissen: Dieser Befehl list in die Console ein) das heißt das die Hauptschleife immer in dieser Funktion stehen bleibt und erst wenn der Spieler seine neuen Kordinaten angegeben hat erst dann der Bot auch neu berechnet wird. Ich hoffe ihr konntet mir soweit folgen hier ein Stück vom Quellcode:

Ps: Es könnte sein dass ich ein wenig unstrukturiert arbeite also wäre es nett mich auf verbesserungs vorschläge zu benachrichtigen.



C-/C++-Quelltext

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
#include <iostream>
#include <Windows.h>


using namespace std;

//Eigende Header (Game.h)
#include "Game.h"

Game::Game()
{
    isRunning   = true;
    Breite      = 80; //79
    Höhe        = 30; //29
    FIELD_B     = 1;
    FIELD_H     = 1;
    BOT_B       = 75;//(rand()% Breite);
    BOT_H       = 25;//(rand()% Höhe);


}
Game::~Game()
{

}



//HAUPTSCHLEIFE   HIER liegt das PROBLEM
void Game::init()
{
    //Lokale Variablen

    while (isRunning == true)
    {

        Draw_field(Höhe, Breite);
        //Player()  <----- Hier hält die Hauptfunktion immer an und wartet auf eine Eingabe 
                        //also wird der Bot nicht neu berechnet ausser der Spieler gibt die neuen Koordinaten an ....                               <-------------DAS PROBLEM
        Bot();


        system("CLS");
    }
}
void Game::Draw_field(const int Höhe, const int Breite)
{

    for(FIELD_Y=0;FIELD_Y<Höhe;FIELD_Y++)
    {
        

        for(FIELD_X=0;FIELD_X<Breite;FIELD_X++)
        {

            field[FIELD_Y][FIELD_X] = ' ';
            field[29][FIELD_X]      = '#';
            field[0][FIELD_X]       = '#';
            field[FIELD_Y][79]      = '#';
            field[FIELD_Y][0]       = '#';

            //Player
            field[FIELD_H][FIELD_B] = '*';


            //BOT Pos
            field[BOT_H][BOT_B] = 'O';
            field[BOT_H][BOT_B] = 'O';

            //Feld ausgeben
            cout << field[FIELD_Y][FIELD_X];


            
        }   

        cout<<endl;
    }


}
void Game::Player()
{
    char Auswahl;


    cout << "\n\n";
    cout <<"Koordinaten: "
         <<"\nHoehe : " << FIELD_H << "\nBreite: " << FIELD_B <<endl;
    cout << "---------------------\n" <<endl;
    cout << "Auswahl(B = beenden): ";
    cin  >> Auswahl;                                                                                                        <---------------- HIER DIE ABFRAGE !!!! 

    switch(Auswahl)
    {
    case'W':
    case'w':
        {

            //move
            FIELD_H -= 1;
            FIELD_B += 0;

            if (field[FIELD_H][FIELD_B] == '#')
            {
                //kollison
                FIELD_H += 1;
                FIELD_B += 0;  
            }

        }break;
    case'A':
    case'a':
        {

            //move
            FIELD_H -= 0;
            FIELD_B -= 1;

            if (field[FIELD_H][FIELD_B] == '#')
            {
                //kollison
                FIELD_H += 0;
                FIELD_B += 1;  
            }


        }break;
    case'S':
    case's':
        {

            //move
            FIELD_H += 1;
            FIELD_B += 0;

            if (field[FIELD_H][FIELD_B] == '#')
            {
                //kollison
                FIELD_H -= 1;
                FIELD_B += 0;  
            }


        }break;
    case'D':
    case'd':
        {

            //move
            FIELD_H += 0;
            FIELD_B += 1;

            if (field[FIELD_H][FIELD_B] == '#')
            {
                //kollison
                FIELD_H += 0;
                FIELD_B -= 1;  
            }

        }break;
    case'B':
    case'b':
        {
            isRunning = false;

        }break;
    default:
        {
            cout << "Falsche Eingabe !" <<endl;
            Sleep(4000);
            isRunning = false;
        }
    }
}
void Game::Bot()
{
        //Loakle Variablen
        //



                                                    //Ich weiss das Bot-system ist noch nicht Fertig also bitte nicht wundern soll nur seinen Zweck erfüllen aber trotzdem wären verbesserungs Vorschläge nicht Schlecht :) 


        //Zufalls Generator (MOVE)
        BOT_B += (rand()% 3);
        BOT_H += (rand()% 3);
        BOT_B -= (rand()% 3);
        BOT_H -= (rand()% 3); 
        Sleep    (200);


        //Kollision (BOT) 
        //
        for (int i=0;i<Höhe;i++) //Höhe = 29
        {

         
            for (int j=0;j<Breite;j++) //Breite = 79
            {


              //Kollision 
              //

              //Höhe
              if (field[0][j] == 'O')
              {
                  BOT_H += 2;
                  system("CLS");
                  Draw_field(Höhe, Breite);
              }
              //Breite
              if (field[i][0] == 'O')
              {
                  BOT_B += 2;
                  system("CLS");
                  Draw_field(Höhe, Breite);
              }
              //unten
              if (field[Höhe-1][j] == 'O')
              {
                  BOT_H -= 2;
                  system("CLS");
                  Draw_field(Höhe, Breite);
              }
              //rechts
              if (field[i][Breite-1] == 'O')
              {
                  BOT_B -= 2;
                  system("CLS");
                  Draw_field(Höhe, Breite);
              }




            }


        }

    




}



Auf die Frage oben bezogen meine ich eig. nur dass beispielsweise die Bot-funktion in einer Schleife leuft und die Player Funktion in einer anderen so dass wärend der Abfrage der Bot weiter berechnet wird.
Danke im voraus :D

2

10.03.2014, 20:34

Parallel? Das geht nur mit Threading. Da es eine Memberfunktion ist, ist hier Kuchen essen. ^^

C-/C++-Quelltext

1
2
std::thread ai(std::bind(&Game::Bot, this)); // führt nun Bot() mit der eigenen Instanz aus aus
ai.join(); //stoppt ausführen, sobald die Schleife in Bot() endet


Zum Code allgemein lässt sich an sich recht viel sagen. Arbeite doch erst mal daran möglichst OOP zu programmieren und dann deinen Stil an sich zu verbessern, (ja so drücke ich mich jetzt vorm schreiben) denn die Game-Klasse muss sich gewiss nicht um all die Dinge in dieser Art kümmern. Die AI würde ich z.B. separat aufführen, so ginge dann auch so was: (bisschen Pseudocode jetzt)

C-/C++-Quelltext

1
2
3
4
struct AI{void coolAiFunction();private:ref& ref; };
///somewhere
Game::Game() : initializer_list, ai_instance(), thread(std::bind(&AI::coolAiFunction, &ai_instance)
{}


Dann solltest du dir noch überlegen, ob der Thread zu einer bestimmten Zeit ausgeführt werden soll, heißt mehr oder weniger ob die Instanz auf Heap oder Stack sein "muss".
Für diesen Fall hier lohnts sich nicht unbedingt, aber nujo.

//Außerdem: http://www.das-dass.de/

MfG
Check

3

10.03.2014, 20:45

Parallel? Das geht nur mit Threading. Da es eine Memberfunktion ist, ist hier Kuchen essen. ^^

C-/C++-Quelltext

1
2
std::thread ai(std::bind(&Game::Bot, this)); // führt nun Bot() mit der eigenen Instanz aus aus
ai.join(); //stoppt ausführen, sobald die Schleife in Bot() endet


Zum Code allgemein lässt sich an sich recht viel sagen. Arbeite doch erst mal daran möglichst OOP zu programmieren und dann deinen Stil an sich zu verbessern, (ja so drücke ich mich jetzt vorm schreiben) denn die Game-Klasse muss sich gewiss nicht um all die Dinge in dieser Art kümmern. Die AI würde ich z.B. separat aufführen, so ginge dann auch so was: (bisschen Pseudocode jetzt)

C-/C++-Quelltext

1
2
3
4
struct AI{void coolAiFunction();private:ref& ref; };
///somewhere
Game::Game() : initializer_list, ai_instance(), thread(std::bind(&AI::coolAiFunction, &ai_instance)
{}


Dann solltest du dir noch überlegen, ob der Thread zu einer bestimmten Zeit ausgeführt werden soll, heißt mehr oder weniger ob die Instanz auf Heap oder Stack sein "muss".
Für diesen Fall hier lohnts sich nicht unbedingt, aber nujo.

//Außerdem: Parallel? Das geht nur mit Threading. Da es eine Memberfunktion ist, ist hier Kuchen essen. ^^

C-/C++-Quelltext

1
2
std::thread ai(std::bind(&Game::Bot, this)); // führt nun Bot() mit der eigenen Instanz aus aus
ai.join(); //stoppt ausführen, sobald die Schleife in Bot() endet


Zum Code allgemein lässt sich an sich recht viel sagen. Arbeite doch erst mal daran möglichst OOP zu programmieren und dann deinen Stil an sich zu verbessern, (ja so drücke ich mich jetzt vorm schreiben) denn die Game-Klasse muss sich gewiss nicht um all die Dinge in dieser Art kümmern. Die AI würde ich z.B. separat aufführen, so ginge dann auch so was: (bisschen Pseudocode jetzt)

C-/C++-Quelltext

1
2
3
4
struct AI{void coolAiFunction();private:ref& ref; };
///somewhere
Game::Game() : initializer_list, ai_instance(), thread(std::bind(&AI::coolAiFunction, &ai_instance)
{}


Dann solltest du dir noch überlegen, ob der Thread zu einer bestimmten Zeit ausgeführt werden soll, heißt mehr oder weniger ob die Instanz auf Heap oder Stack sein "muss".
Für diesen Fall hier lohnts sich nicht unbedingt, aber nujo.

//Außerdem: http://www.das-dass.de/

MfG
Check

Danke für deine Antwort hat echt geholfen so fern ich dass verstehe.. ich meine Afänger bin ich nicht mehr nur alle Befehle kenne ich leider auch nicht. Ich werde mich mal über Die Befehle im Internet schlaue machen:

Danke :thumbsup:

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

4

10.03.2014, 21:07

Ich glaube Threading ist hier wirklich Overkill.

Hier, zwar nicht C++, aber das hilft dir meiner Meinung nach deutlich einfacher weiter: http://www.cprogramming.com/fod/kbhit.html

Und dann musst du in Player nur was tun wenn kbhit dir sagt, dass eine Taste gedrückt worden ist.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Tankard

Treue Seele

Beiträge: 192

Beruf: Student, Hardware- und Softwareentwicklung als wissenschaftliche Hilfskraft

  • Private Nachricht senden

5

10.03.2014, 21:44

Vielleicht könnte man anstatt kbhit auch etwas wie std::cin.rdbuf()->in_avail() verwenden.

Also anstatt auf eine bestimmte Eingabe zu warten prüfst du ob überhaupt etwas vorhanden ist und liest dann das vorhandene ein. Danach kannst du prüfen ob daraus was Sinnvolles wird.

std::istream::peek könnte vielleicht auch interessant sein.

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

6

11.03.2014, 10:34

Könnte sein, dass dieser Aufruf besser "reinpasst" und portabler ist. Ich hatte ihn gestern bei kurzem googeln nicht gefunden. ;)
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Werbeanzeige