Feladatmegoldások: https://pastebin.com/3MJDSLKu
C# referencia dokumentáció: https://www.tutorialspoint.com/csharp/csharp_program_structure.htm
1. Telepítendő alkalmazások
- .Net Core SDK (Fontos, hogy az SDK-t telepítsük): https://dotnet.microsoft.com/download
- Visual Studio Code – https://code.visualstudio.com/download
- Pluginek telepítése:
- “C#” – C# for Visual Studio Code plugin – Microsoft
- “C# Extensions” plugin
2. Első projekt beindítása
- Mappa létrehozása,
- Parancssor megnyitása, megtalálni a létrehozott mappát,
- futtatni: “dotnet new console”, “dotnet run”
- VSCode indítása,
- File/Open… létrehozott mappa megnyitása,
- Omnisharp ablak megnytása (Zöld lángnyelv egészen alul),
- Terminal tab-fül,
- futtatni: “dotnet run”
3. Minta program átírása
using System; namespace Oktatas { class Program { static void Main(string[] args) { new Program().example1(); } void example1() { Console.WriteLine("Hello World!"); } } }
3.1 Új eljárás létrehozása
using System;
namespace Oktatas
{
class Program
{
static void Main(string[] args)
{
new Program().example2();
}
void example1()
{
Console.WriteLine("Hello World!");
}
void example2()
{
Console.Write("Write your name:");
string name = Console.ReadLine();
Console.WriteLine("Hello " + name);
}
}
}
4. Blokkok, Változók és adattípusok, operátorok
4.1 Típusok és műveletek (operátorok)
void example3() { int n1 = 1234; int n2 = 5678; int result = n1 + n2; Console.WriteLine("Sum is " + result); }
4.1.1 Feladat: Próbáljuk ki más műveleteket és értékeket is.
Figyeld meg: Osztás műveletnél is mindig egész számot kapsz. Miért? Hogyan lehet pontosabb eredményt megjeleníteni?
4.2 Bevitel és konverzió
void example4() { Console.Write("Enter a number:"); int n1 = System.Convert.ToInt32(Console.ReadLine()); Console.Write("Enter second number:"); int n2 = System.Convert.ToInt32(Console.ReadLine()); int result = n1 + n2; Console.WriteLine("Sum is " + result); }
4.2.1 Feladat: Próbáljunk ki más műveleteket is.
4.2.2 Feladat: futtatás során adjunk meg “nem várt” értékeket!
4.2.3 Kód formázás
5. Vezérlési szerkezetek
5.1 Logikai kifejezések, elágazások
void example5() { Console.Write("Enter a number:"); int n1 = System.Convert.ToInt32(Console.ReadLine()); Console.Write("Enter second number:"); int n2 = System.Convert.ToInt32(Console.ReadLine()); if (n2 == 0) { Console.WriteLine("Cannot divide with zero"); } else { int result = n1 / n2; Console.WriteLine("The result of the division is " + result); } }
5.1.1 Feladat: Az example2-t írjuk át úgy, hogy ne fogadjon el 3 karakternél rövidebb nevet. (A név hosszát így bírjuk lekérdezni: name.Length )
5.1.2 Feladat: Az example2-t írjuk át úgy, hogy egy “jelszót” kérjen be a rendszer, helyes jelszóra írjon ki egy “titkot”, hibás jelszóra elutasító üzenetet.
5.1.3 Logikai operátorok átismétlése.
5.2 Ciklusok
void example6() { for (int i = 0; i < 10; i++) { Console.Write(" " + i); } Console.WriteLine(); } void example7() { int i = 0; while (i < 10) { Console.Write(" " + i); i = i + 1; } Console.WriteLine(); }
5.2.1 Feladat: “i = i + 1” helyett használjunk más megoldást!
5.2.2 Feladat: Jelenítsünk meg olyan számtani sorozatot, aminek a differenciája 2.
5.2.3 Feladat: A 4-es és 6-os példákból tanultak alapján készítsünk olyan megoldást, ahol egy megadott számig történik a számolás.
5.2.4 Feladat: Az előző feladatot alapul véve készítsünk el a következő megoldást. Egy számot bevisz a felhasználó. Ezután a pozitív egész számokat adjuk össze addig, amíg el nem érjük a felhasználó által megadott számot.
5.2.5 Feladat: “Gondoltam egy számra 1 és 100 között” játék elkészítése.
void szamjatek() { Console.WriteLine("Gondolj egy számra 1 és 100 között!"); int max = 101; int min = 0; while (true) { int mid = min + ((max - min) / 2); Console.WriteLine("Nagyobb mint " + mid + "? (I/N) "); string answer = Console.ReadLine(); if ((answer == "I") || (answer == "i")) { min = mid; } else { max = mid + 1; } if ((min + 2) == max) { Console.WriteLine("A(z) " + (min + 1) + " számra gondoltál."); break; } } }
Véletlen szám generálása 1 és száz között a következő kóddal történhet:
Random rnd = new Random() int veletlenszam = rnd.Next(100) + 1;
5.2.6 Feladat: Az 5.1.2-es “jelszóbekérő” feladat megoldását módosítsuk úgy, hogy háromszor próbálkozhat a jelszó megadásával!
6. Tömbök és Struktúrák
6.1 Tömbök
void example8() { char[] letters = { 'r', 'e', 'd' }; Random rnd = new Random(); for (int i = 0; i < 4; i++) { int index = rnd.Next(letters.Length); char letter = letters[index]; Console.Write(letter); } Console.WriteLine(); }
6.1.1 Feladat: egy futtatásra több szót is kiírjon!
6.1.2 Feladat: a szavak hossza is legyen véletlenszerű!
6.1.3 DEBUG! (Image)
6.1.4 Hogyan fejleszthetnénk tovább az algoritmust, hogy “szebb” szavakat hozzon létre?
6.1.5 “string” típus
6.2 Struktúrák
struct Vector { public int x; public int y; }; void example9() { Vector[] vectors = new Vector[3]; for (int i = 0; i < vectors.Length; i++) { Console.Write("X: "); vectors[i].x = System.Convert.ToInt32(Console.ReadLine()); Console.Write("Y: "); vectors[i].y = System.Convert.ToInt32(Console.ReadLine()); Console.WriteLine(); } Vector result; result.x = 0; result.y = 0; foreach (Vector v in vectors) { result.x += v.x; result.y += v.y; } Console.WriteLine("Result is [" + result.x + ", " + result.y + "]"); }
6.2.1 Figyeljük meg a “foreach” használatát!
6.2.2 Jelszó bekérő (example10)
struct Credential { public string name; public string password; }; void example10() { Credential[] logins = new Credential[2]; logins[0].name = "john"; logins[0].password = "secure"; logins[1].name = "bob"; logins[1].password = "pass"; Console.Write("Login: "); string nameEntered = Console.ReadLine(); Console.Write("Password: "); string passwordEntered = Console.ReadLine(); for (int i = 0; i < logins.Length; i++) { if ((nameEntered == logins[i].name) && (passwordEntered == logins[i].password)) { Console.WriteLine("Welcome " + nameEntered + "!"); return; } } Console.WriteLine("Permission denied!"); }
7. Metódusok
Az example9 átírása.
void example11() { Vector[] vectors = new Vector[3]; for (int i = 0; i < vectors.Length; i++) { Console.Write("X: "); vectors[i].x = System.Convert.ToInt32(Console.ReadLine()); Console.Write("Y: "); vectors[i].y = System.Convert.ToInt32(Console.ReadLine()); Console.WriteLine(); } Vector result = addVectors(vectors); Console.WriteLine("Result is [" + result.x + ", " + result.y + "]"); } Vector addVectors(Vector[] vectors) { Vector result; result.x = 0; result.y = 0; foreach (Vector v in vectors) { result.x += v.x; result.y += v.y; } return result; }
7.1.1 Figyeljük meg a metódus paramétereit és visszatérési értékét!
Láthatóság
Blokkok (ismétlés)
8. OOP
(Egyelőre most csak elméleti szinten, később a gyakorlatok során visszatérünk majd rá.)
Osztály vs. Példány – Osztály = típus leíró; Példányból lehet több is. (Class / Instance)
9. Közös feladatmegoldás
Együtt gondolkodva sajátítjuk el azt, hogy egy milyen módon álljunk hozzá egy komplexebb probléma megoldásához.
9.1 Véletlen szerű számok és a nagy számok törvénye
9.1.1 Feladat: Szimuláljunk dobókocka dobást véletlen szám generátorral. A dobást ismételjük meg 10-szer.
9.1.2 Feladat: Számoljuk össze, hogy az egyes számok hányszor jelentek meg. Mosmár csak a számolás eredménye érdekes, végezzük el a számolást 100, 1000, 100 000 dobásra. Mit tapasztalunk?
9.1.2 Feladat: Írjuk át az előző feladatot úgy, hogy számoljuk két 6-os előfordulása közben hány olyan dobás volt, ami nem 6-os. Csak az érdekel, hogy mi volt a legnagyobb távolság két 6-os dobása között.
9.1.3 Feladat: Írjunk olyan programot, ami egy megadott arab számot római számmal ír ki. (Maximum 2000-ig kell helyesen működjön.)
9.2 Játékok
9.2.1 Írjuk meg közösen a Mesterlogika (mastermind) játékot. Mindig a gép gondol egy feladványra, amit a felhasználónak kell megfejtenie.
Megoldás: https://pastebin.com/VKYyPN3s
Órai megoldás: https://pastebin.com/qWhxHWkE
9.2.2 Írjuk meg a Blackjack játékot.
Elvégzendő lépések:
- Hozzunk létre egy struktúrát a kártyalap típusok tárolására. Tulajdonságok: megnevezés, érték
- Töltsünk föl egy listát a létező kártyatípusokkal.
- Írjunk egy metódust, ami kioszt egy véletlenszerű kártyalapot.
- Osszunk ki kezdésből két kártyalapot.
- Hozzunk létre egy listát a kezünkben levő kártyák letárolására, kiosztáskor ebbe a “kézbe” kerüljenek kiosztásra a lapok. (Írjuk át a metódust, hogy legyen egy bemenő paramétere, ami a lista.)
- Hozzunk létre egy metódust, ami a “kézben” lévő kártyákat kiírja a képernyőre és egyúttal összeszámolja azok értékét. A metódusnak a “kéz” legyen a bemenő paramétere és az összérték a kimenő paramétere. (Figyeljünk rá, hogy két ász esetén is 22 helyett 21 az összérték!)
- Ha az összeszámolt érték nagyobb, mint 21, akkor vesztettünk.
- Ha nem vesztettünk, osszon nekünk még egy lapot. Képezzünk ciklust: Kiírat, 21 ellenőrzése, új lap osztása. (Addig játszik, amíg nem vesztünk.)
- Egészítsük ki, hogy csak akkor osszon, ha ezt szeretnénk.
- Vezessünk be egy újabb listát az osztó “kezében” lévő kártyák tárolására. Induláskor az osztó kezébe is osszunk egy lapot, és jelenítsük meg a kezében lévő lapokat (ami igazából jelenleg egy lap lesz). Használjuk a korábban megírt függvényeket, a kiírató metódust egészítsük egy újabb paraméterrel, ahol megadhatjuk, hogy az osztó vagy a játékos kezét jelenítjük meg.
- Egészítsük ki a programot úgy, hogyha a játékos nem kér újabb lapot, akkor addig osszunk az osztónak, amíg: a) túl nem lép 21-en; b) nagyobb egyelő lesz a lapjainak értéke a játékoséval. Első esetben a játékos nyer, második esetben a bank.
Házi feladat: Legyen egyenlőség is, kezelve.
Szorgalmi feladat: Legyen egy $100-as induló tőke és minden osztás előtt rákérdezünk, hogy ebből mennyit tesz fel. (Minimum $5-et föl kell tenni.) Ha veszít a játékos, akkor ezt a pénzt elbukja. Ha nyer, akkor a tőkéje a feltett pénzmennyiséggel növekszik. Egyenlőségnél pénzénél marad.
Megoldás: https://pastebin.com/cuvXtni5
9.2.3 Írjuk meg az akasztófa játékot. Szótár: https://github.com/laszlonemeth/magyarispell/tree/master/szotar
Elvégzendő lépések:
- Töltsük le a szótárt. A projektünk egy mappájában legyen szövegfájl. (Figyeljük meg a szövegfájl szerkezetét.)
- Töltsük be a szótárat (readDict()). Használjuk a System.IO.StreamReader-et, a mintaillesztést (reguláris kifejezés) és a collection-öket (List).
- Válasszunk ki egy szót a betöltött szótárból (pickWord()).
- Írjunk ki annyi pontot, ahány betűből áll a keresett szó. (displayMaskedWord())
- Kérjünk be egy betűt a felhasználótól (askForChar()), a beadott betűt tároljuk el egy listában. (Később több betű is lesz.)
- A szó kiírását (displayMaskedWord()) módosítsuk úgy, hogy ha keresett szó aktuális betűje szerepel a beadott betűk között, akkor a pont helyett az aktuális betűt írjuk ki.
- Továbbá módosítsuk ugyanezt a metódust, hogy ellenőrizze minden betűt kitaláltunk-e. (Ha legalább egy pontot kiírtunk, akkor nincs minden betű kitalálva.) Legyen ez a BOOL a visszatérési értéke a metódusnak.
- Szervezzünk ciklust: folyton írjuk ki az állást és kérjünk be új betűt, addig amíg az összes betű ki nem találjuk. (Az, hogy ki van-e találva minden betű a displayMaskedWord() visszatérési értéke lett.)
- A játék lényegében kész.
- Módosítsuk a displayMaskedWord() metódust, hogy írja ki a beadott betűket is. String.Join(“, “, guesses.ToArray())
- Módosítsuk a programot, hogy számolja, hány próbálkozás kellett a kitaláláshoz. (Kérdés, hogy ha már korábban beadott betűt újra bead, az új próbálkozásnak számít-e.) Kilépéskor jelenítsük meg a próbálkozások számát.
Megoldás-sablon: https://pastebin.com/g0CVUrpx
9.3 Életjáték
A feladat célja megprogramozni az “Életjáték” algoritmust. A játék leírását ez a link tartalmazza: https://hu.wikipedia.org/wiki/Életjáték. A játék grafikai elemeihez a StreamGraphics keretrendszert használjuk a következő sablonnal: https://pastebin.com/ZbH06NrM
Elvégzendő lépések:
- Az ujMezo metódusban végigmenni az előző mező összes elemén.
- Metódus létrehozása, ami megszámlálja, hogy az adott mező mellett hány életet tartalmazó mező található. (Egyelőre most mindig adjon vissza kettőt.)
- Alkalmazzuk az előző számítás eredményét figyelembe véve a játékszabályokat (3 szabály). Kérdés, hogy az új mező adott cellájába kerüljön-e élet vagy sem.
- A szomszédok számolását programozzuk le. Az eredmény egy összeadás lesz a környező mezőkön található életek számával. A környező mezők vizsgálatára segédfüggvényeket hozunk létre:
- Hozzunk létre egy-egy függvényt a balra és a jobbra található mezők elemzésére. A visszatérési érték legyen 0 vagy 1.
- Hozzunk létre egy-egy függvényt a fölötte és alatta lévő mezők elemzésére. Használjuk az imént megírt ballra/jobbra függvényeket!
- Minden esetben figyejünk arra, hogy nem létezik nullánál kisebb pozíció és mezo.Length-nél kisebb pozíciók értelezettek csak.