Dviejų dimensijų kūrimas rubinu

Gabrielė Cirulli
Šis straipsnis yra serijos dalis. Daugiau šios serijos straipsnių rasite skyriuje Žaidimo klonavimas 2048 in Ruby. Išsamų ir galutinį kodą rasite esmėje.
Dabar, kai žinome, kaip veiks algoritmas, laikas pagalvoti apie duomenis, su kuriais veiks šis algoritmas. Čia yra du pagrindiniai pasirinkimai: butas masyvas tam tikros rūšies arba dvimatis masyvas. Kiekvienas iš jų turi savo privalumų, tačiau prieš priimdami sprendimą, turime į ką nors atsižvelgti.
DRY galvosūkiai
Įprasta technika dirbant su tinkleliais pagrįstais galvosūkiais, kai reikia ieškoti tokių šablonų, yra parašyti vieną algoritmo versiją, kuri veikia dėlionėje iš kairės į dešinę, o tada visą galvosūkį pasukti keturis kartus. Tokiu būdu algoritmą reikia parašyti tik vieną kartą ir jis turi veikti tik iš kairės į dešinę. Tai žymiai sumažina sudėtingumą ir dydį sunkiausia šio projekto dalis.
Kadangi mes dirbsime su galvosūkiu iš kairės į dešinę, prasminga, kad eilutės būtų vaizduojamos masyvais. Kuriant dvimatį masyvą Rubinas (arba, tiksliau, kaip norite, kad tai būtų sprendžiama ir ką iš tikrųjų reiškia duomenys), turite nuspręsti, ar norite eilučių krūvos (kur kiekvieną tinklelio eilutę atvaizduoja masyvas), ar krūvos stulpelių. (kur kiekvienas stulpelis yra masyvas). Kadangi dirbame su eilutėmis, pasirinksime eilutes.
Kaip šis 2D masyvas pasukamas, sužinosime po to, kai iš tikrųjų sukursime tokį masyvą.
Dviejų dimensijų masyvų kūrimas
Metodas Array.new gali priimti argumentą, apibrėžiantį norimo masyvo dydį. Pavyzdžiui, Masyvas.naujas(5) sukurs 5 nulinių objektų masyvą. Antrasis argumentas suteikia jums numatytąją reikšmę, taigi Masyvas.naujas(5, 0) duos jums masyvą [0,0,0,0,0] . Taigi, kaip sukurti dvimatį masyvą?
Neteisingas būdas ir kaip aš matau, kaip žmonės dažnai bando pasakyti Masyvas.naujas(4, Masyvas.naujas(4,0)) . Kitaip tariant, 4 eilučių masyvas, kiekvienoje eilutėje yra 4 nulių masyvas. Ir iš pradžių atrodo, kad tai veikia. Tačiau paleiskite šį kodą:
Atrodo paprasta. Sukurkite 4x4 nulių masyvą, viršutinį kairįjį elementą nustatykite į 1. Bet atspausdinkite ir gausime…
Tai nustatė visą pirmąjį stulpelį į 1, ką tai suteikia? Kai sudarėme masyvus, pirmiausia iškviečiamas vidinis Array.new skambutis, sudarydamas vieną eilutę. Tada viena nuoroda į šią eilutę dubliuojama 4 kartus, kad būtų užpildytas atokiausias masyvas. Tada kiekviena eilutė nurodo tą patį masyvą. Pakeiskite vieną, pakeiskite juos visus.
Vietoj to turime naudoti trečias būdas sukurti masyvą Ruby. Užuot perdavęs reikšmę metodui Array.new, perduodame bloką. Blokas vykdomas kiekvieną kartą, kai metodui Array.new reikia naujos reikšmės. Taigi, jei sakytumėte Masyvas.naujas(5) { gets.chomp } , Ruby sustos ir paprašys įvesti 5 kartus. Taigi viskas, ką turime padaryti, tai tiesiog sukurti naują masyvą šiame bloke. Taigi mes baigiame Masyvas.naujas(4) { Masyvas.naujas(4,0) } . Dabar pabandykime dar kartą tą bandomąjį atvejį.
Ir tai daro taip, kaip tikėjotės.
Taigi, nors Ruby nepalaiko dvimačių masyvų, vis tiek galime padaryti tai, ko mums reikia. Tiesiog atminkite, kad yra aukščiausio lygio masyvas nuorodos į antrinius masyvus, o kiekvienas antrinis masyvas turėtų nurodyti skirtingą reikšmių masyvą.
Ką reiškia šis masyvas, priklauso nuo jūsų. Mūsų atveju šis masyvas yra išdėstytas kaip eilutės. Pirmasis indeksas 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, naudojame a[1] . Norėdami indeksuoti konkrečią plytelę antroje eilutėje, naudojame a[1][n] . Tačiau jei būtume apsisprendę dėl stulpelių... būtų tas pats. Ruby neįsivaizduoja, ką darome su šiais duomenimis, ir kadangi jis techniškai nepalaiko dvimačių masyvų, tai, ką mes darome, yra įsilaužimas. Pasiekite jį tik susitarę ir viskas laikysis kartu. Pamirškite, ką turėtų daryti apačioje esantys duomenys, ir viskas gali greitai subyrėti.