Avatar
Petr Stastny
Redaktor
Avatar
Petr Stastny:7.10.2016 21:05

Zdravím, mám problém. Píšu appku, která obsahuje 2 rozměrné pole o délce několika desítek až stovek. Abych to vykresloval (zatím to dělám prozatímně do console) lépe a bez toho problikávání, když to až moc často clearuji, rozhodl jsem se použít SetCursorPosition. Jenže mám problém.

Při každém vykreslení porovnávám pole a zjišťuji, které prvky se liší a pouze ty vykresluji. Po každém vykreslení do dalšího pole uložím stav, takže to je takhle:

  1. Změním pole
  2. Vykreslím to, co je rozdílné s kontrolním polem
  3. Překopíruju pole do kontrolního pole
  4. Opakuji

Jenže když změním pole, změní se i kontrolní pole, samo! Bez jakéhokoli setteru nebo něčeho podobného. Přikládám části kódu:

// ...
private MapObject[,] map;
private MapObject[,] mapThatWas;
// ...


// Zanasim do pole:
map[x, y] = mapObject;  // Po projiti TOHOTO radku se zanese hodnota nejen do [ map ], ale i do [ mapThatWas ]
// ...
DrawMap();



// DrawMap:

for (int x = 0; x < map.GetLength(0); x++)
            {
                for (int y = 0; y < map.GetLength(1); y++)
                {
                    // If there was no change
                    if (map[x, y] == mapThatWas[x, y])
                        continue;

                    if(x == 15 && y == 20) { }


                    Console.SetCursorPosition(x, y);

                    if (map[x, y] == null)
                        Console.Write(' ');
                    else
                        Console.Write(map[x, y].mapChar);
                }
            }
            mapThatWas = map;

Ještě něco: Toto se děje, až když měním hodnoty pole podruhé, při prvním dosazení to funguje bez problémů.

 
Odpovědět 7.10.2016 21:05
Avatar
Honza
Člen
Avatar
Honza:7.10.2016 21:20

No jasně, protože map[x, y] = mapObject; ti udělá to, že do pole map uloží referenci na mapObject. Jinými slovy máš pořád jeden mapObject ale máš na něj reference v obou polích. A tedy pokud změniš hodnotu v jednom poli, ukáže se ti nový hodnota i ve druhém poli.
Řešením je nepř. vytořit nový objekt MapObject a naplnit ho daty z kontrolního pole. Ale celkově ta implementace mi příjde trochu divoká.

Navíc nevím jak je přesně myšlený řádek map[x, y] == mapThatWas[x, y] Pokud to má být kontrola toho zda se rovnají např. souřadnice v mapObject tak to ti fungovat nebude. Tak jak to máš napsané projde jen v případě, že obě pole ukazují na stejný objekt v paměti, ale neporovnáváš jejich hodnoty.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět 7.10.2016 21:20
Snadnou cestou se daleko nedostanete, je tam velká tlačenice...
Avatar
Petr Stastny
Redaktor
Avatar
Odpovídá na Honza
Petr Stastny:7.10.2016 21:28

Ok, dik. V podstate chci zjistit, jestli se ten dany radek v poli zmenil, nebo ne, abych ho znovu nevykresloval zbytecne. Neporadil bys mi, jak to co nejlepe udelat? :-)

 
Nahoru Odpovědět 7.10.2016 21:28
Avatar
Petr Stastny
Redaktor
Avatar
Petr Stastny:7.10.2016 21:30

Nebylo by nejjednodussi si udelat pole integeru, do ktereho jenom budu ukladat souradnice pri kazde zmene pole a po vykresleni to pole promazu? Nebo mas jiny napad? :-)

Editováno 7.10.2016 21:30
 
Nahoru Odpovědět 7.10.2016 21:30
Avatar
Honza
Člen
Avatar
Odpovídá na Petr Stastny
Honza:7.10.2016 21:46

No ono záleží na tom co si představuješ pod pojmem

chci zjistit, jestli se ten dany radek v poli zmenil

Znamená to že je v obou polích uložena jiná instance proměnné a shodují se nějaké souřadnice na mapě, nebo chceš kontrolovat že obě pole ukazují na ten samý objekt? :)

Nahoru Odpovědět 7.10.2016 21:46
Snadnou cestou se daleko nedostanete, je tam velká tlačenice...
Avatar
Petr Stastny
Redaktor
Avatar
Odpovídá na Honza
Petr Stastny:7.10.2016 22:24

Chci zjistit, na kterých souřadnicích jsou v polích různé objekty a na kterých jsou stejné.

Taky mě napadlo, že bych si při každé úpravě pole někam uložil souřadnice, kde bylo něco upraveno. Ke konci bych projel ty souřadnice a vypsal. Myslíš, že je to dobré řešení?

 
Nahoru Odpovědět 7.10.2016 22:24
Avatar
Marian Benčat
Redaktor
Avatar
Marian Benčat:8.10.2016 11:16

V okamžiku, kdy chceš trackovat efektivně změny, bys měl zapřemýšlet nad "identitou objektu" .. třeba takovým typickým příkladem je Bod v 2D prostoru (v 2D poli).. pokud tomu bodu zmenim souradnici, uz to neni ten samy bod...

Ty chceš možná něco podobného? V tom okamžiku bys měl přemýšlet o Immutable objektu..

To ti zaručí právě to, že pokud bys chtěl editovat objekt, tak musíš vytvořit nový.. Díky tomudle se ti zmení ta reference... jinak to ani nejde. Udělej si tedy ten prvek toho pole immutable.. jsi schopný tedy před každým "tickem" udělat kopii předešlého pole a pak po "ticku" (po provedených změnách) projet to nové pole a porovnat jen reference.. pokud zjistis ze se zmeni, tak zaneses zmeny.. pseudo kod:

List<ImmtableObject> oldList = ....

tick() {
  List <ImmutableObject> newList = oldList.Copy();
   DoChanges(newList);

  for(int i=0; i<newList.Count; i++) {
     if (newList[i] != oldList[i]) // doslo k nejake zmene, prekreslit
     {
       redraw(newList[i]);
     }
   }
   oldList = newList;
}
Nahoru Odpovědět  +1 8.10.2016 11:16
"C# 3.0 (2007) volal Java 8 (2014), že chce svoje featury zpět"
Avatar
Luboš Běhounek (Satik):8.10.2016 11:28

Místo classy pro reprezentaci MapObjectu můžeš použít struct, takže se ti to bude chovat tak, jak čekáš - kdykoliv někam pošleš MapObject, pošle se tam kopie jeho hodnoty a ne reference.

Nahoru Odpovědět  +1 8.10.2016 11:28
:)
Avatar
Marian Benčat
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Marian Benčat:8.10.2016 11:44

A když už používáš struct, tak VŽDY ho udělej immutable, jinak se střelíš do nohy ;-)

Nahoru Odpovědět  +1 8.10.2016 11:44
"C# 3.0 (2007) volal Java 8 (2014), že chce svoje featury zpět"
Avatar
Petr Stastny
Redaktor
Avatar
Petr Stastny:8.10.2016 11:57

Ok diky vsem :-)

 
Nahoru Odpovědět 8.10.2016 11:57
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.