Pomoce:

Biblioteka procedur obsługi konsoli znakowej - newconio


Zgadywanka Wyrazów

Przygotowanie danych dla gry

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:

 

pe.dat

 

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:

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.

 

Program Zgadywanka Wyrazów

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;
}

 



List do administratora Serwisu Edukacyjnego Nauczycieli I LO

Twój email: (jeśli chcesz otrzymać odpowiedź)
Temat:
Uwaga: ← tutaj wpisz wyraz  ilo , inaczej list zostanie zignorowany

Poniżej wpisz swoje uwagi lub pytania dotyczące tego rozdziału (max. 2048 znaków).

Liczba znaków do wykorzystania: 2048

 

W związku z dużą liczbą listów do naszego serwisu edukacyjnego nie będziemy udzielać odpowiedzi na prośby rozwiązywania zadań, pisania programów zaliczeniowych, przesyłania materiałów czy też tłumaczenia zagadnień szeroko opisywanych w podręcznikach.



   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2017 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.