C++ :: Aufgabe #39 :: Lösung #1

2 Lösungen Lösungen öffentlich
#39

4 Gewinnt für die Konsole

Anfänger - C++ von Gustl - 05.01.2013 um 16:57 Uhr
Es soll 4 Gewinnt für die Konsole programmiert werden.
2 Spieler spielen gegeneinander, ohne Computergegner (ohne künstliche Intelligenz), spielen können.

Optional mit Computergegner, aber bitte in der Beschreibung dann angeben.
#1
vote_ok
von incocnito (700 Punkte) - 05.01.2013 um 17:23 Uhr
Quellcode ausblenden C-Code
#include <iostream>
#include <conio.h>
#include <array>
#include <vector>
#include <windows.h>
#include <cassert>

namespace con
{
    enum Color
    {
        BLACK, //schwarz
        BLUEBLACK, //dunkelblau
        DARKGREEN, //dunkelgruen
        TEAL, //blaugruen
        DARKRED, //dunkelrot
        PURPLE, //lila
        OCHER, //ocker
        LIGHTGREY, //hellgrau
        GREY, //dunkelgrau
        BLUE, //blau
        GREEN, //gruen
        LIGHTBLUE, //hellblau
        RED, //rot
        MAGENTA, //magenta
        YELLOW, //gelb
        WHITE //weiss
    };
    enum Key
    {
        ARROW_UP = 72,
        ARROW_DOWN = 80,
        ARROW_LEFT = 75,
        ARROW_RIGHT = 77,
        ESCAPE = 27,
        SPACE = 32,
        ENTF = 83,
        ENTER = 13,
        BACK = 8,
        TAB = 9
    };
    inline void gotoxy(int Y, int X)
    {
        HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
        COORD pos;
        pos.Y = Y;
        pos.X = X;
        SetConsoleCursorPosition(hCon, pos);
    }
    inline void color(const int COLOR)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR);
    }
    template<typename T>
    inline void print(const int& Ypos, const int& Xpos, const T& s, int c = WHITE)
    {
        assert(Ypos >= 0 && Xpos >= 0);
        gotoxy(Ypos, Xpos);
        color(c);
        std::cout << s;
        color(WHITE);
    }
    inline void blinking_cursor(bool on)
    {
        CONSOLE_CURSOR_INFO inf;
        inf.dwSize = 15;
        if(!on) inf.bVisible = false;
        else inf.bVisible = true;
        SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&inf);
    }
}

const int SPIELFELD_HOEHE = 6;
const int SPIELFELD_BREITE = 7;

typedef const std::array<std::array<int, SPIELFELD_BREITE>, SPIELFELD_HOEHE> constFeldTyp;
typedef std::array<std::array<int, SPIELFELD_BREITE>, SPIELFELD_HOEHE> feldTyp;

struct Pfeil
{
    int Ypos, Xpos, positionsWert; //positionswert gleich wert der x-achse
    Pfeil() : Ypos(20), Xpos(26), positionsWert(0) {}
    void operator++()
    {
        if(Xpos < 44 && Xpos > 25)
        {
            ausgeben(true); //alten Pfeil loeschen
            Xpos += 3;
            ausgeben(false); //neuen malen
            ++positionsWert; //wir sind jetzt bei spielfeldMatrix[hoehe][++psw]
        }
    }
    void operator--() //naja alles wie bei ++ nur andersrum
    {
        if(Xpos > 28)
        {
            ausgeben(true);
            Xpos -= 3;
            ausgeben(false);
            --positionsWert;
        }
    }
    void ausgeben(bool leeren)
    {
        con::print(Ypos, Xpos, leeren? ' ' : '^');
        con::print(Ypos+1, Xpos, leeren? ' ' : '|');
    }
};

void gebeSpielfeldAus()
{
    con::gotoxy(1, 1);
    std::cout <<
              "\n\n\n\n\n\n"
              "\t\t\t|--|--|--|--|--|--|--|\n"
              "\t\t\t|  |  |  |  |  |  |  |\n"
              "\t\t\t|--|--|--|--|--|--|--|\n"
              "\t\t\t|  |  |  |  |  |  |  |\n"
              "\t\t\t|--|--|--|--|--|--|--|\n"
              "\t\t\t|  |  |  |  |  |  |  |\n"
              "\t\t\t|--|--|--|--|--|--|--|\n"
              "\t\t\t|  |  |  |  |  |  |  |\n"
              "\t\t\t|--|--|--|--|--|--|--|\n"
              "\t\t\t|  |  |  |  |  |  |  |\n"
              "\t\t\t|--|--|--|--|--|--|--|\n"
              "\t\t\t|  |  |  |  |  |  |  |\n"
              "\t\t\t|--|--|--|--|--|--|--|\n";
}

void aktualisiereSpielfeld(int spieler, int hoehe, int position)
{
    if(spieler == 1)
        con::print(18-(hoehe*2), position, 'X', con::RED);
    else
        con::print(18-(hoehe*2), position, 'O', con::GREEN);
}

bool checkeHorizontalUndVertikal(constFeldTyp& spielfeldMatrix, bool vertikal)
{
    for(int check = 1; check <= 2; ++check)
        for(int i = 0; i < (vertikal? 7 : 6); ++i)
        {
            int anzahlGleicher = 0;
            for(int j = 0; j < (vertikal? 6 : 7); ++j)
                if(spielfeldMatrix[(vertikal? j : i)][(vertikal? i : j)] == check)
                {
                    if(++anzahlGleicher == 4)
                        return true;
                }
                else
                    anzahlGleicher = 0;
        }
    return false;
}

bool checkeDiagonal(constFeldTyp& spielfeldMatrix, bool linksZuRechts)
{
	for(int check = 1; check <= 2; ++check)
	{
		int maxHoehe[] = { 5, 5, 4, 3 };
		for(int i = 0; i <= 3; ++i)
		{
			int anzahlGleicher = 0;
			int j = 6-i;
			if(linksZuRechts)
				j = i;
			for(int k = 0; k <= maxHoehe[i]; ++k)
			{
				if(spielfeldMatrix[k][j] == check)
				{
					if(++anzahlGleicher == 4)
						return true;
				}
				else
					anzahlGleicher = 0;
				if(linksZuRechts)
					++j;
				else
					--j;
			}
		}
	}
	return false;
}

bool checkeDiagonalExtra(constFeldTyp& spielfeldMatrix, bool linksZuRechts)
{
	for(int k = 1; k <= 2; ++k)
	{
        for(int check = 1; check <= 2; ++check)
        {
            int anzahlGleicher = 0;
            int j = 6;
            if(linksZuRechts)
                j = 0;
            for(int i = k; i <= 5; ++i)
            {
                if(spielfeldMatrix[i][j] == check)
                {
                    if(++anzahlGleicher == 4)
                        return true;
                }
                else
                    anzahlGleicher = 0;
                if(linksZuRechts)
                    ++j;
                else
                    --j;
            }
        }
	}
	return false;
}

bool geloest(constFeldTyp& spielfeldMatrix)
{
    return checkeHorizontalUndVertikal(spielfeldMatrix, true) ||
           checkeHorizontalUndVertikal(spielfeldMatrix, false) ||
           checkeDiagonal(spielfeldMatrix, true) ||
           checkeDiagonal(spielfeldMatrix, false) ||
           checkeDiagonalExtra(spielfeldMatrix, true) ||
           checkeDiagonalExtra(spielfeldMatrix, false);
}

bool unentschieden(constFeldTyp& spielfeldMatrix)
{
    for(int i = 0; i < 6; ++i)
        for(int j = 0; j < 7; ++j)
            if(spielfeldMatrix[i][j] == 0) //wenns irgendwo ein leeres feld gibt
                return false; //kann man noch spielen
    return true;
}

void bewegePfeil(Pfeil& p, char eingabe)
{
    if(eingabe == con::ARROW_RIGHT || eingabe == 'd')
        ++p;
    else if(eingabe == con::ARROW_LEFT || eingabe == 'a')
        --p;
}

bool spielEnde(constFeldTyp& spielfeldMatrix)
{
    if(geloest(spielfeldMatrix))
    {
        con::print(12, 60, "hat gewonnen!!", con::GREEN);
        return true;
    }
    if(unentschieden(spielfeldMatrix))
    {
        con::print(12, 60, "setzte den letzten", con::YELLOW);
        con::print(13, 60, "Stein zum ", con::YELLOW);
        con::print(14, 60, "Unentschieden!", con::YELLOW);
        return true;
    }
    return false;
}

int main()
{
    feldTyp spielfeldMatrix = {{{{0}}}};
    con::blinking_cursor(false);
    con::color(con::WHITE);
    Pfeil pfeil; //zeichnet schonmal einen
    pfeil.ausgeben(false);
    gebeSpielfeldAus();
    enum
    {
        SPIELER_1,
        SPIELER_2
    };
    bool aktuellerSpieler = SPIELER_1;
    do
    {
        con::print(12, 50, "Spieler ");
        std::cout << int(aktuellerSpieler)+1; //false = 0, 0 + 1 = 1

        char eingabe;
        do
        {
            eingabe = getch();
			if(eingabe == con::ESCAPE)
				return 0;
            bewegePfeil(pfeil, eingabe);
        }
        while(eingabe != con::ENTER && eingabe != con::SPACE);

        int hoehe = 0; //wird errechnet aus der position des pfeils und dem inhalt des arrays
        for(int i = 0; i < SPIELFELD_HOEHE; ++i) //laeuft von der pfeilposition an einmal nach oben durch
            if(spielfeldMatrix[i][pfeil.positionsWert] != 0)//und wenn da schon was ist, muss das naechte objekt darueber
                ++hoehe;
        if(hoehe < SPIELFELD_HOEHE)
            spielfeldMatrix[hoehe][pfeil.positionsWert] = (aktuellerSpieler == 0? 1 : 2);
        else //es wird gar nix gesetzt und
            continue; //kein Spielerwechsel

        aktualisiereSpielfeld(aktuellerSpieler, hoehe, pfeil.Xpos); //uerbtraegt den Inhalt des Arrays aufs Spielfeld

        aktuellerSpieler ^= 1; //wechselt den Spieler

    } while(!spielEnde(spielfeldMatrix));
    std::cin.get();
}

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben
2108876

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.