Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2008 mgr
Jerzy Wałaszek |
Zapoznaj się z materiałami przedstawionymi na poprzednich zajęciach koła:
Utwórz nowy katalog projektowy. Skopiuj do niego pliki biblioteki:
newconio.cpp | - | plik źródłowy biblioteki |
newconio.h | - | plik nagłówkowy dla biblioteki |
Utwórz nowy projekt konsoli w Dev-C++. Do projektu dodaj plik źródłowy newconio.cpp z twojego katalogu projektowego.
Mocnym atutem języka C++ jest biblioteka standardowych szablonów STL (ang. Standard Template Library), która udostępnia programiście wiele pożytecznych obiektów danych oraz algorytmów operujących na tych obiektach. Dzięki STL programowanie w C++ jest o wiele prostsze.
Obiekt string przechowuje dynamiczny łańcuch znaków. Na dzisiejszych zajęciach poznamy podstawowe funkcje tego obiektu.
W programie wykorzystującym obiekt string należy dołączyć plik nagłówkowy:
#include <string>
Po dołączeniu pliku nagłówkowego string dostajemy typ danych o nazwie string, na podstawie którego możemy budować zmienne klasy string:
string zmienna_string;
Zmienna typu string przechowuje łańcuch znaków, czyli ciąg literek. Literki można wprowadzić do zmiennej za pomocą instrukcji przypisania:
zmienna_string =
"ABCDEF";
lub odczytać je ze strumienia konsoli:
cin >>
zmienna_string;
Dostęp do poszczególnych znaków przechowywanych w zmiennej łańcuchowej otrzymujemy za pomocą operatora [] oraz numeru znaku:
string a = "ABCDEF";
cout << a[0]
<< a[5] << endl;
...
Powyższy przykład umieszcza w zmiennej łańcuchowej a tekst ABCDEF i wyświetla pierwszą i ostatnią literkę. Otrzymamy zatem wydruk liter AF.
string a = "ABCDEF";
cout << a << endl;
a[0] =
'X';
a[5] = 'Z';
cout << a <<
endl;
...
Na wydruku otrzymamy:
ABCDEF
XBCDEZ
Porównanie:
a == b
Jeśli a i b są zmiennymi łańcuchowymi, to porównanie daje wynik true, gdy zmienna a zawiera dokładnie ten sam tekst co zmienna b. W przeciwnym razie wynikiem jest false.
a != b
Wynik true, gdy tekst w zmiennej a różni się od tekstu w zmiennej b (nawet jedną literką!). W przeciwnym razie wynikiem jest true.
a < b
Jest to tzw. porównanie leksykograficzne. Porównywane są kolejne literki obu tekstów aż do napotkania niezgodności. Jako mniejszy uważa się ten z tekstów, w którym niezgodny znak posiada mniejszy kod. Na przykład:
a = "Jan"; b = "Jar";
Teksty różnią się ostatnią literą. Zatem:
a < b
- true, gdyż kod 'n' =
110, kod 'r' = 114 i 110 < 114.
Jeśli jeden z tekstów jest prefiksem drugiego tekstu i jest krótszy, to uważa się go za mniejszy:
a = "Jan"; b = "Janek";
- true, ponieważ Jan jest prefiksem Janek i jest
krótszy.
a < b
Dołączanie znaków:
Operator + w znaczeniu do tekstów oznacza dołączanie, czyli tzw. konkatencję. Niech a, b i c będą zmiennymi łańcuchowymi:
a = 'A' + 'B'; // w a znajdzie się
tekst "AB"
b = "CDEF";
c = a + b; // w c znajdzie się
połączenie tekstów a i b, czyli "ABCDEF"
Operator += dołącza do zawartości zmiennej nowy tekst:
a = "" ; // łańcuch pusty, czyli
nie zawierający żadnego znaku
for(int i = 0; i < 10; i++) a += "AB";
Po zakończeniu pętli zmienna a będzie zwierała 10 razy powtórzony tekst AB, czyli ABABABABABABABABABAB
Znaki są traktowane w języku C++ jak liczby całkowite będące kodami ASCII tych znaków. Dzięki temu w prosty sposób możemy używać znaków w wyrażeniach arytmetycznych:
a = "";
for(int i = 65; i <= 90; i++) a += i;
cout << a << endl;
Wynikiem tego fragmentu kodu jest wyświetlenie kolejnych literek alfabetu od A do Z, które zostały umieszczone w zmiennej a przez pętlę iteracyjną. Literki te posiadają kody ASCII od 65 do 90.
Długość łańcucha:
Liczba znaków zawartych w tekście przechowywanym przez zmienną łańcuchową nosi nazwę długości łańcucha (ang. string length). Obiekt string posiada wiele użytecznych funkcji. Jedną z nich jest length(), która zwraca nam liczbę znaków aktualnie przechowywanych w zmiennej. Funkcję wywołujemy następująco:
zmienna_string.length();
Na przykład:
string a = "ABCD";
cout << a.length() << endl; // otrzymamy wynik 4
Jest to prosta gra logiczna o następujących zasadach:
Komputer losuje 4-ro literowy kod zbudowany z literek A, B, C, D, E i F. Kod ten nie jest ujawniany. Zadaniem gracza-człowieka jest odgadnięcie wylosowanego kodu w maksymalnie 6 próbach. W tym celu gracz wprowadza swoje kody zbudowane z tych samych literek. Komputer ocenia wprowadzony kod następująco:
Jeśli literka w kodzie gracza i komputera jest taka sama i na tej
samej pozycji, to komputer wypisuje znak x - trafiona literka kodu.
Jeśli litera kodu gracza znajduje się w kodzie komputera na innej pozycji, to
komputer wypisuje znak o.
Oczywiście nie wiadomo o które znaki chodzi.
Na przykład:
Kod komputera | ABCD | ||
Kod gracza | EFBF | o | - jedna literka trafiona (B), ale na innej pozycji |
Kod gracza | AFFD | xx | - dwie literki trafione na dobrych pozycjach (A i D) |
Kod gracza | ACFD | xxo | - dwie trafione na dobrych pozycjach (A i D) oraz jedna na innej pozycji (C) |
Wykorzystując logikę gracz-człowiek na podstawie odpowiedzi komputera odtwarza kod komputera. Gra wymaga zatem inteligencji oraz umiejętności logicznego wnioskowania.
// Master Mind // (C)2008 Koło informatyczne w I LO w Tarnowie // Kurs programowania w C++ dla początkujących //-------------------------------------------- #include <iostream> #include <string> #include "newconio.h" using namespace std; // Wyświetla prosty ekran tytułowy i oczekuje // na wciśnięcie dowolnego klawisza //------------------------------------------- void ekran_tytulowy() { textattr(0x1f); clrscr(); center(24,"M A S T E R M I N D"); textcolor(YELLOW); center(26,_pl("(C)2008 Koło informatyczne w I-LO")); textcolor(LIGHTGRAY); center(49,_pl("Aby rozpocząć, naciśnij dowolny klawisz")); while(!getch()); } // Funkcja wywoływana po zakończeniu rozgrywki. // Sprawdza, czy gracz ma ochotę zagrać jeszcze // raz. Jeśli tak, zwraca true, inaczej false //--------------------------------------------- bool jeszcze_raz() { char c; textcolor(LIGHTRED); center(49,_pl("Chcesz zagrać jeszcze raz? (t = TAK) ")); while(!(c = getch())); return c == 't'; } // Ocenia kod wprowadzony przez gracza // Wyświetla literkę x dla każdego znaku // w kodzie gracza zgodnego ze znakiem // kodu komputera co do wartości i miejsca // lub literkę o dla znaku zgodnego co do // wartości, lecz znajdującego się na innej // pozycji w kodzie komputera. // k - kod komputera // g - kod gracza //----------------------------------------- void ewaluacja(string k, string g) { int i,j; // Ponieważ gracz mógł wprowadzić mniej niż 4 znaki kodu, // wyrównujemy spacjami jego kod do 4 znaków while(g.length() < 4) g += " "; // Najpierw analizujemy zgodność znaków kodu gracza // ze znakami kodu komputera co do wartości i pozycji textcolor(LIGHTGREEN); // Przeglądamy kolejne znaki obu kodów i jeśli są // takie same, to wyświetlamy jasnozieloną literkę x // Znaki w obu kodach musimy zniszczyć, aby nie były // powtórnie zliczone przez dalszą część algorytmu // Możemy tak zrobić, ponieważ funkcja otrzymuje kopie // kodów, z którymi może sobie zrobić to, co chce. for(i = 0; i < 4; i++) if(k[i] == g[i]) { cout << "x"; k[i] = '?'; // niszczymy znak i-ty kodu komputera g[i] = '@'; // niszczymy znak i-ty kodu gracza } // Teraz badamy zgodność liter kodu gracza z literami // kodu komputera. Ponieważ litery równe na tych samych // pozycjach w obu kodach zostały zniszczone, nie zliczymy // ich. Kolejne litery kodu gracza porównujemy ze wszystkimi // literami kodu komputera. Jeśli znajdziemy równość, to // wyświetlamy zółtą literkę o, a literę w kodzie komputera // niszczymy i przerywamy pętlę wewnętrzną textcolor(YELLOW); for(i = 0; i < 4; i++) for(j = 0; j < 4; j++) if(g[i] == k[j]) { cout << "o"; k[j] = '?'; // niszczymy znak j-ty w kodzie komputera break; } } // Główna funkcja gry //------------------- void gra() { string kkod; // zawiera kod komputera string gkod; // zawiera kod gracza // Pętla gry do { textattr(0x07); clrscr(); // Generujemy 4-ro literowy kod komputera. Najpierw // zerujemy łańcuch kkod kkod = ""; // Teraz w pętli losujemy przypadkowe literki od A do F // i dołączamy je na koniec łańcucha kkod for(int i = 0; i < 4; i++) kkod += 65 + rand() % 6; textcolor(CYAN); cout << "*** MASTER MIND ***\n\n"; // Rozgrywka składa się z maksymalnie 6 prób odgadnięcia // kodu komputera. Realizujemy ją za pomocą pętli iteracyjnej for(int i = 1; i <= 6; i++) { // Wyświetlamy numer próby i odczytujemy kod gracza textcolor(GREEN); gotoxy(0,2 + 2 * i); cout << "Runda nr " << i << " : "; textcolor(YELLOW); cursoron(); cin >> gkod; cursoroff(); // Ustawiamy pozycję wydruku za kodem wprowadzonym // przez gracza. Jest to konieczne, ponieważ ewaluację // tego kodu chcemy otrzymać w tym samym wierszu gotoxy(19,2 + 2 * i); // oceniamy prowadzony kod ewaluacja(kkod,gkod); // Jeśli gracz odgadł kod komputera, wyświetlamy gratulacje // i przerywamy pętlę if(kkod == gkod) { textcolor(WHITE); gotoxy(24,2 + 2 * i); cout << "*** BRAWO ***"; break; } // Jeśli obecny obieg jest ostatnim, to gracz nie odgadł // kodu komputera w 6 próbach. W takim razie przed // zakończeniem pętli wyświetlamy kod komputera if(i == 6) { textcolor(LIGHTRED); gotoxy(13,4 + 2 * i); cout << kkod; } } // Sprawdzamy, czy gracz chce zagrać ponownie. Jeśli tak, // to wykonujemy następny obieg pętli gry } while(jeszcze_raz()); } // Program główny //--------------- main() { // Inicjujemy bibliotekę newconio _cinit(); // Inicjujemy generator liczb pseudolosowych srand((unsigned)time(NULL)); // Przechodzimy w tryb pełnoekranowy, wyświetlamy ekran // tytułowy i rozpoczynamy grę. fullscreen(true); cursoroff(); ekran_tytulowy(); gra(); cursoron(); fullscreen(false); } |
*** MASTER MIND *** Runda nr 1 : ABCD x Runda nr 2 : EFCC xooo Runda nr 3 : FCDE xxx Runda nr 4 : FEDC xoo Runda nr 5 : FCCE xxxx *** BRAWO *** |
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