Policz, ile to jest - wersja prosta
Rozdział
poświęcony grom i zabawom wykonanych w środowisku Delphi
otwieramy, chyba najprostszym przykładem z możliwych (z punktu
widzenia programistycznego), zabawą matematyczną polegającą na
odgadnięciu poprawnego wyniku działania na dwóch liczbach.
Założenia
i opis zabawy:
Po
naciśnięciu przycisku START program wybierze dla nas jakieś
działanie matematyczne z użyciem dwóch liczb, wyświetli je i
poprosi o podanie właściwego wyniku. Ponieważ zależy nam na
rozwijaniu swego umysłu, wszystkie obliczenia wykonujemy w pamięci.
Z uwagi na ten wymóg ograniczymy zakres używanych liczb do
dwudziestu: program będzie wybierał liczby tylko z zakresu od 0 do
20. Oczywiście, programista może sobie ustalić ten zakres w sposób
zupełnie indywidualny.
Kolejnym
ograniczeniem jakiego dokonamy, będzie wyeliminowanie z używanych
działań, dzielenia. W ten sposób nie będziemy musieli obliczać w
pamięci liczb ułamkowych. Trudno przecież w pamięci policzyć,
ile to jest 19 podzielić przez 7. Nasz program będzie obsługiwał
tylko dodawanie, odejmowanie i mnożenie.
Po
obliczeniu w pamięci wyniku, wpisujemy go w pole edycyjne programu i
naciskamy przycisk Sprawdź. Program sprawdza poprawność wyniku i
wyświetla odpowiedni komunikat informacyjny, czy dobrze, czy źle.
Jeżeli odpowiedź jest poprawna, działanie jest usuwane z panelu
programu. Inna sytuacja ma miejsce w przypadku podania niepoprawnej
odpowiedzi. Działanie do policzenia nie znika, usuwany jest tylko
podany przez nas wynik. W ten sposób możemy spróbować swoich sił
jeszcze raz, a gdy się znowu nie uda, jeszcze raz i jeszcze raz.
Decyzja będzie zależała od nas. Jeżeli będziemy chcieli
zrezygnować z tego działania, wystarczy że naciśniemy przycisk
START, a wymieni nam działanie na inne.
Wprowadzamy
do programu także tabelę wyników, która będzie pokazywała, ile
do tej pory udzieliliśmy odpowiedzi poprawnych, a ile niepoprawnych.
Przy zamykaniu programu, pojawi się także komunikat, w którym w
zależności od uzyskanych wyników, program nam pogratuluje lub
zachęci do większego zaangażowania.
Jako
rozszerzenie możliwości programu zadbamy o to, aby program
informował nas, gdy nieopacznie naciśniemy przycisk Sprawdź bez
wpisania wyniku w polu edycyjnym, oraz aby umożliwiał wpisywanie w
tym polu tylko liczb, minusa (bo wyniki będą czasami liczbami
ujemnymi), oraz pozwalał na używanie klawisza Backpace do kasowania
wprowadzanych znaków w przypadku pomyłki.
Użyte komponenty:
Edit1-
pole edycyjne do wpisywania odpowiedzi,
Button1-
przycisk START,
Button2-
przycisk Sprawdź,
Label1-
wyświetla napis „Wyniki”,
Label2-
wyświetla napis „Poprawne:”,
Label3-
wyświetla napis „Niepoprawne:”,
Label4-
wyświetla ilość poprawnych odpowiedzi,
Label5-
wyświetla ilość niepoprawnych odpowiedzi,
Label6-
wyświetla działanie do policzenia.
Powyższe
komponenty wstawiamy na formę i układamy względem siebie tak, jak
na rysunku poniżej:
Należy
zwrócić uwagę, że numery komponentów lub formy głównej (TForm)
mogą się w Waszych projektach różnić. Należy więc poszczególny
kod przypisać do właściwych komponentów i nadać im właściwe
nazwy. W naszym projekcie modyfikujemy nazwy poszczególnym
komponentom w następujący sposób (właściwość Caption w
Inspektorze Obiektów):
Edit1
(usuwamy nazwę)
Button1
START
Button2
Sprawdź
Label1
Wyniki
Label2
Poprawne:
Label3
Niepoprawne:
Label4
0 (zero)
Label5
0 (zero)
Label6
Ile to jest:
W
dalszej kolejności, także za pomocą Inspektora Obiektów zmieniamy
inne właściwości tych komponentów, a więc: kolor, rozmiar,
położenie itp.
Kod programu:
unit
Unit1;
interface
uses
Windows,
Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,
StdCtrls;
type
TForm1
= class(TForm)
Edit1:
TEdit;
Button1:
TButton;
Button2:
TButton;
Label1:
TLabel;
Label2:
TLabel;
Label3:
TLabel;
Label4:
TLabel;
Label5:
TLabel;
Label6:
TLabel;
procedure
Button1Click(Sender: TObject);
procedure
Button2Click(Sender: TObject);
procedure
Edit1KeyPress(Sender: TObject; var
Key: Char);
procedure
FormCreate(Sender: TObject);
procedure
FormClose(Sender: TObject; var
Action: TcloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1:
TForm1;
WYNIK:
Integer; //zmienna
przechowująca
wynik działania
Poprawne:
Integer; //zmienna przechowująca ilość
poprawnych odpowiedzi
Niepoprawne:
Integer; //zmienna
przechowująca ilość niepoprawnych
odpowiedzi
implementation
{$R
*.dfm}
//przy
uruchomieniu programu wyzeruj punktację
procedure
TForm1.FormCreate(Sender: TObject);
begin
Poprawne:=0;
//wyzeruj ilość poprawnych
odpowiedzi
Niepoprawne:=0;
//wyzeruj ilość niepoprawnych
odpowiedzi
Label4.Caption:=
'0'; //wyświetl
'0' poprawnych odpowiedzi
Label5.Caption:=
'0'; //wyświetl
'0' niepoprawnych odpowiedzi
end;
//przy
zamykaniu programu oceń uzyskane wyniki
procedure
TForm1.FormClose(Sender: TObject; var
Action: TCloseAction);
begin
if
(Poprawne<Niepoprawne) or
(Poprawne=Niepoprawne) then
begin
ShowMessage('Musisz
jeszcze trochę potrenować');
end
else
ShowMessage('Gratuluję!
Uzyskałeś dobry wynik');
end;
//pozwól na wpisywanie
tylko liczb, minusa i Backpace w polu odpowiedzi
procedure
TForm1.Edit1KeyPress(Sender: TObject; var
Key: Char);
begin
if
not (Key in ['0'..'9',#45,#8])
then
begin
Key:=#0;
ShowMessage('To
nie jest liczba'); //wyświetl
komunikat o błędzie
end;
end;
//gdy
naciśniesz przycisk START
procedure
TForm1.Button1Click(Sender: TObject);
var
Liczba1:
Integer; //zmienna przechowująca
pierwszą liczbę
Liczba2:
Integer; //zmienna przechowująca
drugą liczbę
Dzialanie:
Integer; //zmienna pomocnicza do
losowania znaku działania
Znak:
String;
//zmienna przechowująca znak działania
begin
Edit1.Clear;
//wyczyść pole edycyjne
(Do podawania Odpowiedzi)
Randomize;
//uruchom maszynę losującą
Liczba1:=Random(21);
//losuj pierwszą liczbę
Liczba2:=Random(21);
//losuj drugą liczbę
Dzialanie:=Random(3);
//losuj znak działania
matematycznego
case
Dzialanie of
//gdy zostanie wylosowana dana liczba to...
0:
WYNIK:= Liczba1+Liczba2; //...wykonaj
dodawanie
1:
WYNIK:= Liczba1-Liczba2; //...wykonaj
odejmowanie
2:
WYNIK:= Liczba1*Liczba2; //...wykonaj
mnożenie
end;
if
Dzialanie=0 then
Znak:=
'+';
//jeżeli wylosowano dodawanie to pokaż znak '+'
if
Dzialanie=1 then
Znak:=
'-';
//jeżeli wylosowano odejmowanie to pokaż znak '-'
if
Dzialanie=2 then
Znak:=
'x'; //jeżeli
wylosowano mnożenie to pokaż znak 'x'
Label6.Caption:=('Ile
jest: ' + IntToStr(Liczba1) + ' '
+ znak + ' ' +IntToStr(Liczba2) +
' ?'); //wyświetl
działanie
Edit1.SetFocus;
//ustaw focus w Polu do
Odpowiedzi
end;
//gdy
naciśniesz przycisk Sprawdź
procedure
TForm1.Button2Click(Sender: TObject);
Label
KONIEC; //Etykieta do przechodzenia w
inne miejsca kodu
var
Odp:
String; //zmienna
przechowująca naszą odpowiedź
begin
Odp:=
Edit1.Text; //odczytaj podana odpowiedz i
przypisz ja do zmiennej
if
Odp='' then
//gdy nie podano odpowiedzi monituj o
wpisaniu wyniku
begin
ShowMessage('Wpisz
najpierw wynik'); //wyświetl
komunikat informujący
Edit1.SetFocus;
//ustaw focus w Polu do Odpowiedzi
goto
KONIEC; //pomiń poniższy kod i przejdź od
razu na koniec procedury
end;
if
Odp=(IntToStr(WYNIK)) then
//jeżeli odpowiedź jest poprawna to ...
begin
ShowMessage('Bardzo
dobrze!'); //wyświetl komunikat o
poprawnej odpowiedzi
Label6.Caption:=
'Ile jest: ';
//wyczyść działanie
Poprawne:=Poprawne
+ 1; //dodaj
punkt do poprawnych odpowiedzi
end
//bez
średnika
else
//w
przeciwnym wypadku ...
begin
ShowMessage('Niestety
źle'); //wyświetl komunikat o złej
odpowiedzi
Niepoprawne:=Niepoprawne
+ 1; //dodaj
punkt do niepoprawnych odpowiedzi
end;
Edit1.Clear;
//wyczyść
pole do podawania Odpowiedzi)
Edit1.SetFocus;
//ustaw focus w
Polu do Odpowiedzi
Label4.Caption:=
IntToStr(Poprawne); //wyświetl
ilość poprawnych odpowiedzi
Label5.Caption:=
IntToStr(Niepoprawne); //wyświetl
ilość niepoprawnych odpowiedzi
KONIEC:
//etykieta do której przechodzi kod, gdy ktoś
nie wpisze żadnej liczby
end;
end.
Strona 1/3 Dalej >
Artykuł pochodzi z mojej książki pt. "Delphi w przykładach dla początkujących". Zapraszam na Stronę książki.
Ciekawe artykuły:
- Zagadki logiczne i inne zagadki
- Gry matematyczne w Delphi
- Zabawy rozwijające pamięć w Delphi
- Przechwyt klawiatury w Delphi
- Nauki płynące z mądrości pokoleń
Zapoznaj się z innymi utworami. Przejdź do zakładki Spis artykułów.
Dzień dobry
OdpowiedzUsuńZakupiłem Pańską książkę, rozpoczynając samodzielną naukę programowania w Delphi, natknąłem się jednak na problem w drugim zadaniu, a więc policz ile to jest - wersja trudniejsza, zaproponowany przez Pana kod o ile się nie mylę, zlicza działanie nie-matematycznie, tzn po kolei, bez uwzględnienia kolejności wykonywania działań, ponieważ jestem kompletnie początkujący, nie bardzo wiem jak to poprawić, pisanie sekwencji dla każdej możliwości wylosowania znaku działań to zbyt mozolne, a w programowaniu chyba nie o to chodzi, czy jest jakiś sposób na odczytanie zapisu działania w string'u i przekonwertowanie tego wprost do działania matematycznego?
pozdrawiam
Krzysztof Krajniak
Ta "niematematyczność" działań, o której Pan wspomina, wynika z przyjętego założenia, że wersja ta w domyśle, jest punktem wyjścia dla wersji audio, gdzie program słownie podaje kolejne działania do wykonania w pamięci. W książce posłużyłem się wersją prostą zabawy, aby ułatwić zrozumienie kodu.
UsuńSposobów na uzyskanie "matematyczności" zabawy, czyli najpierw wykonanie mnożenia, a potem dodawania i odejmowania, jest kilka. Jako początkujący programista musi Pan właśnie nauczyć się analizować algorytmy wykorzystane w kodzie i - w razie czego - szukać alternatywy.
Analizując kod zabawy widzi Pan, że algorytm, jaki wykorzystałem, realizuje dokładnie moje zamierzenie tj. zliczanie kolejnych poddziałań wg kolejności pojawienia się. Chcąc zatem uzyskać inny efekt, wystarczy najpierw wylosować wszystkie typy działań (dodawanie, odejmowanie, mnożenie), jakie zostaną w danym działaniu użyte, a następnie wprowadzić warunek, że działanie wylosowane, jako "mnożenie" program ma wykonać jako pierwsze. Nie możemy zatem w tak prosty sposób stosować zmienną WYNIK, jak ma to miejsce w kodzie zabawy.
Ogólna koncepcja właściwego algorytmu może być następująca:
1. wylosuj liczby, które będą wykorzystane w działaniu (w naszej zabawie będzie ich cztery) i zapisz je do osobnych zmiennych (Liczba 1...Liczba4)
2. wylosuj wszystkie znaki działania wykorzystane w tym działaniu (będzie ich trzy) i zapisz je do osobnych zmiennych (znak1...znak3)
3. warunek nr 1: jeśli któryś ze znaków jest mnożeniem, wtedy zmienne LiczbaX i LiczbaY (liczby wylosowane dla danego podzdziałania) pomnóż i zapisz do zmiennej "M", a następnie wykonaj całe działanie stosując zmienną "M", zamiast mnożenia dwóch liczb (czyli zamiast działania "Liczba1 + Liczba2 * Liczba 3 - Liczba4", będzie Liczba1 + M - Liczba4"), w przeciwnym razie (tzn jeśli nie ma mnożenia) zastosuj algorytm z przykładu w książce. (Ponieważ mogą wystąpić dwa znaki mnożenia, należy wprowadzić zmienną N, która zapisze wynik mnożenia kolejnych dwóch liczb, może to być nawet zmienna M, np: Liczba1 + Liczba2 * M. Otrzymamy wtedy działanie końcowe: Liczba1 + N)
4. warunek nr 2: jeśli wszystkie trzy znaki to "mnożenie", wtedy zastosuj algorytm z przykładu w książce (bo kolejność działań będzie szła od lewej do prawej).
Nie podaję gotowego kodu, bo w ten sposób niewiele się Pan nauczy. Tylko "kombinując" na różne sposoby, wyrobi Pan w sobie umiejętność budowania algorytmów potrzebnych w Pańskich projektach. Na tym właśnie polega nauka programowania :)
Jeśli chodzi o mozolne pisanie warunków, to niestety jest to coś naturalnego w programowaniu. Proszę spojrzeć sobie no kod gry "HotSpot" lub programu "Jak się masz". Zadaniem programisty w takich przypadka jest tylko próba ułatwienia sobie zadania i odchudzenie kodu, stosując procedury, funkcje i inne wynalazki.
Ja bym zaczął od najprostszej logicznie metody, czyli kodu typu: (Liczba1)(Znak1)(Liczba2)(Znak2)(Liczba3)(Znak3)(Liczba4), zakładając, że komputer jest na tyle mądry, że wykona działanie wg praw matematyki, ale to trzeba by sprawdzić.
Usuń