[VB.net] 2D Array-grid, "vul vak"

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Umbrah
  • Registratie: Mei 2006
  • Laatst online: 19:19

Umbrah

The Incredible MapMan

Topicstarter
Geachte programmeurs,

In 704 posts van hoofdzakelijk mensen helpen, heb ik 3 topics zelf gemaakt: geachte redactie posts. Het is helaas op dit moment zo dat ik nu toch om hulp moet vragen.

Situatieschets:
BI student die, hoewel ondertussen redelijk vaardig in databases/VB.net koppelingen, en volgens mij zelf, niet zo'n ontzettend ei. Het lot wil echter: het is vakantie, en in de vakantie; wil ik wat "verder" gaan met wat ik al weet. Ideaal hiervoor leek mij een "simpel" spelletje, in de vorm van mijnenveger. Besloten is besloten (ik had ook voor een supersimpele als zeeslag kunnen gaan, maar ons bent nou eenmaal koppig, zoals de Friezen zeggen), ik had ook voor Zeeslag of Stratego kunnen gaan, maar goed, mijnenveger it is, en ambitie is er ook. Mijn hobby "koppel overal databases aan vast" moet er in komen, in de vorm van een high-score, en eventueel ook een profielen/achievement systeem. Alsof men mijnenveger zo wil spelen.

Enfin, vol goede moed wat geschetst en bedacht (niks geen UML activity diagrams of PSD's gemaakt, dat doe ik wel voor school opdrachten), en aan het coderen geslagen.

De keuze is gevallen op 2D arrays (met een duidelijke X/Y locatie, en input in de vorm van aantal mijnen, breedte en hoogte), en zo veel mogelijk "simpele" code die ik eventueel later aan beginners kan uitleggen, die het per deelprobleem aan gaan pakken. Vandaar dat vooral de "spawn nummers naast mijnen" code een gedrocht is, en een verdeling in deelproblemen:

1. Maak een knoppen-array (jaja, elementen en handlers via code leren ze ons ook niet meer tegenwoordig op het HBO, alles maar op de designer slepen, en hooguit aanpassen via code).
1.2 Maak een schaduw array voor de knoppen array (als string), met een "." voor niet-mijnen, en "#" voor mijnen
1.3 Tijdelijke schaduw-array waar de nummers die er rond mijnen zitten neergekwakt worden (als integer).
1.4 "Merge" de arrays in een derde string-array, met weergave prioriteiten: 1. Mijnen; 2. Nummers; 3. "lege vakken als ".".
1.5 maak een schaduw array die knop-statussen weergeeft; 0 voor "ingedrukt", 1 voor "niet ingedrukt", en 2 voor "vlaggetje"
2. Handler rechts klikken:
2.1 Als statuswaarde van dat vak 2 is, maak het 1 en werk de knop bij (op dit moment: naar gewoon)
2.2 Als statuswaarde van dat vak 1 is, maak het 2 en werk de knop bij (op dit moment: naar groen)
3. Handler links klikken (alles op voorwaarde dat de statuswaarde van die knop 1 is):
3.1 Als er een "#" in de merge-array staat op dat vak: Game over, laat mijnen zien (als rood)
3.2 Als er een "nummer" staat in de merge-array (test door boolean als een CInt lukt in een try..catch) > open alleen DAT vak, en laat het nummer zien.
3.3 Als er een "." in de merge-array staat op dat vak: open alle aanliggende lege vakken, en hun aanliggende nummervakken.

En bij punt 3.3 zit het probleem: hij controleert de nummers die naast het geklikte vak liggen, geeft al die nummers weer, maakt het vak zelf leeg, maar ik heb geen flauw idee wat te doen om de rest van het "vlak" ook leeg te maken.

Dingen die ik geprobeerd heb:

1. Bepaal hoe ver omhoog/omlaag tot het volgende nummer
1.1. Van hoog naar laag: bepaal hoe ver links, hoe ver rechts, en open die vakken

Dat was een "stapje", maar het probleem verscheen bij vormen die een uitstulping hebben, zoals dit:
code:
1
2
3
4
...#...#..
..######..
##########
.....###..


Het algoritme zou werken voor alle vakjes, behalve het tweede hekje rechtsboven. En dat moeten we niet hebben.

Ik heb nu ongeveer 2 dagen lopen klooien met dit projectje, en op een paar stukken code van anderen na die niet helemaal combineren met mijn stuk (als in: geen idee hoe het er in te knopen, die gasten werken compleet anders), en mijn conclusie is: een BI-er met slechts basis programmeer ervaring lukt dit niet. Ik denk te bedrijfskundig, om het zo te zeggen, en mijn programmeersel is nou ook niet zo... "systematisch", om het netjes te zeggen.

In ieder geval; ik vroeg me af of er hier mensen waren die mij hier mee zouden kunnen helpen. Voor de liefhebbers: plaats relevante code, geen complete projecten

Relevante code. MMMkay, ik ben hier absoluut niet goed in, maar het volgende is het geval: de "klik" functie heeft het volgende:

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
If e.Button = MouseButtons.Left Then
..
'De code trekt de "tag" uit de button properties, die weergegeven is in de vorm "X:Y". Dit wordt door een parsertje verwerkt naar 2 absolute integers: AnalyzeBEFORE, AnalyzeAFTER.

'Via een If-je:
If strSuperarray(intTagAnalyzeBEFORE, intTagAnalyzeAFTER) = "." Then '(strSuperArray is de array waar alle waarden instaan, "." is een lege knop, door de before/after als coördinaten in te voeren)
                    leegtevak(intTagAnalyzeBEFORE, intTagAnalyzeAFTER)

'roep ik de sub aan die de actie moet gaan uithalen. De aanliggende nummers weergeven, de knop uitzetten, en de nummers weergeven in de knoppen naast een mijn werkt. Wat niet werkt is de rest van het vak openen, en ik heb geen idee hoe ik dat moet doen!:

Do
            If strSuperarray(horizontal, vertical) = "." Then 'als er op een leeg vak gedrukt wordt;

                Call staatereengetal(horizontal - 1, vertical + 1) 'ne
                blnNE = blnIsgetal
                
                If blnN = True Then
                    Try
                        aButton(horizontal - 1, vertical).Enabled = False
                        aButton(horizontal - 1, vertical).Text = strSuperarray(horizontal - 1, vertical)
                        intInputFilter(horizontal - 1, vertical) = 0
                    Catch
                    End Try
                End If

'over codegedrochten gesproken: Staatereengetal is een sub die checkt of er in een vak met ingegeven coördinaten een getal staat, en een true/false boolean uitgeeft. Ik heb dus 8 booleans, voor alle aanliggende vakken één. Nadat ik alle 8 booleans bepaald heb, voer ik dmv. een if-statement code uit die de vakken opent als er een omringend nummer is.


'tot daar ben ik gekomen; niet verder. Ik weet wat de naastliggende vakken zijn, maar het punt is: hoe laat ik hem dit allemaal herhalen (gok zo: boolean, met een do .. until boolean = waar, maar hoe bepalen of die boolean waar is?), door dezelfde code nog een keer uit te voeren op nóg een ander leeg vak, maar NIET op lege vakken die niet "bereikbaar" zijn voor het huidige lege vak?

Het project staat vol debug code, (als in: 3 rich text fields waar ik arrays op pomp, en het is nog in windows forms in plaats van het uiteindelijke WPF, en de DB-link/score is ook nog niet verwerkt). Voor mensen die geen VS2010 hebben (en dus gezeur over het feit dat het met een nieuwere versie is gemaakt): alle code staat in Form1.vb, en zou ook in VB2005 of hoger moeten werken, zolang het form maar de volgende elementen heeft:

1. Een auto-sizing panel genaamd grpButtongrid
2. Een label genaamt lblOutput
3. Drie richtext boxes (met een monotype font) genaamd txtUitvoer, txtNumbers, txtCompilatie, allen in staat om dat monotype in een grid van 20*20 tekens weer te geven
4. Een knop genaamd "button1" die als new game knop functioneert.
5. Een numbericUp/Down genaamd nmbrNumberofMines met als minimumwaarde 1, maximumwaarde 100.
6. Twee numbericUp/Down elementen genaamd nmbrWidth en nmbrHeight; beiden met een bodemgrens van 5, en bovengrens van 20.

Bij voorbaat bedankt voor de hulp, en mijn excuses voor de lang uitgevallen startpost.

[ Voor 18% gewijzigd door RobIII op 23-02-2010 22:38 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Ik zie even niet waarom je zo'n shitload aan schaduwarrays hebt :?
1 array met waar de mijnen zitten lijkt me voldoende? De knoppen onthouden hun state zelf maar, en als je cijfers wil weergeven kun je de array met mijnen raadplegen en "ter plekke" bepalen waar welke cijfers getoond moeten worden.

Verder: we zien hier graag (stukjes, relevante!!!) code; geen complete projecten gedumpt om dan vervolgens het fixen aan ons over te laten: Kan iemand even...?. Ook al is het misschien niet zo bedoeld, als het goed is kom je een heel eind met het plaatsen van een paar regels code.

Ik heb dan wél nog even in je project gekeken en wil je graag de volgende tips meegeven:
  1. Programmeer in engels: just do it.
  2. Programmeer in engels en stick with it: Ik zie een Sub newgame() en een Sub ResetAlles()?
  3. Programmeer in engels en verzin geen vertalingen: hermaakArrays() :? :X klikbewerkerk :?
  4. Leer je af om variabelen te prefixen met hun type (Hungarian Notation = bah)
  5. Zorg voor zinnige method/variabele/property/etc.-namen. strTruF :?
  6. Kies een casing en stick with it... newgame is all-lower, ResetAlles is CamelCase?
  7. Whitespace is niet duur :P Her en der een welgeplaatste lege regel(s) maakt je code duizend keer leesbaarder dan 1 lange zooi tekst van ~400 regels code
  8. Commentaar! Het commentaar dat je hebt is wel érg karig.

[ Voor 79% gewijzigd door RobIII op 23-02-2010 22:16 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Umbrah
  • Registratie: Mei 2006
  • Laatst online: 19:19

Umbrah

The Incredible MapMan

Topicstarter
Het is nog schets, met een hoop debuggerij. En de knoppen hun state bewaren, tsja, ik zou niet weten waar ik buiten "tag" zoiets in een knop zet. Zoals ik zei: mijn kennis is erg rudimentair op dit punt. De tag gebruik ik voor een absolute "X:Y" waarde gescheiden door dubbele punt, omdat ik op geen enkele andere manier dat specifieke doorkrijg in de handler. De handler voert dus ook een simpele parser uit om te bepalen wélke knop is ingedrukt, voordat "aButton(resultaatparser1, resultaatparser2).bgcolor = color.green" wordt uitgevoerd.

Ja, ik zie zelf ook wel dingen die beter kunnen, maar het is vooral een doel om het allemaal te leren. Dat is de hoofdreden dat ik niet iemand anders z'n mijnenveger heb gejat, en zelf stap voor stap ben begonnen. Uiteindelijk worden maar 3 arrays echt gebruikt: de knoppen (waar de text wordt aangepast van leeg naar nummer voor het aantal mijnen, waar nummer uit een schaduw array komt); de "merged array" als bron voor de rest, en de "status" numerieken om te voorkomen dat er links kan worden gedrukt op een "vlag" knop, maar om er voor te zorgen dat er wél rechts op gedrukt kan worden.

(offtopic: die 30/40 regels code om de mijnen rondom te tellen had ik O.A. kunnen doen met een for-lusje met een -1 naar +1 tellertje, wat het rondje om de mijn heen maakt).

En ja, commentaar. Ik weet het. Ik weet het. Ik weet het! Ik heb mezelf al gebitchslapped!

White spaces: Dat wist ik niet! Ik heb altijd geleerd (je ziet misschien ook wel: subleegtevak heeft ze wel!) om code als je klaar bent zo "compact" mogelijk te maken. Bedankt voor de tip. Naast het commentaar wat ik mezelf echt aan moet leren, is dat iets om in de toekomst wel te doen. Ik ben nog nooit echt tegen de noodzaak aangelopen in mijn korte carrière. Ik zit nu in BI2 (minor systeemontwikkeling, waar de focus vooral ligt op de methodiek en database links, en niet zozeer het coderen), en vorig jaar, BI1, was de cursus van het niveau "kennismaken met". Hoewel ik al wel het MBO gedeelte, en een redelijk stukje Assembly van een vorige opleiding + Java (met BlueJ!) had gehad.

Maar goed, defensief moet ik niet zijn, ik stel alle hulp op prijs. Bovenstaande tekst is vooral om mijn kennisniveau te schetsen (hoewel ik een aardige zelf-uitzoeker ben, en niet post als ik niet echt radeloos ben!)

[ Voor 27% gewijzigd door Umbrah op 23-02-2010 22:19 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Umbrah schreef op dinsdag 23 februari 2010 @ 22:11:
En de knoppen hun state bewaren, tsja, ik zou niet weten waar ik buiten "tag" zoiets in een knop zet.
Basic OOP. Leid je eigen knop af van een bestaande :?
Umbrah schreef op dinsdag 23 februari 2010 @ 22:11:
Zoals ik zei: mijn kennis is erg rudimentair op dit punt. De tag gebruik ik voor een absolute "X:Y" waarde gescheiden door dubbele punt, omdat ik op geen enkele andere manier dat specifieke doorkrijg in de handler.
Ook dat is natuurlijk makkelijk te implementeren in een eigen property van je MyButton ;) Again: basic OOP. Maak een custom control die je afleid van een button en breid die uit met de properties/methods die je wenst te hebben.
Umbrah schreef op dinsdag 23 februari 2010 @ 22:11:
Uiteindelijk worden maar 3 arrays echt gebruikt
Op 't eerste gezicht zijn 't er 2 teveel ;)
Umbrah schreef op dinsdag 23 februari 2010 @ 22:11:
(offtopic: die 30/40 regels code om de mijnen rondom te tellen had ik O.A. kunnen doen met een for-lusje met een -1 naar +1 tellertje, wat het rondje om de mijn heen maakt).
Als het je code leesbaarder maakt: doen! En anders splits je het op in een aantal kleinere methodes die elk weer hun ding doen. Een sub van 30/40 regels (en dat is overigens nog beschaafd hoor, ik zie zat erger) waar 8 keer hetzelfde wordt gedaan voor een andere 'windrichting' leest nou niet echt fijn ;) DRY!
Umbrah schreef op dinsdag 23 februari 2010 @ 22:11:
White spaces: Dat wist ik niet! Ik heb altijd geleerd (je ziet misschien ook wel: subleegtevak heeft ze wel!) om code als je klaar bent zo "compact" mogelijk te maken.
Degene die je dat bijgebracht heeft is in 1928 geslaagd voor z'n lerarenopleiding dan? Als je dan toch aan 't bitchslappen bent dan bitchslap diegene gerust ook maar even onmeunig hard.

Overigens, wat ik nog vergat te zeggen: als je in plaats van buttons nou eens checkboxes gebruikt en hun appearance op button zet. Hoe je meteen geen minder state meer te onthouden ;) En als je dan van een checkbox je eigen usercontrol afleidt ... ;)

[ Voor 21% gewijzigd door RobIII op 23-02-2010 22:36 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij