Akuba icon

Schiffe Versenken (geht sogar!)

Akuba | PRO | 10/20/17 08:15:21 AM UTC | 0 ⭐ | 430 👁️ | Never ⏰ | []
C |

11.28 KB

|

None

|

0 👍

/

0 👎

/*
                "Schiffe" versenken
    (Wären das dann nicht eigendlich U-Boote wenn man sie nur sieht wenn sie getroffen wurden?)
         Code geschrieben von Tobias Schmidt
 
         Legende:
            ~ - Wasser
            S - Schiff
            o - Getroffenes "Schiff"
            x - Fehlgeschlagener Schuss
    Developer Log:
        19.10.2017 - 10:00 - Irgendwie geht da was nicht.
        19.10.2017 - 11:47 - Fast den kleinen Schrank zerlegt.
        19.10.2017 - 11:49 - Der mist funktioniert nicht ...
        20.10.2017 - 8:00  - Es geht endlich! \(0.0)/
 
*/
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
 
#define sizeX 8
#define sizeY 8
#define sizeTotal ((sizeX+1)*10+sizeY)
#define maxCachedGegnerZuege 4
#define maxShips sizeX+sizeX
 
// Interne Variablen
#define wasser  0
#define daneben 1
#define treffer 2
#define schiff  3
#define bereits_Daneben     11
#define bereits_Getroffen   22
#define player1_Gewonnen    42  // Lösung auf alles.
#define player1_Verloren    31  // 31 hör zu, eine Line macht dich nicht cool ...
 
// Das sieht man später anstatt der Variablen
#define wasser_Icon "~ "
#define daneben_Icon "x "
#define treffer_Icon "� "
#define schiff_Icon "0 "
 
static int spielFeldPlayer[sizeTotal] = { 0 }; // static soll sicherstellen das auch
static int spielFeldGegner[sizeTotal] = { 0 }; // wirklich nur DIESE variable genutzt wird, und keine kopie
static int playerShipsLeft;
static int gegnerShipsLeft;
 
static int mode;
 
static bool spieler1AmZug = true; 
static bool spielVerlassen = false;
static bool zumHauptmenu = false;
 
static int letzteComputerZuege[maxCachedGegnerZuege][2];
static int computerZuege = 0;
 
static int rundenZaehler;
static int timeSinceStart;
// Headerkrams
 
void generiereSpielFeld(bool istSpieler1);
void zeigeSpielFeld(bool nurGetroffen);
int macheSpielZug (int zugX, int zugY);
bool menschlicherSpielZug(int debugx, int debugy);
bool computerSpielZug(bool rekursive);
void clear();
 
void showFieldHeader();
 
void showFieldHeader() {
        int sekunde = (int)(time(NULL)-timeSinceStart), minute = 0;
        while(sekunde > 60)
        {
            sekunde -= 60;
            minute++;
        }
        printf("Runde %d | Zeit: %.2d:%.2d\n", rundenZaehler, minute, sekunde);
        if (spieler1AmZug && mode == 1) printf("\n\t\tDu bist am Zug!\n"
                                               "\tKI Schiffe: %d | Deine Schiffe: %d\n", gegnerShipsLeft, playerShipsLeft);
        else if (spieler1AmZug && mode == 2) printf("\n\t\tSpieler 1 ist am Zug!\n"
                                                    "\tSchiffe Spieler 2: %d | Deine Schiffe: %d\n", gegnerShipsLeft, playerShipsLeft);
        else if (!spieler1AmZug && mode == 2) printf("\n\t\tSpieler 2 ist am Zug!\n"
                                                     "\tSchiffe Spieler 1: %d | Deine Schiffe: %d\n", playerShipsLeft, gegnerShipsLeft);
        else if (spieler1AmZug && mode == 3) printf("\n\t\tTestmodus\n");
        else if (!spieler1AmZug && mode == 1) printf("\n\t\tDie KI ist am Zug!\n"
           "\tKI Schiffe: %d | Deine Schiffe: %d\n", gegnerShipsLeft, playerShipsLeft);
}
 
void clear() {
    printf("\e[1;1H\e[2J");
}
 
bool computerSpielZug(bool rekursive) {
    bool ret = false;
    if (!rekursive) {
        clear();
        showFieldHeader();
        zeigeSpielFeld(false);
        sleep(1);
    }
    int nextx = rand() % sizeX-1;
    int nexty = rand() % sizeY-1;;
    /*if(computerZuege == 0){   // Es geht, ich fasse hier nichtsmehr an!
        nextx = rand() % sizeX-1;
        nexty = rand() % sizeY-1;
        letzteComputerZuege[computerZuege][0] = nextx;
        letzteComputerZuege[computerZuege][1] = nexty;
        computerZuege++;
    } */
    int status = macheSpielZug(nextx, nexty);
    //if (!rekursive) {
    clear();
    showFieldHeader();
 
    zeigeSpielFeld(false);
    //}
    if (status == treffer) {
        printf("\n\t Verdammt! Der Computer hat eins unserer Schiffe versenkt\n");
    } else if (status == daneben) {
        //ret = computerSpielZug(true);
        printf("\n\t Daneben! - Uns kann nichts aufhalten!\n");
    } else if (status == bereits_Daneben) {
         ret = computerSpielZug(true);
        //printf("\n\t Erneut Daneben... - Das sollte eigendlich nicht möglich sein ...!\n");
    } else if (status == player1_Gewonnen) {
        printf("\n\t SIEG! Wir haben gewonnen!!\n");
        ret = true;
    } else if (status == player1_Verloren) {
        printf("\n\t NIEDERLAGE! Der Computer hat gewonnen..\n");
        ret = true;
    }
    else if ( status == bereits_Getroffen) {
        ret = computerSpielZug(true);
        //printf("\n\t Schiff bereits getroffen! - Entwickler hat verpennt das zu vermeiden...\n");
    }
    else {
        printf("\n\t Unbekannter Zustand... Der Entwickler ist immernoch Doof!\n");
    }
    if (!rekursive){
        sleep(3);
        clear();
    }
    return ret;
}
 
bool menschlicherSpielZug(int debugx, int debugy) {
    showFieldHeader();
    if (mode == 3) zeigeSpielFeld(false);
    else zeigeSpielFeld(true);
    int nextx;
    if (debugx == -1){
        do {    // Nested Loop, hurray!
            printf("\n\t Naechster Zug: X Koordinate: ");
            scanf("%d", &nextx);
            nextx--;
            if (nextx > sizeX-1)
            {
                printf("\tDie X Koordinate ist zu gross!\n");
            } else if (nextx < 0) {
                printf("\tDie X Koordinate ist zu klein!\n");
            } else {
                break;
            }
        } while (1);
    } else nextx = debugx;
    int nexty;
    if (debugy == -1) {
        do {    // Nested Loop again, hurray!
            printf("\n\t Naechster Zug: Y Koordinate: ");
            scanf("%d", &nexty);
            nexty--;
            if (nexty > sizeY-1)
            {
                printf("\tDie Y Koordinate ist zu gross!");
            } else if (nexty < 0) {
                printf("\tDie Y Koordinate ist zu klein!");
            } else {
                break;
            }
 
        } while (1);
    } else nexty = debugy;
    if (mode == 3 || mode == 4) printf("X: %d - Y: %d", nextx, nexty);
    int status = macheSpielZug(nextx, nexty);
    clear();
    showFieldHeader();
    if (mode == 3) zeigeSpielFeld(false);
    else zeigeSpielFeld(true);
    if (status == treffer) {
        printf("\n\t TREFFER! - Gegnerisches Schiff versenkt!\n");
    } else if (status == daneben) {
 
        printf("\n\t Daneben! - Leider nur Wasseratome getroffen!\n");
    } else if (status == bereits_Daneben) {
        printf("\n\t Immernoch Daneben! - Hier ist nach wie vor kein Schiff!\n\t\t\tNeuer versuch!\n");
        sleep(2);
        clear();
        return menschlicherSpielZug(debugx, debugy);
    } else if (status == player1_Gewonnen) {
        printf("\n\t SIEG! Spieler 1 Hat gewonnen!!\n");
        return true;
    } else if (status == player1_Verloren) {
        if(mode == 1) printf("\n\t NIEDERLAGE! Der Computer hat gewonnen..\n");
        else printf("\n\t SIEG! Spieler 2 Hat gewonnen!!\n");
        return true;
    }
    else if ( status == bereits_Getroffen) {
        printf("\n\t Schiff bereits getroffen! - Die sind doch bereits alle tot!...\n\t\t\tNeuer Versuch!");
        sleep(2);
        clear();
        return menschlicherSpielZug(debugx, debugy);
    }
    else {
        printf("\n\t Unbekannter Zustand... Der Entwickler ist Doof!\n");
    }
    sleep(2);
    clear();
    return false;
}
 
int macheSpielZug (int zugX, int zugY) {
    int status = -1;
    if (spieler1AmZug) status = spielFeldGegner[(zugX*10)+zugY];
    else status = spielFeldPlayer[(zugX*10)+zugY];
    if (status == schiff) {
        if (spieler1AmZug) {
            spielFeldGegner[(zugX*10)+zugY] = treffer;
            gegnerShipsLeft--;
            if(gegnerShipsLeft == 0) return player1_Gewonnen;
        }
        else {
            spielFeldPlayer[(zugX*10)+zugY] = treffer;
            playerShipsLeft--;
            if(playerShipsLeft == 0) return player1_Verloren;
        }
        return treffer;
    }
    else if (status == daneben) return bereits_Daneben;
    else if (status == wasser) {
        if (spieler1AmZug) spielFeldGegner[(zugX*10)+zugY] = daneben;
        else spielFeldPlayer[(zugX*10)+zugY] = daneben;
        return daneben;
    }
    else if (status == treffer) return bereits_Getroffen;
}
 
void generiereSpielFeld(bool istSpieler1) {
    int totalShipps = 0;
    /*for (int x = 0; x < sizeX; x++)
    {
        for (int y = 0; y < sizeY; y++)
        {
            if(istSpieler1) spielFeldPlayer[x][y] = 0;
            else spielFeldGegner[x][y] = 0;
        }
    }*/
    for (int k = 0; k<maxShips; k++) {
        int x = rand() % sizeX;
        int y = rand() % sizeY;
        if(istSpieler1)
        {
            if (spielFeldPlayer[(x*10)+y] != schiff) {
                spielFeldPlayer[(x*10)+y] = schiff;
                playerShipsLeft++;
            }
            else k--;
        } else {
            if (spielFeldGegner[(x*10)+y] != schiff) {
                spielFeldGegner[(x*10)+y] = schiff;
                gegnerShipsLeft++;
            }
            else k--;
        }
    }
 
}
 
void zeigeSpielFeld(bool nurGetroffen)
{
    for (int y = 0; y < sizeY; y++)
    {   
        for (int x = 0; x < sizeX; x++)
        {
            // AußenBorder Start
            if (x == 0 && y == 0){
                printf("\n\t\t# X ");
                for (int k = 0; k < sizeX; k++)
                {
                    printf("%d ", k+1);
                }
                printf("\n\t\tY\n\t\t1   ");
            }
            if (x == 0 && y != 0)
            {
                printf("\t\t%d   ", y + 1);
            }
            // AußenBorder Ende
            // Spielfeld Zeichnen Start
            int toPrint = -1;
            if(spieler1AmZug) toPrint = spielFeldGegner[(x*10)+y];
            else toPrint = spielFeldPlayer[(x*10)+y];
            if (nurGetroffen){
                if(toPrint == schiff) toPrint = wasser;
            }
 
            switch (toPrint)
            {
                case wasser:    printf(wasser_Icon); break;
                case daneben:   printf(daneben_Icon); break;
                case treffer:   printf(treffer_Icon); break;
                case schiff:    printf(schiff_Icon); break;
            }
            // Spielfeld Zeichnen Ende
 
        }
        //int temp;
        //scanf("%d", &temp);
        printf("\n");
    }
}
 
int main() {
    // Variablen Initialisieren
 
    
    // Modi: 0 - Ungenutzt, 1 - gegen KI, 2 - 2 Spieler, 3 - Testmodus, 4 - Ein Feld automatisch ausfüllen. 
    bool spielVerlassen = false;
 
    int debugx = 0;
    int debugy = 0;
    srand(time(NULL)); // Wir setzten einen Seed für den Zufallsgenerator.
    clear();
    printf("**********************************\n");
    printf("* \"Schiffe\" versenken! Oder so...*\n");
    printf("**********************************\n\n");
    printf("\t\t Hauptmenue:\n");
    printf("\t1) Neues Spiel (gegen KI)\n");
    printf("\t2) Neues Spiel (2 Spieler Modus)\n");
    printf("\t3) Testmodus\n");
    printf("\t4) Autofill\n");
    printf("\n\t0) Spiel Beenden\n");
    printf("\n\tAuswaehlen: ");
    int hauptMenue = 1;
    scanf("%d", &hauptMenue);
 
    switch (hauptMenue)
    {
        case 1: mode = 1; break;
        case 2: mode = 2; break;
        case 3: mode = 3; break;
        case 4: mode = 4; break;
        case 0: return 0; break; // break ist echt voll super sinnvoll hier. Echt jetzt... nicht ...
    }
    timeSinceStart = (int)time(NULL);
    clear();
    //generiereSpielFeld(false);
    if(mode != 3 && mode != 4){
        //printf("Generiere Spielfelder:");
        //printf("\n\t- Spieler 1 Komplett -");
        generiereSpielFeld(true); // Wir generieren für den Spieler das Spielfeld
        //if (mode == 1) printf("\n\t- KI-Gegner Komplett - \n");
        //else printf("\n\t- Spieler 2 Komplett - \n");
        generiereSpielFeld(false); // Wir generieren für den (KI-)Gegner das Spielfeld
    } else if (mode == 4) generiereSpielFeld(false);
    else printf("\n");
    do {
        if (spieler1AmZug)
        {
            rundenZaehler++;
            if (mode == 4) {
                menschlicherSpielZug(debugx, debugy);
                if (debugx < 7) debugx++;
                else {
                    debugx = 0;
                    debugy++;
                }
                if (debugy == 8)  {
                    spielVerlassen = !spielVerlassen;
                    break;
                }
                //sleep(1);
 
            } else {
                spielVerlassen = menschlicherSpielZug(-1, -1);
                if (mode != 3) spieler1AmZug = !spieler1AmZug;
            }
 
        } else {
            if (mode == 1) {
                spielVerlassen = computerSpielZug(false);
                spieler1AmZug = !spieler1AmZug;
            } else {
                spielVerlassen = menschlicherSpielZug(-1, -1); // Mode ist total sinnlos hier... | Wir das das Spielfeld von Spieler 1.
                spieler1AmZug = !spieler1AmZug;
            }
        }
    } while(!spielVerlassen);
    return 0;
}

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎