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

wunhopkuendo

Frischling

  • »wunhopkuendo« ist der Autor dieses Themas

Beiträge: 31

Beruf: Student

  • Private Nachricht senden

1

23.12.2013, 14:58

Meinungen zu meinem Vier Gewinnt Grundgerüst?

Hey Leute,

ich habe schonmal ein Vier Gewinnt Konsolenspiel programmiert, und das war viel zu viel Aufwand,
deswegen hatte ich jetzt Lust das Ganze mal ganz anders über Klassen, etc anzugehen..Von daher würde mich interessieren
was ihr so von dem Grundgerüst haltet, das "Spiel" ist noch lange nicht fertig, es fehlen noch die ganzen Gewinnkombinationen, etc..
ich hab auch gehört dass 'new' und 'delete' eher nicht mehr benutzt werden, sonder eher 'unique_ptr', aber wie siehts mit dem 2D-Array in meiner
Klasse Field aus? wie würde man das "heutzutage" machen ? mit std::arrays? Lasst mich einfach alles wissen, was man optimieren könnte :)


Game.h:

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
#ifndef GAME_H
#define GAME_H

#include "Player.h"
#include "Field.h"

class Game
    {
        private:
            Field*  _Gameboard;
            Player* _Playerp1;
            Player* _Playerp2;

        public:

            Field*  getField()const{return _Gameboard;}
            Player* getPlayer1()const{return _Playerp1 ;}
            Player* getPlayer2()const{return _Playerp2 ;}

            Game();
            ~Game();
    };

#endif


Field.h

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
#ifndef FIELD_H_
#define FIELD_H_

#ifndef FIELD_H_
#define FIELD_H_

#include "Player.h"
#include <string>

class Field
{
    private:

        unsigned int _WIDTH;
        unsigned int _HEIGHT;

        char  _Position[6][7];
        char  _DefaultSymbol;

    public:

        Field();
        Field(const char defaultsymbol);

        unsigned int getHeight()const{ return _HEIGHT;}
        unsigned int getWidth ()const{ return _WIDTH; }

        void printField()const;

        const std::string reservePosition(const Player& p,const int column);

};

#endif



Player.h:

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
#ifndef PLAYER_H_
#define PLAYER_H_

#include <string>


class Player
    {
        private:

            char        _Symbol;
            std::string _Name;

        public:

            Player();
            Player(const char symbol);
            Player(const std::string name );
            Player(const std::string name ,const char symbol);

            void printPlayerData()const;

            void setSymbol(const char  symbol);
            void setName  (const std::string name);

            const char getSymbol()const{return _Symbol;}
            const std::string getName  ()const{return _Name;}


    };

#endif /* PLAYER_H_ */


Game.cpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "Game.h"
#include <iostream>


Game::Game()
    {
        _Gameboard = new Field;
        _Playerp1 = new Player("Basti",'x');
        _Playerp2 = new Player("Laura",'+');
    }

Game::~Game()
    {
        delete _Gameboard;
        delete _Playerp1;
        delete _Playerp2;
    }


Field.cpp:

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



Field::Field()
    {
    _WIDTH  = 7;
    _HEIGHT = 6;
        _DefaultSymbol = 'O';

        for(unsigned int s = 0;s < _HEIGHT;s++)
            {
                for(unsigned int t = 0;t < _WIDTH;t++)
                    {
                        _Position[s][t] = _DefaultSymbol;
                    }
            }

    }

Field::Field(const char defaultsymbol)
    {
        _WIDTH  = 7;
        _HEIGHT = 6;
        _DefaultSymbol = defaultsymbol;

        for(unsigned int s = 0;s < _HEIGHT;s++)
            {
                for(unsigned int t = 0;t < _WIDTH;t++)
                    {
                        _Position[s][t] = defaultsymbol;
                    }
            }
    }

const std::string Field::reservePosition(const Player& p,const int column)
    {
        std::string markierStatus("");

        for(unsigned int i = 0, s = 1; i < _WIDTH ; i++, s++)
            {
                if(s == _WIDTH)
                    {
                        markierStatus = "Voll";
                        break;
                    }

                if(_Position[i][column] == _DefaultSymbol)
                    {
                        _Position[i][column] = p.getSymbol();
                        markierStatus = "Erfolgreich";

                        break;
                    }

            }

        return markierStatus;
    }

void Field::printField()const
    {
        for(unsigned int s = _HEIGHT - 1;s >= 0 ;s--)
            {
                for(unsigned int t = 0;t < _WIDTH;t++)
                    {
                        std::cout << " | " << _Position[s][t];
                    }

                std::cout << std::endl
                     << "-----------------------------"
                     << std::endl;
            }
    }


Player.cpp:

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
#include "Player.h"

#include <iostream>
#include <cstdlib>
#include <string>


static unsigned int PlayerID = 0;

Player::Player()
    {
        ++PlayerID;

        _Name = "Spieler";
        _Name += PlayerID;

        _Symbol = static_cast<char>(PlayerID);
    }

Player::Player(const std::string name)
    {
        srand(time(0));

        _Name = name;
        _Symbol = (rand()%255);
    }

Player::Player(const char symbol)
    {
        ++PlayerID;

        _Name   = "Spieler";
        _Name  += PlayerID;
        _Symbol = symbol;
    }

Player::Player(const std::string name,const char symbol)
    {
        _Name   = name;
        _Symbol = symbol;
    }


void Player::printPlayerData()const
    {
        std::cout << "Name des Spielers: "   << _Name   << std::endl
                  << "Symbol des Spielers: " << _Symbol << std::endl;
    }

void Player::setName(const std::string name)
    {
        _Name = name;
    }

void Player::setSymbol(const char symbol)
    {
        _Symbol = symbol;
    }


und schließlich:

main.cpp:

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
#include "Game.h"
#include "Player.h"

#include <iostream>

using std::cout;
using std::endl;
using std::cin;


int main()
    {
        bool    won = false;
        Game*   Matchp   = new Game;
        Player* tmpPlayerp;


        cout << "Vier Gewinnt" << endl
             << "~~~~~~~~~~~~" << endl << endl;

        cout << "Spieler : " << endl
             << "-------------------------------" << endl;

        Matchp->getPlayer1()->printPlayerData();

        cout << "-------------------------------" << endl;

        Matchp->getPlayer2()->printPlayerData();


        cout << "Welcher Spieler soll beginnen?"<< endl
             << " 1 - " << Matchp->getPlayer1()->getName() << endl
             << " 2 - " << Matchp->getPlayer2()->getName() << endl;



        int choice = 0;
        do
            {
                cout << "Wahl ( 1 / 2 ) : ";
                cin >> choice;
            }
        while(choice != 1 && choice != 2);

        switch(choice)
            {
                case 1:
                    tmpPlayerp = Matchp->getPlayer1();
                break;
                default:
                    tmpPlayerp = Matchp->getPlayer2();
                break;
            }


        int column = 0;

        while(!won)
        {

            Matchp->getField()->printField();

            while(true)
                {
                    cout << tmpPlayerp->getName() << " ist am Zug."              << endl
                         << "Gib die Spalte an, in die dein Stein fallen soll: " << endl
                         << "Spalte: "                                           << endl;
                    do
                        cin  >> column;

                    while(column < 1 || column > 7);

                    std::string Status = Matchp->getField()->reservePosition(*tmpPlayerp, column - 1);

                    if(Status == "Erfolgreich") break;
                    if(Status == "Voll") cout << "Diese Spalte ist voll, bitte gib eine andere Spalte an" << endl;
                }





            if(won == false)
                {
                    if(tmpPlayerp == Matchp->getPlayer1()) tmpPlayerp = Matchp->getPlayer2();
                    else tmpPlayerp = Matchp->getPlayer2();
                }

        }

        return 0;
    }



Grüße

wunhopkuendo

P.S.: Mal ne wirklich blöde Frage, wie löscht man von sich Beiträge wieder? :D

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »wunhopkuendo« (30.12.2013, 14:16)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

23.12.2013, 15:02

P.S.: Mal ne wirklich blöde Frage, wie löscht man von sich Beiträge wieder? :D

Gar nicht.
Du hättest auch einfach deinen alten Thread nochmal "pushen" können, du musst dazu nicht einen neuen mit dem exakt gleichen Inhalt eröffnen.

wunhopkuendo

Frischling

  • »wunhopkuendo« ist der Autor dieses Themas

Beiträge: 31

Beruf: Student

  • Private Nachricht senden

3

29.12.2013, 20:16

Achso, das wusste ich nicht..
und zum 'pushen' hab ich auch nichts Entsprechendes gefunden .. :)

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

29.12.2013, 22:58

und zum 'pushen' hab ich auch nichts Entsprechendes gefunden .. :)

Genau das hast du doch gerade getan. ;)

wunhopkuendo

Frischling

  • »wunhopkuendo« ist der Autor dieses Themas

Beiträge: 31

Beruf: Student

  • Private Nachricht senden

5

29.12.2013, 23:12

Ah, jetzt hab ichs verstanden,
war gerade bisschen schwer von Begriff :dash:

kann jemand schon ein paar Anmerkungen zu meinem Code machen?

FSA

Community-Fossil

  • Private Nachricht senden

6

29.12.2013, 23:30

Wofür statische Variablen?
Warum const char* als Parameter?
using namespace würde ich nicht in Headern nutzen bzw. generell nicht.
string markierStatus = 0; ist komisch gelöst.
markierStatus = static_cast<string>("Voll"); der Cast ist sinnlos.
Warum leere Destruktoren?

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

wunhopkuendo

Frischling

  • »wunhopkuendo« ist der Autor dieses Themas

Beiträge: 31

Beruf: Student

  • Private Nachricht senden

7

30.12.2013, 13:25

oh, das stimmt natürlich..
using namespace std ist komplett raus,
aber ich habe stattdessen
using std::cout;
using std::cin;
using std::endl;

drin, das geht doch sicher,denn ich hab nicht vor etwas anderes als cout zur Ausgabe zu verwenden?

Cranberry

Treue Seele

Beiträge: 312

Wohnort: Innsbruck, Tirol

  • Private Nachricht senden

8

30.12.2013, 13:28

Du könntest aber einfach std::cout << "Blabla" << std::endl; verwenden.

buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

9

30.12.2013, 13:33

Da ist eine ganze Menge, was Fragen aufwirft. Fangen wir mal bei Game.h an. Warum sind Player1 und Player2 denn Pointer? Field ist es nicht.
Dann ist das mit "const" auch immer schön durcheinander gewürfelt. Das ist nicht wirklich konsistent verwendet.
Dann verwendest Du einmal unsigned int und dann unsigned short. Entscheide dich mal.
Der Rückgabewert von reserverPosition ist mir nicht klar und warum ist der erste Parameter in der Methode nicht const?
Außerdem wie bereits erwähnt niemals "using namespace" verwenden. Es sei denn, du weißt 100% was du machst.
Das mit "const" ist Dir auch nicht so ganz klar, oder?
Das mit dem Array ist absolut in Ordnung. Da es ja nicht dynamisch ist, brauchst Du wirklich kein std::array. Es sei denn Du hast da Spaß dran.
Was ist denn PlayerID? Das erschlißet sich mir auch nicht.

Sorry, aber der Code ist nicht so ganz dolle.

wunhopkuendo

Frischling

  • »wunhopkuendo« ist der Autor dieses Themas

Beiträge: 31

Beruf: Student

  • Private Nachricht senden

10

30.12.2013, 14:11

Das mit using std::cout etc. war nur pure faulheit, weil ich mir das ganze umschreiben sparen wollte,
ist es denn sicherer, das std:: vor jedes cout zu schreiben? im Rahmen meines Projektes meine ich, ich weiß ja
was ich uungefähr tun werde, und was ich nicht tun werde, deswegen scheint mir das in diesem Projekt sinnlos..

@buggypixels:
was meinst du mit durcheinander gewürfelt bezüglich const? eigtl habe ich versucht, const soweit durchzuziehen, wie es geht..
okay, die Rückgabetypen sehe ich ein, darauf habe ich nicht geachtet..
und beim ersten Parameter von reservePosition sowie bei getField gab es Fehlermeldungen als ich es const gemacht habe,
aber ansonsten ist doch eigtl alles const, was im Großen und Ganzen const geht?

zum Rückgagetyp von reservePosition: das ist nur eine vorübergehende Lösung, wie genau ich das regeln will weiß ich noch nicht,
wohl wahrscheinlich mit int

PlayerID sollte einfach eine Möglichkeit sein um zum einen Spieler mit fortlaufenden Nummern zu 'erzeugen', die
damit auch durch den Standardkonstruktor voneinander unterschiedliche namen haben und zum anderen,
damit jeder Spieler der mit dem Standardkonstruktor erzeugt wird ein anderes Symbol zum Belegen der Felder erhält,
was bei zwei Spielern vielleicht überzogen sein mag, aber ich wollte es ganz gerne so allgemein haben

ich editiere mal meinen gesamten code, wie er jetzt aussieht

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »wunhopkuendo« (30.12.2013, 14:18)


Werbeanzeige