![]() |
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