Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
Roshun
Sędziwy Jeż
Posty: 31 Rejestracja: 07 cze 2012, 18:25
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Środowisko graficzne: Unity
Architektura: x86_64
Lokalizacja: Białystok
Kontakt:
Post
autor: Roshun » 30 sty 2014, 22:40
Witam. Nie jestem jakimś orłem w programowaniu, więc różnie mi to idzie. Ostatnio w szkole zadano nam napisanie gry w C++. Do wyboru było kilka między innymi poczciwy wisielec
Jednak pojawiło się kilka problemów. Otóż nie wiem z jakiego powodu program się zapętla, w jednym miejscu (prawdopodobnie złe zliczanie zmiennych bądź zły warunek w pętli), oraz nie wiem z jakiego powodu dodaje dodatkowy znak '_'. Jeśli znalazłby się na forum ktoś kto potrafiłby to naprawić, i wytłumaczyć mi gdzie zrobiłem błąd, byłbym bardzo wdzięczny. W kodzie zamieściłem komentarze, aby był chociaż trochę bardziej czytelny
Kod: Zaznacz cały
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <cstdlib>
#include <string.h>
using namespace std;
string slowo, podawane; // 1. słowo z pliku 2. to które będziemy podawać
void kategoria()
{
int help=0, ktore=1; // 2 zmienne pomocnicze
char a; // zmienna do menu
cout<<"Wybierz kategorie:"<<endl<<"1 - INFORMATYKA"<<endl<<"2 - ZWIERZETA"<<endl<<"3 - ROSLINY"<<endl<<"4 - ZIMA"<<endl<<"5 - LATO"<<endl<<"6 - INNE"<<endl<<"(Jesli nie otrzymasz potwierdzenia wybierz jeszcze raz)"<<endl<<"Wybieram kategorie: "<<endl;
switch(a=getchar())
{
case '1':
cout<<"Wybrales kategorie: INFORMATYKA"<<endl;
ktore=1;
break;
case '2':
cout<<"Wybrales kategorie: ZWIERZETA"<<endl;
ktore=2;
break;
case '3':
cout<<"Wybrales kategorie: ROSLINY"<<endl;
ktore=3;
break;
case '4':
cout<<"Wybrales kategorie: ZIMA"<<endl;
ktore=4;
break;
case '5':
cout<<"Wybrales kategorie: LATO"<<endl;
ktore=5;
break;
case '6':
cout<<"Wybrałes kategorie: INNE"<<endl;
ktore=6;
break;
default:
help++;
break;
}
if(help==1) {
system("clear");
kategoria();
}
int p; // potem do przerywania czytania wyrazu z pliku losowana przez komputer
if(ktore==1) { ifstream wej("informatyka"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
}
}
if(ktore==2) { ifstream wej("zwierzeta"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
}}
if(ktore==3) { ifstream wej("rosliny"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
} }
if(ktore==4) { ifstream wej("zima"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
}}
if(ktore==5) { ifstream wej("lato"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
} }
if(ktore==6) { ifstream wej("inne"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
}}
cout<<slowo<<endl; // dla sprawdzenia poprawnosci przeczytania przez program
}
void pregame()
{
int b=slowo.size();
podawane.clear(); // czyszczenie zawsze bezpieczniej i pewniej
for(int i=0; i<b; i++) podawane=podawane+'_'; // podstawienie pod nieznane litery znaku '_'
}
void game()
{
int kri; // zmienna zliczająca chybienia
char znak; // znak podawany
int b=slowo.size(); // długość słowa juz raz wystąpila ale nie chce zmieniac zeby sie nie pomylic
while(kri!=6) // warunek dalszej gry
{
cout<<podawane<<endl; // nasz wyraz zastapiony znakami '_'
cout<<"Podaj znak"<<endl;
znak=getchar();
if(slowo.find(znak)==0) { kri++; continue; } // jesli znak nie wystepuje zwiększamy zmienną porażki
for(int i=0; i<b; i++) // petla podstawiajaca trafione litery do naszego stringa
{
if(slowo[i]==znak) podawane[i]=znak;
}
system("clear");
}
if(kri==6) cout<<"PRZEGRALES"<<endl;
}
int main()
{
srand(time(NULL));
// tu bedzie while - menu glowne
kategoria();
pregame();
game();
return 0;
}
Poza tym pozostaje zrobienie menu ale to już łatwo da się zrobić na switchu.
P.S
Ma ktoś jakiś pomysł rysowania szubienicy?
TrolleY
Serdeczny Borsuk
Posty: 160 Rejestracja: 06 cze 2013, 12:40
Wersja Ubuntu: inny OS
Środowisko graficzne: Inne
Architektura: x86_64
Post
autor: TrolleY » 30 sty 2014, 23:43
Funkcja kategorie() jest delikatnie mówiąc nieczytelna. Masz tam całkowicie zbędną rekurencję (wywołujesz w niej po raz kolejny funkcję kategorie co jest w tym przypadku niepoprawne nawet jeśli działa). Skoro masz już tą zmienną help=0 to powinieneś mieć coś w tym stylu:
Kod: Zaznacz cały
int help=0;
while(help!=1)
{
twoje switche
gdy wszystko jest ok to ustawiasz help=1
}
Tak nawiasem tych switchy można też uniknąć i skrócić kod do ok 3 linijek ale byłoby to pewnie dla ciebie mocno nieczytelne więc można to zostawić jak jest.
Zwróciłem uwagę tak na szybko jeszcze na użycie metody find() z klasy string, której używasz przy sprawdzeniu czy litera należy do słowa. Wg reference:
http://www.cplusplus.com/reference/string/string/find/
jak nie znajdzie podnapisu to zwraca string::npos czyli -1 a nie 0.
Powód dla którego wyświetla za dużo '_'? Myślałem, że metoda size() liczy razem ze znakiem końca napisu 0 ale wg reference tak nie jest, więc podejrzewam, że coś źle sczytuje z pliku.
Linux Mint 17 + Cinnamon (x64) / Windows 7 (x64)
Roshun
Sędziwy Jeż
Posty: 31 Rejestracja: 07 cze 2012, 18:25
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Środowisko graficzne: Unity
Architektura: x86_64
Lokalizacja: Białystok
Kontakt:
Post
autor: Roshun » 31 sty 2014, 11:20
Poprawiłem funkcje katergorie(), tak jak pisałeś, zbyt często kombinuje i zapominam o prostych sposobach na rozwiązanie problemu.
Program zaczął przyjmować pierwszą literę wyrazu, więc jeden problem załatwiony. Wy-edytowałem pliki tekstowe jeszcze raz. Jednak nadal nie zlicza odpowiednio zmiennej odpowiadającej za koniec gry. Zmodyfikowałem warunek, aby porównywało z "-1" jednak nadal nic się nie dzieje.
Kod: Zaznacz cały
void game()
{
int kri;
char znak;
int b=slowo.size();
while(kri!=6)
{
system("clear");
cout<<podawane<<endl;
cout<<"Podaj znak"<<endl;
znak=getchar();
if(slowo.find(znak)==-1) {kri++; continue;}
for(int i=0; i<b; i++)
{
if(slowo[i]==znak) podawane[i]=znak;
}
system("clear");
}
if(kri==6) cout<<"PRZEGRALES"<<endl;
}
Kompilator zwraca jako uwagę (program się normalnie kompiluje i uruchamia)
Kod: Zaznacz cały
gra.cpp:117:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
Linijka z metodą find()
Odnośnie zastąpienia switch'y jakby to wyglądało?
ethanak
Wygnańcy
Posty: 3054 Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:
Post
autor: ethanak » 31 sty 2014, 12:19
find jest typu size_t, czyli na mój rozum porównuj z (size_t)-1
przynajmniej tak by było w C. w C++ masz string::npos.
google "c++ string find" i pierwszy wynik...
Кто жопой родился, чижиком не помрёт
enedil
Przebojowy Jelonek
Posty: 1352 Rejestracja: 08 wrz 2012, 16:54
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: i3
Architektura: x86_64
Kontakt:
Post
autor: enedil » 31 sty 2014, 12:25
npos nie oznacza -1, a największą wartość inta, którą można uzyskać na danym komputerze. Dlatego lepiej, żeby porównanie wyglądało tak:
Dobrze jest, psiakrew, a kto powie, że nie, to go w mordę!
~moderatorzy
ethanak
Wygnańcy
Posty: 3054 Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:
Post
autor: ethanak » 31 sty 2014, 12:28
a co oznacza twoim zdaniem (size_t)-1
Кто жопой родился, чижиком не помрёт
Roshun
Sędziwy Jeż
Posty: 31 Rejestracja: 07 cze 2012, 18:25
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Środowisko graficzne: Unity
Architektura: x86_64
Lokalizacja: Białystok
Kontakt:
Post
autor: Roshun » 31 sty 2014, 13:12
W obu przypadkach, nic się nie dzieje. Istnieje może jakiś inny sposób, sprawdzenia czy w wyrazie występuje dany znak?
ethanak
Wygnańcy
Posty: 3054 Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:
Post
autor: ethanak » 31 sty 2014, 13:15
w c jest funkcja strchr - może spróbujesz? zwraca wskaźnik albo NULL czyli może być bezpośrednio użyta w ifie.
Кто жопой родился, чижиком не помрёт
Roshun
Sędziwy Jeż
Posty: 31 Rejestracja: 07 cze 2012, 18:25
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Środowisko graficzne: Unity
Architektura: x86_64
Lokalizacja: Białystok
Kontakt:
Post
autor: Roshun » 31 sty 2014, 13:48
Coś nie wychodzi mi sklejenie tej funkcji do kupy. Zastanawiam się czy coś takiego miałoby sens, sam sposób:
Kod: Zaznacz cały
void game()
{
int kri=0; // po poprawce
char znak;
int b=slowo.size();
while(kri!=6)
{
int help=0;
system("clear");
cout<<podawane<<endl;
cout<<"Podaj znak"<<endl;
znak=getchar();
for(int i=0; i<b; i++)
{
if(slowo[i]==znak) {
podawane[i]=znak;
help++;
}
}
if(help==0) kri++;
system("clear");
}
if(kri==6) cout<<"PRZEGRALES"<<endl;
}
EDIT
Heh błąd młodego "programisty" brak wyzerowania kri przy deklaracji. Teraz problem wygląda tak że po 3 złych próbach wychodzi z while, o trzy próby za wcześnie.
Ostatnio zmieniony 31 sty 2014, 14:08 przez
Roshun , łącznie zmieniany 3 razy.
ethanak
Wygnańcy
Posty: 3054 Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:
Post
autor: ethanak » 31 sty 2014, 13:52
a może byś zainicjalizował kri?
Кто жопой родился, чижиком не помрёт
enedil
Przebojowy Jelonek
Posty: 1352 Rejestracja: 08 wrz 2012, 16:54
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: i3
Architektura: x86_64
Kontakt:
Post
autor: enedil » 31 sty 2014, 16:02
Po co dajesz system("clear") ?
Dobrze jest, psiakrew, a kto powie, że nie, to go w mordę!
~moderatorzy
ethanak
Wygnańcy
Posty: 3054 Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:
Post
autor: ethanak » 31 sty 2014, 16:08
znajdź natywny zamiennik, a jak znajdziesz to już będziesz wiedział po co.
Кто жопой родился, чижиком не помрёт
Nettmanek
Serdeczny Borsuk
Posty: 167 Rejestracja: 26 lis 2008, 18:51
Płeć: Mężczyzna
Wersja Ubuntu: 14.04
Środowisko graficzne: Unity
Architektura: x86_64
Lokalizacja: Wolverhampton
Kontakt:
Post
autor: Nettmanek » 10 lut 2014, 14:20
możnaby zamienic string'a na chara i sprawdzac znak po znaku... chociaż wydaje mi się, że w stringu też to jest możliwe.
Lenovo G580-20150 | Intel Core i3 3120M | 8GB DD3 | Intel HD 4000 & Nvidia GF 710M | 1TB HDD | kubuntu 13.10 64bit
ethanak
Wygnańcy
Posty: 3054 Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:
Post
autor: ethanak » 10 lut 2014, 15:01
na char* a nie na chara jak mniemam?
poza tym to ma być c++, a nie c++ wywołujący funkcje w ansi c.
Кто жопой родился, чижиком не помрёт
Roshun
Sędziwy Jeż
Posty: 31 Rejestracja: 07 cze 2012, 18:25
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Środowisko graficzne: Unity
Architektura: x86_64
Lokalizacja: Białystok
Kontakt:
Post
autor: Roshun » 19 lut 2014, 22:46
Trochę odświeżam temat. Dzięki pomocy mojego nauczyciela udało się trochę poprawić kod. Działa już dobrze zlicza wszystkie zmienne w odpowiedni sposób. Należało w kilku miejscach dostawić linijkę
Teraz pytanie do Was macie pomysły, aby uatrakcyjnić grę. Jakieś takie proste efekty. W najbliższym czasie dodam jeszcze rysowanie wisielca i ogólnie czyszczenie ekranu, aby całość była bardziej przejrzysta.
Kod: Zaznacz cały
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <cstdlib>
#include <string.h>
using namespace std;
string slowo, podawane;
void kategoria()
{
int help=0, ktore=1;
char a;
while(help!=1)
{
cout<<"Wybierz kategorie:"<<endl<<"1 - INFORMATYKA"<<endl<<"2 - ZWIERZETA"<<endl<<"3 - ROSLINY"<<endl<<"4 - ZIMA"<<endl<<"5 - LATO"<<endl<<"6 - INNE"<<endl<<"Wybieram kategorie: "<<endl;
switch(a=getchar())
{
case '1':
cout<<"Wybrales kategorie: INFORMATYKA"<<endl;
ktore=1;
help++;
break;
case '2':
cout<<"Wybrales kategorie: ZWIERZETA"<<endl;
ktore=2;
help++;
break;
case '3':
cout<<"Wybrales kategorie: ROSLINY"<<endl;
ktore=3;
help++;
break;
case '4':
cout<<"Wybrales kategorie: ZIMA"<<endl;
ktore=4;
help++;
break;
case '5':
cout<<"Wybrales kategorie: LATO"<<endl;
ktore=5;
help++;
break;
case '6':
cout<<"Wybrałes kategorie: INNE"<<endl;
ktore=6;
help++;
break;
default:
system("clear");
break;
}
}
cin.ignore();
int p;
if(ktore==1) { ifstream wej("informatyka"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
}
}
if(ktore==2) { ifstream wej("zwierzeta"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
}}
if(ktore==3) { ifstream wej("rosliny"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
} }
if(ktore==4) { ifstream wej("zima"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
}}
if(ktore==5) { ifstream wej("lato"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
} }
if(ktore==6) { ifstream wej("inne"); {while(!wej.eof())
{
wej>>slowo;
p=(int)rand()%3;
if(p==1) break;
}
}}
cout<<slowo<<endl;
}
void pregame()
{
int b=slowo.size();
podawane.clear();
for(int i=0; i<b; i++) podawane=podawane+'_';
}
void game()
{
int kri=0, b=slowo.size();
char znak;
while(kri!=5)
{
cout<<podawane<<endl;
znak=getchar();
cout<<"Podany znak: "<<znak<<endl;
if(slowo.find(znak)!=string::npos)
{
cin.ignore();
for(int i=0; i<b; i++)
{
if(znak==slowo[i]) podawane[i]=znak;
}
}
if(slowo.find(znak)==string::npos) {kri++; cin.ignore();}
if(slowo==podawane) { cout<<slowo<<endl<<"WYGRALES"<<endl; break; }
}
if(kri==5) cout<<"PRZEGRALES"<<endl<<"Slowo ktore bylo rozwiazaniem to: "<<slowo<<endl;
cout<<"Wcisnij ENTER, aby wrócić do menu."<<endl;
getchar();
}
int main()
{
int cos=0;
char help;
srand(time(NULL));
// co kto dlaczego
while(cos!=1)
{
cout<<"Wcisnij: "<<endl<<"1 - Gra"<<endl<<"2 - Zasady"<<endl<<"3 - Zakoncz"<<endl;
switch(help=getchar())
{
case '1':
system("clear");
kategoria();
pregame();
game();
break;
case '2':
system("clear");
cout<<"Prosta gra. Musisz odgadnąć hasło wpisując litery."<<endl<<"Możesz podać po jednej lub wpisać cały wyraz."<<endl<<"W grze występują podwójne słowa. W tym przypadku zamiast spacji wpisz '-' (minus)"<<endl;
cout<<"Zrozumiono?"<<endl<<"Wciśnij ENTER, aby przejsc do menu."<<endl;
cin.ignore();
getchar();
system("clear");
break;
case '3':
cos++;
break;
}
}
return 0;
}
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 11 gości