Program konsolowy z planszą wczytywaną z pliku, problem (C++)


(Igorbugajski2) #1

Witam.

Otóż chciałem sobie zrobić w konsoli program wyświetlający planszę, po której można się poruszać klawiszami WASD.

Wyszło mi to, potem zrobiłem jeszcze ściany itd. I wszystko działało, póki nie wymyśliłem sobie, żeby program wczytywał mapę z pliku.

Otóż tak wygląda zawartość pliku tekstowego:

http://www.wklej.org/id/1477423/txt/

To natomiast widzę w programie:

 

Tutaj jest kod programu: (przepraszam za ewentualny niemiły język w kodzie)

#include <iostream>
#include <cstdlib>
#include <cctype>
#include <conio.h>
#include <fstream>

using namespace std;

char teren[20][50];
char gunwo[1000];
int userp1 = 5, userp2 = 5;
char opcja;
fstream plik;

int main()
{
    plik.open("map.txt", ios::in);
    if(plik.good()==true)
    {
        plik.read(gunwo, 1000);
        plik.close();
    }
    else
    {
        cout << "Niestety, panowie z obslugi usera byli zbyt zmeczeni i nie udalo im sie zaladowac pliku z mapa." << endl;
        getch();
        cout << "Nie! Nie! Zaraz! Nowe informacje! Plik jest do dupy i nie nadaje sie do wczytania!" << endl;
        getch();
        exit(666);
    }

    int pluus = 0;
    for(int i=0; i<20; i++)
    {
        for(int j=0; j<50; j++)
        {
            teren[i][j] = gunwo[j+pluus];
        }
        pluus = pluus+50;
    }

    while(true)
    {
        system("cls");

        teren[userp1][userp2] = '0';

        for(int i=0; i<20; i++)
        {
            for(int j=0; j<50; j++)
            {
                cout << teren[i][j];
            }
            cout << endl;
        }

        opcja = getch();
        opcja = tolower(opcja);

        switch(opcja)
        {
            case 'w':
            {
                if(teren[userp1-1][userp2]!='1')
                {
                    userp1--;
                }
                if(teren[userp1-1][userp2]='>')
                {
                    exit(666);
                }
                break;
            }
            case 'a':
            {
                if(teren[userp1][userp2-1]!='1')
                {
                    userp2--;
                }
                if(teren[userp1][userp2-1]='>')
                {
                    exit(666);
                }
                break;
            }
            case 's':
            {
                if(teren[userp1+1][userp2]!='1')
                {
                    userp1++;
                }
                if(teren[userp1+1][userp2]='>')
                {
                    exit(666);
                }
                break;
            }
            case 'd':
            {
                if(teren[userp1][userp2+1]!='1')
                {
                    userp2++;
                }
                if(teren[userp1][userp2+1]='>')
                {
                    exit(666);
                }
                break;
            }
            default:
            {
                break;
            }
        }
    }

    return 0;
}

Jestem absolutnie pewien, że problem jest w miejscu, w którym próbuję przenieść dane z jednowymiarowej tablicy gunwo do dwuwymiarowej tablicy teren, mianowicie w tym miejscu:

int pluus = 0;
    for(int i=0; i<20; i++)
    {
        for(int j=0; j<50; j++)
        {
            teren[i][j] = gunwo[j+pluus];
        }
        pluus = pluus+50;
    }

Oraz że to ma związek ze zmienną pluus, jednak nie wiem za bardzo, co sensowniejszego by z nią zrobić. (na pewno nie zwiększać o 49 zamiast 50, ponieważ wtedy wpisywałbym niepotrzebnie dwa razy ten sam znak)


(tomek2102) #2

Witam,

Nakieruję Cię na problem, który wydaje mi się, że jest najbardziej prawdopodobny. Otóż faktycznie powstaje on w miejscu, które wskazałeś i dotyczy długości wiersza odczytywanego z pliku. Otóż skoro w pliku każdą linijkę swojej mapy masz oddzieloną enterem, to ta linijka ma więcej niż 50 znaków. Możesz to łatwo sprawdzić chociażby w Notepad++ włączając podgląd białych znaków. Oddzielenie linijek enterem w windowsie powoduje wstawienie znaku końca linii i powrotu karetki. Nie pamiętam dokładnie jak działa odczytywanie plików w C++, ale chyba tam widndowsowe znaki końca linii były zamieniane na pojedynczy znak “\n”. Tak więc długość linijki w Twoim pliku nie wynosi 50 znaków, ale przynajmniej 51.


(Igorbugajski2) #3

Dziękuję za pomoc, pomogło. :slight_smile:

Zrobiłem też inny błąd w innej części kodu, (dotyczący czegoś innego), ale już go poprawiłem.