Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2010 mgr
Jerzy Wałaszek |
Pomoce:
Biblioteka procedur obsługi konsoli znakowej - newconio
Na zajęciach utworzymy prostą grę logiczną w odgadywanie znaków. Będziemy do niej potrzebowali duży zasób słów. Wykorzystamy plik słownika polsko-esperanckiego, który zawiera ponad 78 tys. wyrazów. Utwórz projekt w Code::Blocks i skopiuj plik słownika do katalogu projektu. Plik znajdziesz tutaj:
Plik składa się z pojedynczych wierszy. W każdym wierszu jest definicja jednego słowa wg schematu:
słowo polskie=słowo esperanckie (ewentualny komentarz)
Na początek napiszemy program, który odczyta zawartość pliku pe.dat wiersz po wierszu i wyświetli ją w oknie konsoli znakowej. Dostęp do pliku uzyskamy za pomocą strumieni plikowych. W tym celu należy dołączyć do programu plik nagłówkowy fstream. Strumień jest zmienną, którą definiujemy jak każdą inną zmienną:
fstream nazwa_strumienia;
fstream - określa typ: strumień plikowy
Przed rozpoczęciem czytania danych ze strumienia plikowego należy go otworzyć:
nazwa_strumienia.open("nazwa_pliku",fstream::in); // plik otwarty do odczytu
nazwa_strumienia.open("nazwa_pliku",fstream::out); // plik otwarty do zapisu
W pierwszym przypadku z pliku możemy odczytywać dane, np.:
getline(nazwa_strumienia,zmienna_łańcuchowa); // odczyt całego wiersza znaków
W drugim przypadku do pliku dane możemy zapisywać, np.:
nazwa_strumienia << zmienna_łańcuchowa << endl; // zapis wiersza znaków
Stan strumienia uzyskamy za pomocą funkcji:
nazwa_strumienia.good(); // zwraca true, jeśli ze strumienia można czytać dane
Po zakończeniu pracy ze strumieniem plikowym należy go zamknąć:
nazwa_strumienia.close();
Pierwszy program przygotowuje dane dla naszej gry. Wczytuje on kolejne wiersze z pliku pe.dat. Wczytany wiersz zostaje obcięty przed znakiem '='. Wykorzystujemy do tego dwie funkcje klasy string:
łańcuch.find('='); // zwraca pozycję znaku '=' w
zmiennej łańcuch.
łańcuch.substr(start, ile); // zwraca fragment łańcucha od pozycji
strat i zawierający ile znaków
Łańcuch wynikowy zapisujemy do pliku dane.txt, jeśli:
nie występował w poprzednim wierszu
nie posiada spacji, przecinka, kropki, dwukropka, minusa
ma więcej niż 4 znaki
Przed zapisem kody liter są konwertowane na Laitin II za pomocą funkcji _pl() z biblioteki newconio. Dzięki temu w konsoli będą wyświetlane z prawidłowymi znakami polskimi.
// Przygotowanie danych dla zgadywanki // (C)2010 ILO w Tarnowie // KOŁO INFORMATYCZNE //----------------------- #include <iostream> #include <string> #include <fstream> using namespace std; // Funkcja konwertuje tekst ze standardu Windows 1250 // na standard konsoli znakowej Latin II. //--------------------------------------------------- // s - tekst kodowany wg Windows 1250 //--------------------------------------------------- string _pl(string s) { for(unsigned i = 0; i < s.length(); i++) switch(s[i]) { case 'ą' : s[i] = 165; break; case 'ć' : s[i] = 134; break; case 'é' : s[i] = 'e'; break; case 'ę' : s[i] = 169; break; case 'ł' : s[i] = 136; break; case 'ń' : s[i] = 228; break; case 'ö' : s[i] = 'o'; break; case 'ó' : s[i] = 162; break; case 'ś' : s[i] = 152; break; case 'ż' : s[i] = 190; break; case 'ź' : s[i] = 171; break; case 'Ą' : s[i] = 164; break; case 'Ć' : s[i] = 143; break; case 'Ę' : s[i] = 168; break; case 'Ł' : s[i] = 157; break; case 'Ń' : s[i] = 227; break; case 'Ó' : s[i] = 224; break; case 'Ś' : s[i] = 151; break; case 'Ż' : s[i] = 189; break; case 'Ź' : s[i] = 141; break; } return s; } int main() { fstream f,g; string s,t; // otwieramy strumień f do odczytu z pliku pe.dat f.open("pe.dat",fstream::in); // otwieramy strumień g do zapisu do pliku dane.txt g.open("dane.txt",fstream::out); // odczytujemy wiersze z pe.dat i zapisujemy je do dane.txt t = ""; while(f.good()) { // czytamy z f wiersz znaków getline(f,s); // obcinamy wiersz przed znakiem '=' s = s.substr(0,s.find('=')); // jeśli wiersz spełnia warunki, zapisujemy go do g if((s != t) && (s.length() > 4) && (s.find(' ') == string::npos) && (s.find(',') == string::npos) && (s.find('.') == string::npos) && (s.find(':') == string::npos) && (s.find('-') == string::npos)) g << _pl(s) << endl; t = s; // zapamiętujemy obecny wiersz } // zamykamy strumienie plikowe f.close(); g.close(); return 0; } |
Powyższy program utworzy nam plik dane.txt, który zawiera ponad 27 tys. wierszy. W każdym wierszu jest jedno słowo. Słowa nie powtarzają się, nie zawierają innych znaków niż litery. Plik dane.txt wykorzystamy w programie zgadywanki.
Zasady gry będą następujące:
Program wczyta do tablicy łańcuchów zawartość pliku dane.txt. Tablica będzie posiadała 30000 elementów typu string. Każdy wczytany wiersz będziemy umieszczać w kolejnych elementach tej tablicy. Następnie wygenerujemy liczbę losową pomiędzy 0 a liczbą wczytanych słów. W ten sposób wybierzemy jeden z 27000 wyrazów. Użytkownikowi wyświetlimy jedynie wiersz zbudowany z tylu kropek, ile znaków posiada wylosowany wyraz. Użytkownik będzie musiał ten wyraz odgadnąć w 7 próbach. W każdej próbie może on wpisać swój wyraz. Wpisany wyraz jest porównywany literka po literce z wylosowanym wyrazem, Jeśli wystąpi zgodność liter, to komputer odkryje wszystkie odgadnięte w wyrazie literki. Jeśli użytkownik odgadnie hasło w 7 próbach, wygrywa. Jeśli nie, przegrywa.
// Zgadywanka Wyrazów // (C)2010 ILO w Tarnowie // KOŁO INFORMATYCZNE //----------------------- #include <iostream> #include <string> #include <fstream> #include <time.h> #include <cstdlib> using namespace std; // Funkcja konwertuje tekst ze standardu Windows 1250 // na standard konsoli znakowej Latin II. //--------------------------------------------------- // s - tekst kodowany wg Windows 1250 //--------------------------------------------------- string _pl(string s) { for(unsigned i = 0; i < s.length(); i++) switch(s[i]) { case 'ą' : s[i] = 165; break; case 'ć' : s[i] = 134; break; case 'ę' : s[i] = 169; break; case 'ł' : s[i] = 136; break; case 'ń' : s[i] = 228; break; case 'ó' : s[i] = 162; break; case 'ś' : s[i] = 152; break; case 'ż' : s[i] = 190; break; case 'ź' : s[i] = 171; break; case 'Ą' : s[i] = 164; break; case 'Ć' : s[i] = 143; break; case 'Ę' : s[i] = 168; break; case 'Ł' : s[i] = 157; break; case 'Ń' : s[i] = 227; break; case 'Ó' : s[i] = 224; break; case 'Ś' : s[i] = 151; break; case 'Ż' : s[i] = 189; break; case 'Ź' : s[i] = 141; break; } return s; } int main() { fstream f; string w[30000],h,s,x; unsigned i,j,lw,runda; // inicjujemy generator pseudolosowy srand((unsigned)time(NULL)); // tekst powitalny cout << _pl("GRA W ZGADYWANIE SŁÓW") << endl << "=====================\n\n"; // wczytujemy do w[] zawartość pliku dane.txt f.open("dane.txt",fstream::in); for(lw = 0; f.good(); lw++) getline(f,w[lw]); f.close(); // losujemy słowo z w[] i umieszczamy je w h h = w[rand() % lw]; // przygotowujemy wiersz z kropek x = "........................................"; x = x.substr(0,h.length()); // rozpoczynamy rozgrywkę for(runda = 1; runda <= 7; runda++) { cout << "RUNDA #" << runda << endl << endl << x << endl; getline(cin,s); cout << endl; // dopasowujemy długość s do długości h s += "........................................"; s = s.substr(0,h.length()); // sprawdzamy, czy tekst odgadnięty if(s == h) { cout << "*** GRATULACJE ***\n\n"; break; } // przygotowujemy nowe x x = "........................................"; x = x.substr(0,h.length()); // szukamy pasujących liter i odsłaniamy je w x for(i = 0; i < h.length(); i++) if(s[i] == h[i]) for(j = 0; j < h.length(); j++) if(h[j] == s[i]) x[j] = h[j]; // sprawdzamy, czy ostatnia runda if(runda == 7) { cout << h << _pl(" --- NIE UDAŁO CI SIĘ TEGO ODGADNĄĆ. SPRÓBUJ PONOWNIE.") << endl << endl; } } return 0; } |
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe