de Andrew Bales

Cum puteți construi un joc terminal cu CSV și Ruby

În acest articol, veți învăța cum să construiți un joc terminal cu un CSV și câteva pietre Ruby! Vedeți o demonstrație în videoclipul de mai sus și găsiți codul pe GitHub.

Acest proiect vine dintr-o prelegere la care am ținut Ada Developers Academy în Seattle. Subiectul a fost biblioteca Ruby CSV și am vrut un mod distractiv de a ilustra metodele și potențialul său.

În clasă, am discutat despre modul în care majoritatea oamenilor folosesc programe precum Excel pentru a crea și edita CSV-uri. Acestea fac actualizări făcând clic pe celule și schimbând valorile. Dar întrebarea pentru noi a devenit: ce putem face cu un CSV dacă îl abordăm ca programatori? Folosind un limbaj de programare precum Ruby, cum poți deschide, citi și manipula aceste valori? Pot aceste rânduri și coloane ordonate să devină o bază de date pentru o aplicație?

Acest articol acoperă aceste întrebări în trei secțiuni:

ad-banner
  1. Valori separate prin virgulă
  2. Biblioteca CSV a lui Ruby: crearea, deschiderea, atașarea, utilizarea antetelor
  3. Construirea jocului

Valori separate prin virgulă

CSV înseamnă valori separate prin virgulă și exact așa sună. Dacă ați deschis vreodată unul dintre aceste fișiere într-un program precum Excel, ați văzut aceste valori redate într-o foaie de calcul.

Cu toate acestea, dacă ar fi să deschideți același fișier într-un editor de text precum Atom sau Sublime, ați găsi o serie de valori – le-ați ghicit – separate prin virgulă. După cum vedeți mai jos, Excel folosește acele valori brute pentru a reda un tabel ușor de utilizat.

Cum puteti construi un joc terminal cu CSV si Ruby

Instalare rapida

Este cel mai ușor de urmat dacă descărcați acest lucru Depozitul GitHub. După ce ați făcut acest lucru, navigați la acel folder din terminal. Această repo include toate din exemplele de mai jos, așa că vă rugăm să știți că va trebui să comentați secțiunile pe care nu doriți să le rulați.

De asemenea, veți dori să instalați Imprimare minunată, care înfrumusețează ieșirea terminalului:

gem install awesome_print

Biblioteca CSV a lui Ruby

Ruby vine cu un Biblioteca CSV care ne permite să deschidem, să citim și să manipulăm fișiere CSV.

Crearea unui CSV

Să începem prin a ne crea propriul CSV. În depozitul Github, veți găsi planets.rb. Acest fișier începe prin setarea planetelor variabile egale cu o matrice bidimensională (o matrice de matrice).

În fiecare, avem atribute ale planetei: id, nume, masă și distanță. Am atribuit numele atributelor variabilei anteturi ca o altă matrice.

require 'csv'require 'awesome_print'
planets = [  [1, "Mercury", 0.055, 0.4],  [2, "Venus", 0.815, 0.7],  [3, "Earth", 1.0, 1.0],  [4, "Mars", 0.107, 1.5]]headers = ["id", "name", "mass", "distance"]CSV.open("planet_data.csv", "w") do |file|  file << headers  planets.each do |planet|    file << planet  endend

Mai sus, CSV.open acceptă până la trei argumente:

CSV.open(file name, mode, options)

I-am dat un nume de fișier (planet_data.csv). Deoarece am dat și modul „w” (numai în scriere), creează un fișier nou pentru noi, chiar dacă nu exista deja. Nu au fost trecute opțiuni în acest timp.

Următorul bloc face câteva lucruri:

  1. Acesta adaugă matricea de antete la fișierul pe care l-am creat. Aceasta creează un singur rând cu patru coloane – fiecare cu o intrare șir a numelui proprietății.
  2. Folosim planets.each pentru a itera prin matricea planetei (completată cu informații despre id-ul, numele și așa mai departe) și adăugăm fiecare intrare ca un rând individual.

Dacă rulați acest bit de cod, veți găsi că a fost creat următorul CSV:

Cum puteti construi un joc terminal cu CSV si Ruby

Moduri

Mai sus, am folosit „w” ca mod pentru a scrie un fișier nou. Aveți la dispoziție o serie de alte opțiuni, în funcție de sarcina la îndemână. Cei mai mari factori de luat în considerare sunt dacă doriți să citiți și / sau să scrieți și unde doriți să începeți munca în CSV.

De exemplu, dacă utilizați fișierul pentru a vă completa site-ul web cu înregistrări, „r” (numai în citire) ar fi un mod adecvat. Dacă doriți să adăugați planete noi în CSV, modul „a” (adăugați citire-scriere) va începe la sfârșitul fișierului și vă va permite imediat să adăugați aceste rânduri.

Iată o listă completă de moduri:

“r”  Read-only, starts at beginning of file (default mode).“r+” Read-write, starts at beginning of file.“w”  Write-only, truncates existing file to zero length.“w+” Read-write, truncates existing file to zero length.“a”  Append write-only, starts at end of file if file exists.“a+” Append read-write, starts at end of file if file exists.“b”  Binary file mode.“t”  Text file mode.

Anexare

Putem adăuga o nouă planetă la planet_data.csv astfel:

CSV.open("planet_data.csv", "a") do |file|  file << [5, "Jupiter", 1234, 3321]end

În lista de moduri de mai sus, „a” este „numai în scriere” și „începe la sfârșitul fișierului”. Deci informațiile lui Jupiter vor fi inserate la sfârșitul CSV-ului existent.

Iterând

Deoarece .open cu modul „r” va returna o serie de tablouri, putem folosi .each pentru a itera peste rânduri. Codul de mai jos va imprima fiecare rând al CSV din terminal.

CSV.open("planet_data.csv", "r").each do |row|  ap rowend

Puteți face acest lucru cu un pas mai departe pentru a crea propoziții interpolate!

CSV.open("planet_data.csv", "r").each do |row|  ap "#{row[1]} has a mass of #{row[2]} and distance of #{row[3]}."end

Este minunat, dar ar putea fi ceva mai bun. Trebuie să folosim indicii (1, 2, 3) pentru a accesa datele. Acest lucru este predispus la erori și, în general, nu este distractiv. Apoi, vom vedea cum să remediem această problemă trecând opțiuni.

Utilizarea anteturilor

Când adăugați opțiunea pentru anteturi pentru a fi adevărate, veți primi înapoi un nou obiect CSV :: Table.

csv_with_headers = CSV.open("planet_data.csv", "r", headers: true, header_converters: :symbol)csv_with_headers.each do |row|  ap rowend

Citind cu anteturi și convertind acele anteturi în simboluri, vom obține înapoi un obiect unic: o serie de hashuri. Asta înseamnă că este posibil să parcurgeți fiecare rând așa cum am făcut înainte, dar apoi putem folosi și simbolurile din hash pentru a izola datele cheie.

Dacă ne întoarcem la exemplul propoziției, acesta devine:

CSV.open("planet_data.csv", "r", headers: true, header_converters: :symbol).each do |row|  ap "#{row[:name]} has a mass of #{row[:mass]} and distance of #{row[:distance]}."end

Este mult mai lizibil decât indicii numerici pe care i-am folosit înainte!

Când anteturile sunt setate la adevărat, biblioteca ne oferă obiectul CSV :: Table, care ne oferă, de asemenea, acces la unele metode la îndemână. Mai jos, .read este sinonim cu .open în modul „r”:

csv = CSV.read("planet_data.csv", headers: true, header_converters: :symbol)ap csv               # <CSV::Table mode:col_or_row row_count:6>ap csv.headers       # Returns an array of headersap csv.by_col[:id]   # Array of id column dataap csv.by_col[:name] # Array of name column dataap csv.by_row[0]     # Entire row at 0 (or any position)ap csv[:name][3]     # Name of the 3rd entry => "Mars"ap csv[3][:name]     # 3rd row's name => "Mars"

Construirea unui joc de sistem solar!

Știm cum să deschidem și să folosim date într-un fișier CSV cu Ruby, așa că haideți să punem aceste metode în funcțiune pentru a crea un joc al sistemului solar.

Cum puteti construi un joc terminal cu CSV si Ruby
Prin intermediul SUPERNOVA

Înființat

Va trebui să instalați Catpix și Launchy. Catpix permite ilustrații în terminal, iar Launchy ne permite să controlăm o fereastră de browser. În terminal:

gem install catpix gem install launchy 

CSV ca bază de date

Poate doriți să deschideți „Solar System.csv” în Excel pentru a obține vizual o imagine a atributelor pentru fiecare intrare. Odată ce vă veți simți confortabil cu datele, vom folosi Ruby pentru a citi fișierul CSV și a-l atribui unei variabile globale ($ solar_system_data). Aceasta va servi drept baza noastră de date.

Pe măsură ce jocul se deschide, îl întâmpinăm pe utilizator LA SISTEMUL SOLAR! și creați acea bază de date astfel:

require 'catpix'require 'launchy'$solar_system_data = CSV.read("Solar System.csv", headers: true, header_converters: :symbol)
ap "WELCOME TO THE SOLAR SYSTEM!"

Jocul începe cu adevărat atunci când numim metoda explore_planet. Această metodă conține acest cod:

ap $solar_system_data.by_col[:name]prompt = "Where would you like to start? 0 - #{$solar_system_data.length}"
ap promptinput = gets.chomp
until $selected_planet && /d/.match(input)  ap prompt  input = gets.chomp  $selected_planet = $solar_system_data[input.to_i]end
ap $selected_planet

Deasupra, terminalul imprimă toate numele din coloana „nume”. Apoi îi cere utilizatorului să selecteze o intrare între primul (index 0) până la ultimul (lungimea datelor noastre). Acesta este un punct bun pentru a face o pauză pentru a lua în considerare următoarele:

Întrebare: Dacă am folosit anteturi pentru a obține un hash, cum poate solar_system_data.length == 14?

Răspuns: Acest CSV :: Tabel poate uite ca un hash, dar este de fapt o serie de hash-uri. Prin urmare, are o lungime și putem itera prin fiecare hash. Pentru a selecta înregistrarea corectă, trebuie doar să convertim intrarea dintr-un șir într-un număr întreg (.to_i)

Veți vedea, de asemenea, că am folosit o declarație until. Acest lucru validează selecția – solicitând un răspuns până când utilizatorul ne dă un număr valid. Odată ce se face o selecție adecvată, terminalul imprimă informațiile despre planetă.

Utilizatorul poate alege dacă dorește să afle sau să Vadă planeta:

prompt = "Do you want to LEARN or SEE?"ap prompt
while input = gets.chomp  case input.downcase  when "learn"    Launchy.open($selected_planet[:uri])    return  when "see"    Catpix::print_image $selected_planet[:image]    return  else    ap prompt  endend

Similar cu anterior, se folosește o instrucțiune while pentru a ne asigura că obținem o intrare validă. De data aceasta, fie folosește Launchy pentru a deschide URI-ul asociat planetei, fie imprimă imaginea în terminal cu Catpix.

Jocul are încă o funcționalitate. Aceasta se ține în metoda select_attribute. Folosim metodele CSV pe care tocmai le-am acoperit pentru a returna atribute specifice fiecare planeta din baza noastră de date.

ap "Which attribute do want to see for each planet (ex: number_of_moons)?"
ap $solar_system_data.headers.to_sattribute = gets.chomp
ap "Here are the #{attribute} findings:"
$solar_system_data.each do |row|  ap "#{row[:name]} --> #{attribute}: #{row[attribute.to_sym]}"end

În primul rând, imprimăm toate anteturile ca șiruri. Aceasta oferă utilizatorului o listă de atribute din care să aleagă. Cu răspunsul utilizatorului, putem enumera numele planetei împreună cu atributul solicitat și valoarea acestuia.

În cele din urmă, pot selecta un alt atribut sau o pot începe din nou și EXPLORA planete individuale:

prompt = "SELECT another attribute or EXPLORE another planet?"ap prompt
while input = gets.chomp  case input.downcase  when "select"    select_attribute()  when "explore"    explore_planet()  else    ap prompt  endend

Sper că acest lucru vă ajută să clarificați metodele CSV și să vă entuziasmeze să vă creați propriile jocuri.

Dacă îl extindeți sau creați ceva nou, lăsați un comentariu. Mi-ar plăcea să văd cu ce veniți!