Dviejų matmenų masyvų kūrimas rubine

Šis straipsnis yra serijos dalis. Norėdami rasti daugiau šios serijos straipsnių, skaitykite „Žaidimo klonavimas 2048“ ruby. Norėdami sužinoti visą ir galutinį kodą, skaitykite turinį.

Dabar, kai mes žinome, kaip veiks algoritmas, laikas pagalvoti apie duomenis, kuriuos šis algoritmas veiks. Čia yra du pagrindiniai pasirinkimai: butas masyvas kažkokio ar dvimačio masyvo. Kiekvienas iš jų turi savo privalumų, tačiau prieš priimdami sprendimą turime į ką atsižvelgti.

DRY galvosūkiai

Įprasta darbo su galvosūkiais tinkleliais technika, kai reikia ieškoti tokių modelių, yra rašyti algoritmo versija, kuri veikia dėlionėje iš kairės į dešinę, o paskui visą galvosūkį sukite apie keturis laikai. Tokiu būdu algoritmas turi būti parašytas tik vieną kartą ir jis turi veikti tik iš kairės į dešinę. Tai dramatiškai sumažina sudėtingumą ir dydį sunkiausia šio projekto dalis.

Kadangi mes sieksime galvosūkio iš kairės į dešinę, prasminga, kad eilutės būtų išdėstytos masyvais. Sudarant dvimatį masyvą Rubinas

instagram viewer
(arba, tiksliau, kaip norite, kad į jį būtų kreiptasi ir ką duomenys iš tikrųjų reiškia), turite nuspręsti, ar norite eilučių krūva (kai kiekviena tinklelio eilutė žymima masyvu) arba stulpelių krūva (kai kiekviena stulpelis yra masyvas). Kadangi mes dirbame su eilėmis, mes pasirenkame eilutes.

Kaip sukasi šis 2D masyvas, pateksime iš tikrųjų sukūrę tokį masyvą.

Dviejų matmenų masyvų konstravimas

Metodas „Array.new“ gali pateikti argumentą, apibrėžiantį norimo masyvo dydį. Pavyzdžiui, Array.new (5) sukurs 5 nulinių objektų masyvą. Antrasis argumentas suteikia numatytąją vertę, taigi „Array.new“ (5, 0) duos jums masyvą [0,0,0,0,0]. Taigi, kaip sukurti dvimatį masyvą?

Netinkamas būdas ir tai, ką matau dažnai bandančius žmones, yra pasakyti „Array.new“ (4, „Array.new“ (4, 0)). Kitaip tariant, 4 eilučių masyvas, kiekviena eilutė yra 4 nulių masyvas. Ir atrodo, kad tai iš pradžių veikia. Tačiau paleiskite šį kodą:

Tai atrodo paprasta. Padarykite 4x4 nulio masyvą, viršutinį kairįjį elementą nustatykite į 1. Bet atsispausdink ir gausime ...

Visą pirmą stulpelį nustatė į 1, kas duoda? Kai sudarėme masyvus, pirmiausia iškviečiamas vidinis skambutis į Array.new, sudarant vieną eilutę. Tada viena nuoroda į šią eilutę 4 kartus dubliuojama, kad būtų užpildytas išorinis masyvas. Tada kiekvienoje eilutėje nurodomas tas pats masyvas. Pakeisk vieną, pakeisk juos visus.

Vietoj to turime naudoti trečias būdas sukurti masyvą „Ruby“. Užuot perdavę reikšmę į Array.new metodą, mes perduodame bloką. Blokas vykdomas kiekvieną kartą, kai Array.new metodui reikia naujos vertės. Taigi, jei būtų sakoma „Array.new“ (5) {gets.chomp}, „Ruby“ sustos ir paprašys įvesti 5 kartus. Taigi viskas, ką turime padaryti, yra tik sukurti naują masyvą šio bloko viduje. Taigi mes galų gale „Array.new“ (4) {Array.new (4,0)}. Dabar pabandykime dar kartą išbandyti tą pavyzdį.

Ir tai daro taip, kaip jūs galite tikėtis.

Taigi, nors „Ruby“ nepalaiko dviejų dimensijų matricų, mes vis tiek galime padaryti tai, ko reikia. Tiesiog nepamirškite, kad aukščiausio lygio masyvas yra nuorodos į antrinius masyvus, ir kiekvienas antrinis masyvas turėtų nurodyti skirtingą reikšmių masyvą.

Ką šis masyvas vaizduoja, jūs turite nuspręsti. Mūsų atveju šis masyvas išdėstytas eilėmis. Pirmasis rodyklė yra eilutė, kurią indeksuojame, iš viršaus į apačią. Norėdami indeksuoti viršutinę galvosūkio eilutę, naudojame a [0], norėdami indeksuoti kitą eilutę žemyn, kurią mes naudojame a [1]. Norėdami indeksuoti tam tikrą plytelę antroje eilėje, naudojame a [1] [n]. Tačiau jei būtume nusprendę dėl kolonų... tai būtų tas pats. „Ruby“ neturi supratimo, ką mes darome su šiais duomenimis, ir kadangi jis techniškai nepalaiko dvimačių matricų, tai, ką mes čia darome, yra įsilaužimas. Prieikite prie jo tik pagal susitarimą ir viskas susitvarkys. Pamirškite tai, ką daro turimi duomenys, ir viskas gali greitai sugriūti.