2020-12-13T15:25:52+01:00
2020-12-13T20:11:08+01:00
2022-07-19T00:42:37+02:00
Welfel
Sziasztok!
SOS-ban kellene a válasz. Írtam C#-ban egy játékot ami működik is. A baj az, hogy jó pár parancs nem fogadható el és nem tudom, hogyan kéne javítani.
Amit ki kell szedni a kódból:
• ne legyen this[pont p] indexelő -> cseréld ki egy függvényre
• ne legyen => operátor -> cseréld ki rendes get set blokkokra
• ne legyen List, vagy egy MyList saját lista implementációt csinálsz, vagy tömbre cseréld ki -> a saját lista osztály egy privát tömböt tartalmaz abból a típusból amiből helyettesíted a listát, van publikus Add, Get és Remove függvénye, a tömb mérete dinamikusan változzon, azaz Add esetén egy n+1 elemű új tömbbe átmásolod az eddigi elemeket és az utolsó helyre beszúrod az addolt elemet, remove esetén egy n-1 elemű tömb jön létre amibe azokat másolod csak át a régi tömbből ami nem a törlendő elem, a get pedig csak megkeres egy elemet és ha van akkor visszaadja, ha nincs akkor null vagy -1 vagy valami.
SOS-ban kellene a válasz. Írtam C#-ban egy játékot ami működik is. A baj az, hogy jó pár parancs nem fogadható el és nem tudom, hogyan kéne javítani.
Amit ki kell szedni a kódból:
• ne legyen this[pont p] indexelő -> cseréld ki egy függvényre
• ne legyen => operátor -> cseréld ki rendes get set blokkokra
• ne legyen List, vagy egy MyList saját lista implementációt csinálsz, vagy tömbre cseréld ki -> a saját lista osztály egy privát tömböt tartalmaz abból a típusból amiből helyettesíted a listát, van publikus Add, Get és Remove függvénye, a tömb mérete dinamikusan változzon, azaz Add esetén egy n+1 elemű új tömbbe átmásolod az eddigi elemeket és az utolsó helyre beszúrod az addolt elemet, remove esetén egy n-1 elemű tömb jön létre amibe azokat másolod csak át a régi tömbből ami nem a törlendő elem, a get pedig csak megkeres egy elemet és ha van akkor visszaadja, ha nincs akkor null vagy -1 vagy valami.
Holnap 18:00-ig kell leadjam.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Feleves_feladat_javitas
{
class Program
{
const string fajlnev = "leaderboard.txt";
static void Main(string[] args)
{
Console.CursorSize = 100;
Console.SetWindowSize(80, 30);
Console.SetBufferSize(80, 30);
dicsosegtabla e = new dicsosegtabla();
Console.WriteLine("A kurzor mozgatása a WASD-ven illetve nyilakkal.");
Console.WriteLine("Kérlek add meg a nevedet: ");
e.Nev = Console.ReadLine();
Console.WriteLine("Mennyi ideig szeretnél játszani? (percben): ");
if (int.TryParse(Console.ReadLine(), out int perc))
{
e.Ido = perc;
}
else
{
e.Ido = 0;
}
Jatek game = new Jatek(79, 24, e.Ido * 60, 1.5);
game.jatekMenet();
Console.Clear();
e.Eredmeny = game.Eredmeny;
e.Mentes(fajlnev);
dicsosegtabla[] bemenet = dicsosegtabla.Load(fajlnev);
Console.WriteLine("Dicsőségtábla");
for (int i = 0; i < bemenet.Length; i++)
{
Console.WriteLine($"{bemenet[i].Nev,-30}{bemenet[i].Ido,3} perc {bemenet[i].Eredmeny,5} pont");
}
Console.ReadLine();
}
}
public class szin
{
private const int max = 8;
private static ConsoleColor[] colors = new ConsoleColor[]
{
ConsoleColor.Cyan,
ConsoleColor.Green,
ConsoleColor.Yellow,
ConsoleColor.Red,
ConsoleColor.Magenta,
ConsoleColor.DarkCyan,
ConsoleColor.DarkGreen,
ConsoleColor.Blue
};
private static char[] szimbolum = new char[]
{
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
};
private int ertek;
public ConsoleColor Color => colors[ertek];
public char Szimbolum => szimbolum[ertek];
public bool megjelol { get; set; }
public szin(int ertek)
{
if (ertek >= max) throw new ArgumentException("Ismeretlen.");
this.ertek = ertek;
}
public static szin CreateRandom(Random randomGenerator)
{
return new szin(randomGenerator.Next(max));
}
public bool Equals(szin masik)
{
if (masik == null)
{
return false;
}
return this.ertek == masik.ertek;
}
public static szin Kulonbozo(szin jewel)
{
return new szin((jewel.ertek + 1) % max);
}
public void visszad(pont p)
{
Console.SetCursorPosition(p.X, p.Y);
Console.ForegroundColor = this.Color;
Console.Write(this.Szimbolum);
}
}
public class palya
{
private readonly szin[,] jewels;
public int szeles => jewels.GetLength(0);
public int magas => jewels.GetLength(1);
public palya(int szeles, int magas)
{
jewels = new szin[szeles, magas];
}
public szin this[pont p]
{
get
{
if (IsInBounds(p))
{
return jewels[p.X, p.Y];
}
else
{
return null;
}
}
set
{
if (IsInBounds(p))
{
jewels[p.X, p.Y] = value;
}
}
}
public bool IsInBounds(pont p)
{
return p.X >= 0 && p.X < szeles && p.Y >= 0 && p.Y < magas;
}
}
class Allapot
{
public bool Racs => ChangedCells.Count > 0;
public bool VisszaIdo => DateTime.Now - utolsoIdo > TimeSpan.FromSeconds(1);
public bool Szukseges => Racs || VisszaIdo;
public List<pont
> ChangedCells
{ get; }
private DateTime utolsoIdo;
public Allapot()
{
utolsoIdo = DateTime.MinValue;
ChangedCells = new List<pont>();
}
public void Idozito()
{
utolsoIdo = DateTime.Now;
}
}
public class Jatek
{
private readonly Random random;
private pont kuzorpozicio;
// Esély egy ékszer létrehozására, amely garantáltan különbözik minden szomszédjától, hogy ellenőrizze a nehézségeket.
private double Esely;
private DateTime JatekVege;
private int JatekHossz;
private Allapot Allapot;
private palya grid;
public int Eredmeny { get; private set; }
public Jatek(int szeles, int magas, int gameLengthSeconds, double difficulty)
{
grid = new palya(szeles, magas);
random = new Random();
kuzorpozicio = new pont(szeles / 2, magas / 2);
Esely = 1 - Math.Exp(-difficulty);
this.JatekHossz = gameLengthSeconds;
Allapot = new Allapot();
}
public void jatekMenet()
{
Init();
Teljes();
bool fut = true;
while (fut)
{
bool meccsvan = meccs();
bool ujertek = false;
if (meccsvan)
{
Oszlopok();
}
else
{
ujertek = OszlopToltes();
}
// A felhasználótol bekért információ
if (!meccsvan && !ujertek && Console.KeyAvailable)
{
fut = Felhasznalo(fut);
}
else
{
// discard all user input while it's not the user's turn
while (Console.KeyAvailable)
{
Console.ReadKey(true);
}
}
//A játék végeredménye
if (DateTime.Now > JatekVege)
{
fut = false;
}
// Képernyő frissítése
if (Allapot.Szukseges)
{
visszaFrissit();
}
System.Threading.Thread.Sleep(30);
// Az összes új ékszer/érték megállítása egy pillanatra
if (meccsvan)
{
System.Threading.Thread.Sleep(100);
}
if (ujertek)
{
System.Threading.Thread.Sleep(200);
}
}
GameOver();
}
private void GameOver()
{
string uzenet = $"G A M E O V E R - {Eredmeny} pont";
Console.CursorVisible = false;
Console.SetCursorPosition(0, grid.magas / 2 - 1);
Console.WriteLine(new string(' ', grid.szeles));
Console.WriteLine(new string(' ', grid.szeles));
Console.WriteLine(new string(' ', grid.szeles));
Console.ForegroundColor = ConsoleColor.Red;
Console.SetCursorPosition(grid.szeles / 2 - uzenet.Length / 2, grid.magas / 2);
Console.Write(uzenet);
Console.ReadKey();
}
private void Init()
{
JatekVege = DateTime.Now.AddSeconds(JatekHossz);
for (int col = 0; col < grid.szeles; col++)
{
for (int row = 0; row < grid.magas; row++)
{
pont p = new pont(col, row);
szin jewel = szin.CreateRandom(random);
while (jewel.Equals(grid[p.Bal]) || jewel.Equals(grid[p.Fel]))
{
jewel = szin.Kulonbozo(jewel);
}
grid[p] = jewel;
}
}
}
private bool meccs()
{
bool meccsvan = false;
// A kitörlendő értékek/ékszerek megjelölése
for (int col = 0; col < grid.szeles; col++)
{
for (int row = 0; row < grid.magas; row++)
{
pont p = new pont(col, row);
szin mostani = grid[p];
if (mostani != null)
{
szin right = grid[p.Jobb];
szin down = grid[p.Le];
if (mostani.Equals(down))
{
mostani.megjelol = true;
down.megjelol = true;
}
if (mostani.Equals(right))
{
mostani.megjelol = true;
right.megjelol = true;
}
}
}
}
// A kitörlendő ékszerek/értékek eltávolítása
for (int col = 0; col < grid.szeles; col++)
{
for (int row = 0; row < grid.magas; row++)
{
pont p = new pont(col, row);
szin mostani = grid[p];
if (mostani != null && mostani.megjelol)
{
grid[p] = null;
Eredmeny++;
Allapot.ChangedCells.Add(p);
meccsvan = true;
}
}
}
return meccsvan;
}
private void Oszlopok()
{
// Az összes oszlopra:
for (int col = 0; col < grid.szeles; col++)
{
int visszater = 0;
// Insertion sort of one column. Sort all nulls to the top of the column (must be stable)
// Egy oszlopot illeszt be. Mindenképp úgy rendezi, hogy az oszlopban a 0-kat a tetejére.
for (int i = 1; i < grid.magas; i++)
{
int j = i - 1;
pont p = new pont(col, j);
szin mostani = grid[p];
szin alatti = grid[p.Le];
while (j >= 0 && mostani != null && alatti == null)
{
grid[p] = alatti;
grid[p.Le] = mostani;
j = j - 1;
p = new pont(col, j);
mostani = grid[p];
alatti = grid[p.Le];
// Elements of this column may change between 0th and i-th element, and must be redrawn.
// Az elemek ebben az oszlopban, lehet változás a 0 és az i-dik elem között, és muszáj újrakészíteni
visszater = i;
}
}
// Mark changed cells for redraw
// A megjelölt cserélt cellák/betűk/jelek újrakészítése
for (int i = 0; i <= visszater; i++)
{
pont p = new pont(col, i);
Allapot.ChangedCells.Add(p);
}
}
}
private bool OszlopToltes()
{
bool ujErtek = false;
for (int col = 0; col < grid.szeles; col++)
{
pont p = new pont(col, 0);
while (grid.IsInBounds(p) && grid[p] == null)
{
szin jewel = szin.CreateRandom(random);
if (random.NextDouble() < Esely)
{
while (jewel.Equals(grid[p.Bal]) || jewel.Equals(grid[p.Jobb]) || jewel.Equals(grid[p.Fel]) || jewel.Equals(grid[p.Le]))
{
jewel = szin.Kulonbozo(jewel);
}
}
grid[p] = jewel;
Allapot.ChangedCells.Add(p);
ujErtek = true;
p = p.Le;
}
}
return ujErtek;
}
private bool Felhasznalo(bool fut)
{
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
switch (keyInfo.Key)
{
case ConsoleKey.W:
mozgathatoHa(kuzorpozicio.Fel);
break;
case ConsoleKey.A:
mozgathatoHa(kuzorpozicio.Bal);
break;
case ConsoleKey.S:
mozgathatoHa(kuzorpozicio.Le);
break;
case ConsoleKey.D:
mozgathatoHa(kuzorpozicio.Jobb);
break;
case ConsoleKey.UpArrow:
csereHa(kuzorpozicio.Fel);
break;
case ConsoleKey.LeftArrow:
csereHa(kuzorpozicio.Bal);
break;
case ConsoleKey.DownArrow:
csereHa(kuzorpozicio.Le);
break;
case ConsoleKey.RightArrow:
csereHa(kuzorpozicio.Jobb);
break;
case ConsoleKey.Escape:
fut = false;
break;
default:
break;
}
Console.SetCursorPosition(kuzorpozicio.X, kuzorpozicio.Y);
return fut;
}
private bool Cserelheto(pont from, pont to)
{
bool vegeredmeny = false;
szin jewel = grid[from];
if (jewel == null)
{
return false;
}
foreach (pont point in to.nyilak)
{
if (!from.Equals(point) && jewel.Equals(grid[point]))
{
vegeredmeny = true;
}
}
Mutasd a teljes hozzászólást!
Na írogattam egy kicsit:
ne legyen this[pont p] indexelő -> cseréld ki egy függvényre:
Ezt szerintem nem lehet egy függvénnyel megcsinálni, csak kettővel, így javaslok egy
GetGridColor és SetGridColor függvényt.
Használatra példák:
helyett:
"setter":
ne legyen => operátor -> cseréld ki rendes get set blokkokra:
Tehát ne használd az úgynevezett "Expression-bodied members" szintaxist, hanem sima getter:
ne legyen List...:
Itt elegánsabb egy saját List osztály, mert akkor alig kell a kód többi részén változtatni:
Remélem, világos, hogy hogyan kell használni, én teszteltem, és látszólag ugyanúgy működött a játék. Ha valami hiba maradt, azt már rád bíznám.
Teljes működő kódot nem szeretnék adni, így is megírtam helyetted :)
A kódod amúgy elég kaotikus, pl nem javasolt keverni az angol és magyar változóneveket, megjegyzéseket, a nevek nem mindig beszédesek, hol kis, hol nagybetűs egy függvény(metódus inkább C#-osan) stb.
Olvasnivaló, amik hasznosak lehetnek a feladat kapcsán:
Getter property with arguments
How to use foreach keyword on custom Objects in C#
Üdv.
ne legyen this[pont p] indexelő -> cseréld ki egy függvényre:
Ezt szerintem nem lehet egy függvénnyel megcsinálni, csak kettővel, így javaslok egy
GetGridColor és SetGridColor függvényt.
public szin GetGridColor(pont p)
{
if (IsInBounds(p))
{
return jewels[p.X, p.Y];
}
else
{
return null;
}
}
public void SetGridColor(pont p, szin sz)
{
if (IsInBounds(p))
{
jewels[p.X, p.Y] = sz;
}
}
jewel.Equals(grid[p.Bal])
jewel.Equals(grid.GetGridColor(p.Bal))
grid[p] = jewel; // helyette:
grid.SetGridColor(p, jewel);
ne legyen => operátor -> cseréld ki rendes get set blokkokra:
Tehát ne használd az úgynevezett "Expression-bodied members" szintaxist, hanem sima getter:
public ConsoleColor Color // az egész amúgy mehet egy sorba is
{
get
{
return colors[ertek];
}
}
Itt elegánsabb egy saját List osztály, mert akkor alig kell a kód többi részén változtatni:
class MyList
{
int count = 0;
private pont[] changedCells = new pont[0];
private pont[] newArray;
public int Count { get { return changedCells.Length; } }
// ha megengedett, akkor ezzel használhatod a listát
// foreach-csel is (pont p in ChangedCells.Cells),
// ha nem, akkor marad a sima for ciklus, vagy GetEnumerator..., stb-t írsz
public pont[] Cells { get { return this.changedCells; } }
public void Add(pont p)
{
++count;
newArray = new pont[count];
for (int i = 0; i < changedCells.Length; ++i)
{
newArray[i] = changedCells[i];
}
newArray[count - 1] = p;
changedCells = newArray;
}
public pont Get(int idx)
{
if (idx >= 0 && idx < this.Count)
{
return changedCells[idx];
}
else
{
// itt valamit vissza kell adni, amivel jelzed,
// hogy érvénytelen elemre hivatkozol
return new pont(-1, -1);
}
}
public void Clear()
{
count = 0;
changedCells = new pont[0];
}
// Az idx-edik elem törlése, de ezt amúgy nem használod
// a kódban, de a leírás szerint kell...
// szerk: a Remove hibás volt, elvileg most már jó:
public void Remove(int idx)
{
if (!(idx >= 0 && idx < this.Count))
{
return;
}
--count;
newArray = new pont[count];
int j = 0;
for (int i = 0; i < this.Count; ++i)
{
if (i != idx)
{
newArray[j] = changedCells[i];
++j;
}
}
changedCells = newArray;
}
}
Teljes működő kódot nem szeretnék adni, így is megírtam helyetted :)
A kódod amúgy elég kaotikus, pl nem javasolt keverni az angol és magyar változóneveket, megjegyzéseket, a nevek nem mindig beszédesek, hol kis, hol nagybetűs egy függvény(metódus inkább C#-osan) stb.
Olvasnivaló, amik hasznosak lehetnek a feladat kapcsán:
Getter property with arguments
How to use foreach keyword on custom Objects in C#
Üdv.
Mutasd a teljes hozzászólást!
- rocketmanválasza Welfel (15:26) részére
- 2020.12.13. 15:47
- permalink
Üdv!
Első körben nem ártana, ha valahogy sikerülne a teljes fordítható forráskódot beilleszteni.
Ha esetleg a prog.hu fórummotorja rontotta el, akkor csatold mellékletként a .cs fájlt.Mutasd a teljes hozzászólást!- Welfelválasza Welfel (15:26) részére
- 2020.12.13. 15:53
- permalink
Bocsánat, csak eddig nem engedte.
Itt van:Mutasd a teljes hozzászólást!Csatolt állomány- Program.cs19,81 KB
- Na írogattam egy kicsit:
ne legyen this[pont p] indexelő -> cseréld ki egy függvényre:
Ezt szerintem nem lehet egy függvénnyel megcsinálni, csak kettővel, így javaslok egy
GetGridColor és SetGridColor függvényt.
public szin GetGridColor(pont p) { if (IsInBounds(p)) { return jewels[p.X, p.Y]; } else { return null; } } public void SetGridColor(pont p, szin sz) { if (IsInBounds(p)) { jewels[p.X, p.Y] = sz; } }
jewel.Equals(grid[p.Bal])
jewel.Equals(grid.GetGridColor(p.Bal))
grid[p] = jewel; // helyette: grid.SetGridColor(p, jewel);
ne legyen => operátor -> cseréld ki rendes get set blokkokra:
Tehát ne használd az úgynevezett "Expression-bodied members" szintaxist, hanem sima getter:
public ConsoleColor Color // az egész amúgy mehet egy sorba is { get { return colors[ertek]; } }
Itt elegánsabb egy saját List osztály, mert akkor alig kell a kód többi részén változtatni:
class MyList { int count = 0; private pont[] changedCells = new pont[0]; private pont[] newArray; public int Count { get { return changedCells.Length; } } // ha megengedett, akkor ezzel használhatod a listát // foreach-csel is (pont p in ChangedCells.Cells), // ha nem, akkor marad a sima for ciklus, vagy GetEnumerator..., stb-t írsz public pont[] Cells { get { return this.changedCells; } } public void Add(pont p) { ++count; newArray = new pont[count]; for (int i = 0; i < changedCells.Length; ++i) { newArray[i] = changedCells[i]; } newArray[count - 1] = p; changedCells = newArray; } public pont Get(int idx) { if (idx >= 0 && idx < this.Count) { return changedCells[idx]; } else { // itt valamit vissza kell adni, amivel jelzed, // hogy érvénytelen elemre hivatkozol return new pont(-1, -1); } } public void Clear() { count = 0; changedCells = new pont[0]; } // Az idx-edik elem törlése, de ezt amúgy nem használod // a kódban, de a leírás szerint kell... // szerk: a Remove hibás volt, elvileg most már jó: public void Remove(int idx) { if (!(idx >= 0 && idx < this.Count)) { return; } --count; newArray = new pont[count]; int j = 0; for (int i = 0; i < this.Count; ++i) { if (i != idx) { newArray[j] = changedCells[i]; ++j; } } changedCells = newArray; } }
Teljes működő kódot nem szeretnék adni, így is megírtam helyetted :)
A kódod amúgy elég kaotikus, pl nem javasolt keverni az angol és magyar változóneveket, megjegyzéseket, a nevek nem mindig beszédesek, hol kis, hol nagybetűs egy függvény(metódus inkább C#-osan) stb.
Olvasnivaló, amik hasznosak lehetnek a feladat kapcsán:
Getter property with arguments
How to use foreach keyword on custom Objects in C#
Üdv.Mutasd a teljes hozzászólást!