Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
NOVATEK-ELECTRO POLSKA SP. Z O.O.NOVATEK-ELECTRO POLSKA SP. Z O.O.
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

pascal wczytywanie pliku txt

10 May 2008 20:07 11287 30
  • Level 9  
    Witam mam do napisania grę pacman w pascalu w trybie tekstowym, która ma wczytywać plansze z pliku tekstowego. Plansza ma mieć 50 wersów i 80 kolumn.
    Postanowiłem ze dobrym rozwiązaniem bedzie wczytanie planszy w tablice 2 wymiarową i od razu na początku pojawiły sie schody bo po wyświetleniu tablicy brakuje w ostatnim wersie paru znaków. Oto kod programu znaczy samo wczytywanie z pliku i wyświetlanie.
    Code:

    Program pac;
    uses crt;
    var
    plansza:text;
    tab:array[1..50,1..80] of char;
    i,d:integer;

    begin
    clrscr;
    assign(plansza,'C:/Users/Radek/Documents/plansza1.txt');
    reset(plansza);
    for i:=1 to 50 do
             for d:=1 to 80 do
                    read(plansza, tab[i,d]);
    close(plansza);
    for i:=1 to 50 do
             for d:=1 to 80 do
                    write(tab[i,d]);
    readln;
    end.

    z góry dziękuje za pomoc.
  • NOVATEK-ELECTRO POLSKA SP. Z O.O.NOVATEK-ELECTRO POLSKA SP. Z O.O.
  • Level 14  
    Może sprawdź plik, z którego wczytujesz plansze.
  • Level 29  
    Po pierwsze to w najlepszym wypadku będzie brakowało całej ostatniej linii, bo po napisaniu ostatniego znaku w tej linii ekran się automatycznie przewinie do góry ucinając pierwszy wiersz obrazu. Dlatego ostatnią linię lepiej wykorzystać na wyświetlanie wyników itp...
  • NOVATEK-ELECTRO POLSKA SP. Z O.O.NOVATEK-ELECTRO POLSKA SP. Z O.O.
  • Level 12  
    Wczytujesz tablice znakow, czyli spacja tez jest liczona jako znak, znak nowej linii również i te dodatkowe znaki zajmują Ci miejsca w tablicy... jeżeli wiesz dokładnie ile w pliku masz wierszy i kolumn, do tego jeżeli wiesz jaka jest szerokość danej kolumny to zwiększ rozmiar tablicy żeby nie było 80 w wierszu tylko jak kolumna ma szerokość 1 znaku to zrób 2 razy więcej, czyli 160 bo miedzy każdym znakiem jest spacja, a po ostatnim enter, jeżeli kolumna jest szersza to sobie policz ile trzeba, pamietajac ze 1 znak kolumny to 1 element w tablicy... Jezeli nie wiesz jaka jest szerokość kolumny to sporbuj ifami sprawić aby nie czytal spacji i enterow (zeby nie bylo entera chyba trzeba bedzie ord(wczytany znak)<>13, spacja wystarczy znak<>' ')... no chyba ze to co czytasz to liczby to tylko zmien typ tablicy na integer czy cos i wtedy bedzie działac bez dodatkowych zmian, poza zmiana w typu tablicy i malego ulepszenia w wyswietlaniu pozniej... chociaż z wyświetlaniem tak jak napisał kolega wyżej będziesz miał problem, bo na ekranie mieści sie chyba 25 linii, a Ty chcesz wyświetlić 2 razy więcej (z komulnamie pewnie podobnie, nie wiem nie wiem dokladnie ile kolumn sie miesci), czyli nie dasz rady, z wierszami da sie rozwiazac ze jak wyswietlasz to gdy i:=25 to czyścisz ekran, albo jakas petla zeby czekal na enter czy cos... :]
  • Level 42  
    Lepos:
    1. Skąd przypuszczenie, że po każdym znaku jest spacja?
    2. Znak nowej linii w standardzie kodowania DOS, to dwa znaki - #10#13
    Nie trzeba zmieniać rozmiaru tablicy, lecz:
    1. Wczytywać do niej wyłącznie poprawne znaki
    2. Wyświetlać w sposób, ktory spowoduje zachowanie wierszy, a więc po każdym wyświetlonym wierszu program powinien dostawiać znak załamania linii (czyli entera).
  • Helpful post
    Level 16  
    Witam.

    A może coś takiego:
    Code:
    Program pac; 
    
    uses crt;
    var
    plansza:text;
    linia:string;
    tab:array[1..50,1..80] of char;
    i,d:integer;

    begin
    clrscr;
    assign(plansza,'C:/Users/Radek/Documents/plansza1.txt');
    reset(plansza);
    for i:=1 to 50 do
    begin
             readln(plansza,linia)
             for d:=1 to 80 do
                    tab[i,d]:=linia[d];
    end;
    close(plansza);
    for i:=1 to 50 do
    begin
             for d:=1 to 80 do
                    write(tab[i,d]);
             writeln;
    end;
    readln;
    end.
  • Level 12  
    Hmm właściwie racja, jak przeczytałem kolumna to pomyśłałem że są one jakoś oddzielone, ale w sumie jeżeli nie są to wystarczy usunąć żeby nie czytał znaków nowej linii, bo skoro jest 50 wierszy to ucina Ci 49 miejsc z tablicy (chyba że jest tak jak Dżyszla pisze ze znak nowej linii to dwa znaki wtedy 98, a skoro tak mowi to pewnie tak jest). Ze zwiekszeniem rozmiaru tablicy, jezeli mu nie zalezy dokladnie na tym co w niej jest to jest to najprostszy chyba sposob bez dodatkowych przerobek w wyswietlaniu, jednak żeby było zrobione porządnie to powinno się zrobić z wczytaniem pomijając znaki nowej linii, a wyświetlanie zrobić żeby if i mod 8 then writeln; czyli co 8 kolumn przechodzil do nowej lini...
  • Level 9  
    Tak właśnie ucinało mi 49 miejsc czyli znaki nowej lini wczytywało mi do tablicy, wprowadzenie zmiennej linia rozwiązało problem teraz będę zastanawiał sie nad zjadaniem znaków, i liczeniem punktów myślę, że najpierw ustawie sobie znak zjadajac poprzez gotoxy na planszy i wczytam go w to samo miejsce w tablicy, myśle ze na case zrobię sterowanie i to wszystko w repeat, danym znaczkiem bede chodził po tablicy "if"em uwzględnię sciany na które nie moge wejść, tylko się zastanawiam jak zrobić żeby mi wyświetlało moje ruchy na planszy?
  • Level 34  
    Ekran się przewinie, ale akurat interesująca nas kolumna i wiersz będą widoczne, bo są na końcu. Program nie ma błędu. Możesz dodać kontrolę:
    Code:

     for i:=1 to 50 do
      for d:=1 to 80 do
      begin
       read(plik,tab[i,d]);
       if(i=50)then
       write(tab[i,d]);
       end;

    for i:=1 to 50 do
             for d:=1 to 80 do
              begin
              write(tab[i,d])
         if(i=50)then
         write(tab[i,j]);
       end;

    Oba wydruki muszą być takie same.
  • Level 9  
    wiec napisałem sterownie moim pacmanem ale nie chodzi jak powinien, otóż wchodzi w nie tą kolumne co trzeba,choc nie zawsze,potrafi wejsc na znak nie jadalny lub wogóle sie zatrzymuje oto kod
    Code:

    Program pacm;
    uses crt;
    var
    plansza:text;
    linia:string;
    tab:array[1..50,1..80] of char;
    i,d,x,y:integer;
    key,pac,nic:char;



    begin
    clrscr;

    assign(plansza,'C:/Users/Radek/Documents/plansza1.txt');
    reset(plansza);
    for i:=1 to 50 do
    begin
             readln(plansza,linia);
             for d:=1 to 80 do
                    tab[i,d]:=linia[d];
    end;
    close(plansza);
    for i:=1 to 50 do
    begin
             for d:=1 to 80 do
                    write(tab[i,d]);
             writeln;
    end;

    pac:='#';
    nic:=' ';
    tab[2,2]:=pac;
    gotoxy(2,2);
    write(tab[2,2]);
    x:=2; y:=2;
    repeat
        Key := #0; {zerowanie zmiennej klawisza}
        if KeyPressed then begin {jesli wcisnieto klawisz}
          Key := ReadKey; {odczyt klawisza}
          if Key = #0 then begin {kod klawisza strzalki poprzedzony jest znakiem #0}
            Key := ReadKey; {odczyt klawisza}
            case Key of
              #72: {w gore} if (((tab[x,y-1]='.')or(tab[x,y-1]=nic)) and (y>0) and (y<50)) then
                    begin
                    tab[x,y]:=nic;
                    tab[x,y-1]:=pac;
                    gotoxy(x,y);
                    write(tab[x,y]);
                    gotoxy(x,y-1);
                    write(tab[x,y-1]);
                    y:=y-1;
                    end;
              #75: {w lewo} if (((tab[x-1,y]='.')or(tab[x-1,y]=nic)) and (x>0) and (x<80)) then
                    begin
                    tab[x,y]:=nic;
                    tab[x-1,y]:=pac;
                    gotoxy(x,y);
                    write(tab[x,y]);
                    gotoxy(x-1,y);
                    write(tab[x-1,y]);
                    x:=x-1;
                    end;
              #77: {w prawo} if (((tab[x+1,y]='.')or(tab[x+1,y]=nic)) and (x>0) and (x<80)) then
                    begin
                    tab[x,y]:=nic;
                    tab[x+1,y]:=pac;
                    gotoxy(x,y);
                    write(tab[x,y]);
                    gotoxy(x+1,y);
                    write(tab[x+1,y]);
                    x:=x+1;
                    end;
              #80: {w dol} if (((tab[x,y+1]='.')or(tab[x,y+1]=nic)) and (y>0) and (y<50)) then
                    begin
                    tab[x,y]:=nic;
                    tab[x,y+1]:=pac;
                    gotoxy(x,y);
                    write(tab[x,y]);
                    gotoxy(x,y+1);
                    write(tab[x,y+1]);
                    y:=y+1;
                    end;
            end;

          end;
        end;
      until Key = #27; {Esc wychodzi}




    end.

    w załączniku plansza narqzie nie za skąplikowana ale to jest akurat do dopracowania.
  • Level 34  
    Przeanalizuj kod który zamieszczam. Najpierw jest tworzony plik array.txt w głównym katalogu dysku c: i do niego wpisane są znaki. Potem plik jest otwierany, odczytywany i wyświetlany na ekranie. Chyba o to Ci chodziło. Twojego kodu nie analizowałem, bo chcę oglądnąć Formułę1.
    Code:

    uses crt;
    var i,j:integer;
        plik:text;
        tab:array[1..10,1..10]of char;
        tab1:array[1..10,1..10]of char;
    begin
     clrscr;
     writeln('zawartosc tablicy');
        for i:=1 to 10 do
        for j:=1 to 10 do
         begin
        tab[i,j]:=char(60+i+j);
        write(tab[i,j]);
        end;
        writeln;
        readkey;
      writeln('odczyt z pliku');
     assign(plik,'c:\array.txt');
     rewrite(plik);
     for i:=1 to 10 do
     for j:=1 to 10 do
     begin
     write(plik,tab[i,j]);
     end;
     close(plik);
     assign(plik,'c:\array.txt');
     reset(plik);
      for i:=1 to 10 do
      for j:=1 to 10 do
      begin
       read(plik,tab1[i,j]);
       write(tab1[i,j]);
       end;
       close(plik);
       readkey;
    end.
  • Level 9  
    Nie o to chodzi tą kwestie już rozwiązałem...
  • Level 42  
    co do zatrzymywania, to nie jest tak, że przy brzegach ekranu? Załóżmy jesteś na x=79, więc mozesz iść w prawo, idziesz w prawo na x=80 i w tym momencie warunki ruchu poziomego już nigdy nie zostaną spełnione. Określ dostępny obszar wg pozycji przyszłej, a nie bieżącej. Ponadto nie ma potrzeby sprawdzać przy ruchu w prawo, czy nie jest poza lewą krawędzią. Analogicznie reszta przypadków.

    Co do wchodzenia nie w tą kolumnę to nie wiem - debugowałeś może program?
  • Level 9  
    nie debugowałem, a z tymi ograniczeniami masz racje stwierdziłem ze w sumie one nie są potrzebne bo samo założenie nastepnego elementu wystarczy, wyrzuciłem je i teraz sie juz nie zatrzymuje ale wchodzi w wiersze i linie niezjadalne choc nie wszystkie jak również w nie wszystkie zjadalne
  • Helpful post
    Level 42  
    A generlanie co to za tryb 50 wierszowy?

    Pomyliłeś wiersze z kolumnami.

    To od razu kilka porawek:

    Code:

    Program pacm;
    uses crt;
    var
    plansza:text;
    linia:string;
    tab:array[1..80,1..50] of char;
    i,d,x,y,nextx,nexty:integer;
    key,pac,nic:char;



    begin
    clrscr;

    assign(plansza,'plansza1.txt');
    reset(plansza);
    for i:=1 to 50 do
    begin
             readln(plansza,linia);
             for d:=1 to 80 do
                    tab[d,i]:=linia[d];
    end;
    close(plansza);
    for i:=1 to 24 do
    begin
             for d:=1 to 80 do
                    write(tab[d,i]);
             {writeln;}
    end;

    pac:='#';
    nic:=' ';
    tab[2,2]:=pac;
    gotoxy(2,2);
    write(tab[2,2]);
    x:=2; y:=2;
    repeat
        Key := #0; {zerowanie zmiennej klawisza}
        if KeyPressed then begin {jesli wcisnieto klawisz}
          Key := ReadKey; {odczyt klawisza}
          if Key = #0 then begin {kod klawisza strzalki poprzedzony jest znakiem #0}
            Key := ReadKey; {odczyt klawisza}
            nextx:=x;
            nexty:=y;
            gotoxy(1,25); write(x,' - ',y);
            case Key of
              #72: dec(nexty);
              #75: dec(nextx);
              #77: inc(nextx);
              #80: inc(nexty);
            end;
            if (nextx<>x) or (nexty<>y) then begin
               if (nextx in [1..80]) and (nexty in [1..50]) and (tab[nextx,nexty] in ['.',nic]) then
                    begin
                    tab[x,y]:=nic;
                    gotoxy(x,y);
                    write(tab[x,y]);
                    x:=nextx; y:=nexty;
                    gotoxy(x,y);
                    tab[x,y]:=pac;
                    write(tab[x,y]);

                    end;
            end;
          end;
        end;
      until Key = #27; {Esc wychodzi}




    end.

    Ograniczyłem jednak do wyświetlania 24 linii - msuiałbyś programowo wymusić zmianę trybu wyświetlania, bo standardowe rozmiary to 80x25, przy czym linia 25 jest traktownaa ijako informacyjna i nie można się na nią dostać inaczej, niże przez gotoxy.
  • Level 9  
    Tak zauważyłem że standard to 80x25 po prostu zawsze uruchamiałem z kompilatora i po pierwszym uruchomieniu rozciągałem okno i już ono takie zostawało. Co do kodu kawałek warunku który sprawdza czy współrzędne mieszczą się w tablicy znaczy pozycja elementu są zbyteczne wystarczy założenie o zawartości elementu następnego elementu. Teraz dopisze licznik i warunek zakończający gre. Jedynie mam jeszcze pytanie jeżeli bym chciał zrobić potwora polującego na pacmana to musiał zadeklarować 2 tablice o identycznych wymiarach i określić jego ruch. zastanawia mnie jak zrobić żeby się on poruszał niezależnie od ruchu pacmana i porównywał jednocześnie położenie
  • Level 42  
    Generalnie co któryś przeskok pętli musiałbyś dokonać ruchu potwora. Nie potrzebujesz drugiej tablicy - można spokojnie oprzeć na tej istniejącej. Potrzebujesz wyłącznie pamiętać jego współrzędne (dla wygody).
    Jeśli byś chciał, aby gonił on pacmana, to musiałbyś zastosować algorytm budowania trasy (podobny do tego wykorzystywanego w szelkiego rodzaju mapach bądź grach RTS) - http://www.policyalmanac.org/games/aStarTutorial_pl.htm
  • Level 9  
    Jeszcze nie ruszyłem potwora bo mam problem z zakończeniem programu, napisał również licznik wyniku.Liczba punktów ma się zmieniać zależnie od upływu czasu, stwierdziłem że napisze funkcje która liczy pozostałe elementy zjadalne i dodałem licznik ruchów.gdyż stwierdziłem że im więcej ruchów tym czas rośnie. Wszystko działa dobrze, tylko mnie zastanawia czy istnieje funkcja która liczy czas w sekundach trwania programu nie zależnie czy program coś robi czy nie i zwraca ta funkcja wartość liczbową. Teraz mam problem z kończeniem programu, gdyż wcześniej miałem ustawiony tylko klawisz który przerywał pętle teraz chciałem dodać żeby program również kończył się jeżeli moja funkcja licząca pozostałe elementy zjadalne zwróciła wartość 0, po dodaniu tego warunku kompilator ma konflikt typów, znaczy nie pasuje mu typ znakowy do odczytu klawisza.
  • Level 37  
    Jeśli już robisz planszę do gry to zapisz to jako 'zrzut ekranu' (tablica->litera:atrybuty), wczytuj i zapisuj do tablic przez blockread i blockwrite, używaj do wyświetlania bezpośredniego 'przerzucenia' tablicy ze screenem na pamięć ekranu (lub bufora).
  • Level 42  
    Fyszo - wyświetlenie całej planszy nie jest tak istotne ze względów optymalizacyjnych, a reszta to już tylko podmienianie pojedynczych znaków. Moim zdaniem bezpośredni dostęp do pamięci ekranu dla autora jest zbyt wysoką jazdą:)
  • Level 9  
    Jest dobrze jak jest:) grę pisze na zaliczenie przedmiotu o nazwie podstawy programowania więc nie ma co się porywać. Wracając do tematu uporałem się z licznikiem czasowym skorzystałem z modułu dos i funkcji gettime.
    Napisałem potwora ale nie na podstawie algorytmu astar. Mój algorytm miał polegać na tym że na początu umieszczam potwora w danym miejscu na ekranie i tablicy zresztą tak jak pacman następnie używam funki random(2)-1 (wynik 1,0,-1która ma losować nowe współrzędnej potwora. Wszystko jest w pętli repeat która kończy swoje działanie gdy wylosowana współrzędna spełnia warunek że w niej jest znak jadalny,nic lub pacman następnie sprawdza warunek jaki jest to dokładnie znak dla poszczególnych znaków działa analogicznie jak algorytm poruszający pacmana, jeszcze nie ruszałem opcji spotkania z pacmananem, mój potwór idzię na przemian z pacmanem ale jak zrobi ruch w pion to zaczyna skakać co drugie pole i jedno zjada kropki pomiędzy nimi aż zatrzymuje program, zastanawiam co jest żle i co zrobić żeby potwór poruszał się nie zależnie od pacmana
    oto kod potwora;
    Code:

    pot:='%';
            tab[78,49]:=pot;
            gotoxy(78,49);
            write(tab[78,49]);
            xp:=78;
            yp:=49;

    begin

                    nextxp:=xp;
                    nextyp:=yp;
                    repeat
                           zmx:=random(2)-1;
                           zmy:=random(2)-1;
                    until (tab[nextxp+zmx,nextyp+zmy] in ['.',nic,pac]);
                    gotoxy(1,1);
                    write(zmx,' ',zmy);
                    nextxp:=nextxp+zmx; nextyp:=nextyp+zmy;
                            if (tab[nextxp,nextyp] in ['.']) then
                            begin
                                    tab[xp,yp]:='.';
                                    gotoxy(xp,yp);
                                    write(tab[xp,yp]);
                                    xp:=nextxp; yp:=nextyp;
                                    gotoxy(xp,yp);
                                    tab[xp,yp]:=pot;
                                    write(tab[xp,yp]);
                            end;
                            if (tab[nextxp+zmx,nextyp+zmy] in [' ']) then
                            nextxp:=nextxp+zmx; nextyp:=nextyp+zmy;
                            begin
                                    tab[xp,yp]:=nic;
                                    gotoxy(xp,yp);
                                    write(tab[xp,yp]);
                                    xp:=nextxp; yp:=nextyp;
                                    gotoxy(xp,yp);
                                    tab[xp,yp]:=pot;
                                    write(tab[xp,yp]);
                            end;

    wszystko jest w tej pętli co sterowanie pacmanem
  • Level 42  
    1. Pozwalasz potworowi poruszać się po skosie ;) Lepiej byłoby wylosować kierunek (1-4; odpowiednio np.: GPDL) a następnie ustawić nowe współrzędne.

    2. Prościej będzie ,aby do obsługi potwora było tot tak: Musiałbyś zapamiętywać stan pola, na jaki wszedł, aby odtwarzać go po wyjściu. Wtedy nie będziesz musiał zapisywać ifów (który notabene w Towim rozwarzaniu powinien być w alternatywnie do pierwszego i uwzględniać poprawne współrzędne - dałeś dwukrotny skok.
  • Level 9  
    wiec napisałem tak:
    Code:

     nextxp:=xp;
            nextyp:=yp;

            kierunek:=random(3);
            gotoxy(1,1);
              write(kierunek);

                    case kierunek of
                    0: dec(nextyp);
                    1: dec(nextxp);
                    2: inc(nextxp);
                    3: inc(nextyp);
                    end;
            if (nextxp<>xp) or (nextyp<>yp) then begin
            if (tab[nextxp,nextyp]='.') then
            begin
                    tab[xp,yp]:='.';
                    gotoxy(xp,yp);
                    write(tab[xp,yp]);
                    xp:=nextxp; yp:=nextyp;
                    gotoxy(xp,yp);
                    tab[xp,yp]:=pot;
                    write(tab[xp,yp]);
            end;
            if (tab[nextxp,nextyp]=nic) then
            begin
                    tab[xp,yp]:=nic;
                    gotoxy(xp,yp);
                    write(tab[xp,yp]);
                    xp:=nextxp; yp:=nextyp;
                    gotoxy(xp,yp);
                    tab[xp,yp]:=pot;
                    write(tab[xp,yp]);
            end;
    end;


    wiec potwór sie porusza choć troche dziwnie ale sie porusza:) teraz chciałbym to dać w pętle którą by przerywało wciśnięcie klawisza który jest następnie przekazywany do ruchu pacmana, jeśli klawisz nie został wciśnięty to potwór się porusza
  • Level 9  
    pętla nie istnieje znaczy nie istniała bo warunkiem do odpalenia głównej pętli było keypressed ale już zrobiłem warunek repeat until keypressed; i działa ale potwór biega strasznie szybko jeżeli użyłem procedury delay lub skorzystałem z mojej funkcji pobierania czasu
    która pobiera aktualną godzine to miałem problem moim pacmanem wjechanie w kolumnie miedzy dwoma nie jadalnymi:(
  • Level 42  
    jak to? przecież pętla krążyła Ci cały czas, a Keypressed powodował spełnienie warunku IF. Wystarczyło kod odpowiedzialny za poruszanie potwora zawrzeć w drugim ifie, dla którego warunkiem byłby czas (jeśli minęło 200ms, odpalamy, zapisujemy czas, czekamy na minięcie 200 ms. i tak w kółko).
    Code:

    repeat
       if keypressed then
          ruchaj_pacmana;
       if GetMicroTime-SavedMicroTime>200 then begin
          SavedmicroTime:=GetMicroTime;
          ruchaj_monstera;
       end;
    until False;

    (W założeniach GetMicroTime daje Ci bieżacy czas wyrażony w milisekundach (może być z dokładnością do doby myślę czyli (((h*60)+m)*60+s)*100+ms))
  • Level 9  
    to rozumie tylko tych funkcji nie ma w moich modułach a mam zadeklarowane crt i dos, wujek google te funkcje łączył z php, ale chyba potrafię napisać taką funkcje bynajmniej spróbuje
    Code:

    function mikro:longint;
    var
      godz,min,sek,sek100:word;
    begin
        gettime(godz, min,sek,sek100);
        mikro:=((((godz*60)+min)*60+sek)*100+sek100);
    end;