• Welcome to the new COTI server. We've moved the Citizens to a new server. Please let us know in the COTI Website issue forum if you find any problems.

Hobbit Style Birthday Present

Leitz

SOC-14 1K
Admin Award
Baron
Hobbits give others presents on their birthday. I'm a bit tall for a hobbit but well rounded enough to do for. Today is my birthday and I wanted to give us both a present.

Star Merchant actually runs! While it has lots of tests it is still fragile, there's very little error checking and user input is only nominally validated. So far. I wanted to prove to myself that I could take a slightly larger than my usual program and make it work.

Here's a sample short run. Those of you doing other C based languages like TCL, Python, Java, etc, should have no problem replicating my Ruby. I'm using JSON and CSV files and straight unit tests.

Code:
Welcome Captain Ian Domici, the Spinward Quest is ready.
We are currently at Haearn.
Port: Haearn, Cash: 215987601, Open Cargo Space: 153
  textiles : 3
  spice : 5
  weapons : 9
  medicinals : 30
  rare metals : 0
(b)uy, (s)ell, (j)ump, or <q>uit?
b
There is 46 of rare metals; buy?
y
Port: Haearn, Cash: 215527601, Open Cargo Space: 107
  textiles : 3
  spice : 5
  weapons : 9
  medicinals : 30
  rare metals : 46
(b)uy, (s)ell, (j)ump, or <q>uit?
j
Here are the possible jump destinations:
Birach: UWP 777888, Location: -1,1, Trade: Ag
Saorsa: UWP 888777, Location: 2,-1, Trade: Ag
Haearn: UWP 999999, Location: 0,0, Trade: Ag
Which one do we chart for?
Birach
Jumping to Birach.
Port: Birach, Cash: 215527601, Open Cargo Space: 107
  textiles : 3
  spice : 5
  weapons : 9
  medicinals : 30
  rare metals : 46
(b)uy, (s)ell, (j)ump, or <q>uit?
s
Here are the offers, one by one:
Cargo: textiles Offer: 13500.0.
Sell? [y/n]
y
Cargo: spice Offer: 22500.0.
Sell? [y/n]
n
Cargo: weapons Offer: 40500.0.
Sell? [y/n]
n
Cargo: medicinals Offer: 135000.0.
Sell? [y/n]
n
Cargo: rare metals Offer: 207000.0.
Sell? [y/n]
n
Port: Birach, Cash: 215530601, Open Cargo Space: 110
  textiles : 0
  spice : 5
  weapons : 9
  medicinals : 30
  rare metals : 46
(b)uy, (s)ell, (j)ump, or <q>uit?
b
There is 70 of spice; buy?
y
Port: Birach, Cash: 215355601, Open Cargo Space: 40
  textiles : 0
  spice : 75
  weapons : 9
  medicinals : 30
  rare metals : 46
(b)uy, (s)ell, (j)ump, or <q>uit?
q
 
More grey hares than carrots, I'm afraid...

I've started using the "Issue" tracker on GitHub, if anyone is interested in helping out. Some of the issues are marked "Good First Issue" if you want to learn some more Ruby. Anyone skilled with C based languages (C, Java, TCL, Python) shouldn't have difficulty picking up Ruby.

On another note I'm storing data files as CSV and JSON. If you want to steal...err...reuse any of it for coding in a different language, let me know. Trying to keep things portable and documented. For example, here's the cargo.csv file. Note that the prices are bogus, haven't started on that bit yet. Still in early development phase. :)

Code:
# title: base price: per unit volume in dT: sell mods : buy mods
textiles:1000:1:Ag 7:Hi 2, NA 3
medicinals:5000:1::In 2, Po 2, Ri 2
vehicles:6000:4:In 2:Ni 2, Hi 1
rare metals:10000:1::Ri 2, In 3
spice:2500:1::Hi 2, Ri 3, Po 3
weapons:4500:1:Hi 2: Po 6
 
No header for the CSV? Is that a Ruby thing?

I'm keeping it simple and not actually using the CSV gem for this. Yet, anyway. Any line that starts with a "#" is ignored, input wise. The line "next if name.start_with?" does that.

Code:
  def get_cargo_options(data_dir, file)
    require 'cargo'
    cargo_data = get_data_csv(data_dir, file)
    cargo = Hash.new
    cargo_data.each {|c|
      name        = c[0]
      next if name.start_with?('#')
      base_price  = c[1]
      cargo_hash = {'name' => name, 'base_price' => base_price}
      cargo[name] = Cargo.new(cargo_hash)
    }
    cargo
  end
  module_function :get_cargo_options
 
No header for the CSV? Is that a Ruby thing?

actually very common and CSV is entirely language agnostic. Most of the time you consume data knowing what you are getting. HL7 files, for instance, have a 3 digit code indicating the type of record, and then it is all | ^ and other interesting field/repetition data. You have to RTFM to know what is where.

Ruby, particularly Rails, as some interesting opinions (Rails will not let you use upper case variables. Really. Drives me nuts as in C# at least, public fields (attributes in Ruby) are caps by convention to indicate that they are public (private usually lower case, often preceded with an underscore. And that throws me off a bit from my C programming days...)
 
I've been using a header in my CSV files so that Python knows what the variable names to use are when reading the data.

I can see the utility in that, you could make the dict key based on the header. Since my code is pretty raw, and others might want to add to and use it without my snake case name scheme, I'll holding off for the nonce. I do like the idea, though...
 
I had hoped to provide the bit of code to the community, as my 2019 birthday present. Sadly, work issues took up a lot of time, and dealing with the potential to start job-hunting again took up even more time.

That said, here's what I'm doing as my 2019 Hobbit Style Birthday present.

Code:
Crew

    Pilot: Lizabeth Colon [ F ] 897758 ( 5 terms) Age: 39    Brawling-1, Carouse-2, Pilot-3
    Navigator: Coralee Maury [ F ] 87B986 ( 3 terms) Age: 31    Brawling-2, Navigation-2
    Engineers:
        Noble Barna [ M ] 8C7649 ( 2 terms) Age: 28    Carouse-1, Engineering-2, Vehicle-1
        Winford Hanssen [ M ] 883632 ( 5 terms) Age: 41    Carouse-1, Engineering-3, Survival-2
    Medic: Kip Rey [ M ] A62774 ( 3 terms) Age: 32    Carouse-1, Medic-2, Survival-1
    Steward: Murray Nilsen [ M ] 388896 ( 5 terms) Age: 39    Brawling-1, Carouse-1, Gamble-1, Steward-3
    Gunners:
        Jimmy Munro [ M ] 985442 ( 4 terms) Age: 35    Brawling-2, Gunner-3, Stealth-1
        Theron Pollard [ M ] 654968 ( 5 terms) Age: 40    Brawling-1, Gamble-1, GunCbt-1, Gunner-3

There are lots of ways to make this better, and the code repo issues page has a list of known improvements.

While the code is always free and open, that's not this year's present. Ruby is an easy language to learn, if you've thought about wanting to program but never picked up on it, or if you did stuff "back in the day" and would like to learn a modern object oriented language, there's no time like the present!

And that is 2019's present. I'm not a Ruby master, my code is very simple. I am an experienced mentor, and would be happy to help one or two people learn to program. If you're willing to do the work to learn, you can be enjoying your first Ruby in a matter of hours. You can probably read the project's code in a matter of days. In a week or two, at most, you can edit it locally to put in the skills and business logic you prefer.

Think about it. I'll be off-line for a week or so, you have time to poke at Ruby and see if it is for you. You can:
 
HAPPY BIRTHDAY, LEITZ.

Personally, I would like to have a few more grey hares to feed carrots too.

I was at my 50th High School Reunion last weekend, and while I had no trouble recognizing some of the girls, the guys were a lot harder. And no, recognizing a lot of the girls does not mean that I dated in high school. The first time I went out on a date, the girl invited me. The odd thing is that she kept inviting me when she went off to college whenever she came home.
 
I did leave a comment in the repo about DB vs flat files. Essentially serializing to/from JSON or XML may be easier, and SQLite, assuming your classes inherit from a base class that has the DB stuff integrated, is another option.

Thanks for the Hobbit present: I do need to learn Ruby (we use Rails at work) but so far am stuck in the world of Filemaker (basically Access for Macs). We are converting the FM stuff to Rails for a variety of reasons, and this could be a low barrier way for me to pick it up (as mentioned, Ruby, and especially Rails, has some opinions I just don't agree with, but hey, I am an old developer with old habits. And get off my lawn!)
 
Hey timerover51, I think you pre-date me by a year or two. Not more than a decade, though, is my guess. :)

I find programming to be rejuvenating and I really don't want to retire. Ruby is great for rapid prototyping and a hoot to code in; hopefully I can keep learning until I croak off.

Back in high school I was aware of girls. Not sure the awareness was mutual.
 
I did leave a comment in the repo about DB vs flat files. Essentially serializing to/from JSON or XML may be easier, and SQLite, assuming your classes inherit from a base class that has the DB stuff integrated, is another option.

Thanks for the Hobbit present: I do need to learn Ruby (we use Rails at work) but so far am stuck in the world of Filemaker (basically Access for Macs). We are converting the FM stuff to Rails for a variety of reasons, and this could be a low barrier way for me to pick it up (as mentioned, Ruby, and especially Rails, has some opinions I just don't agree with, but hey, I am an old developer with old habits. And get off my lawn!)

For some reason my wife thinks city ordinance forbids placing live ordnance around the lawn perimeter. Not sure why...

In various incarnations I've used JSON, flat files, SQLite, and MongoDB. Part of the future state is to write up documentation so someone could take the code, easily change the various lists (skills by career, appearance, names) to suit their own campaign and needs. To that end I'm looking more at flatfiles and SQLite, which are currently used.

If you're a RoR shop, you have my condolences! The web app uses Sinatra, a route based web server with easy syntax. I'm also using Erb, which is still the RoR template of choice, right?
 
coliver988, I looked at some of your code. It should take you less than a week to get as good at Ruby as I am. There are some Ruby-isms to be aware of, like automatically generated getters and setters with the "attr_accessor" statement. Also, a Ruby method automatically returns the result of the last statement evaluated, absent an explicit "return" statement. So the above returns true of @upp[:soc] is > 10, false otherwise.

And yes, a method ending in "?" is valid. The convention is to use them for booleans, but they can be use however you like.
 
I can see the utility in that, you could make the dict key based on the header. Since my code is pretty raw, and others might want to add to and use it without my snake case name scheme, I'll holding off for the nonce. I do like the idea, though...
I'm using pandas now. So CSV headers are a must.
 
Mazel Tov!

Hobbits give others presents on their birthday. I'm a bit tall for a hobbit but well rounded enough to do for. Today is my birthday and I wanted to give us both a present.

Star Merchant actually runs! While it has lots of tests it is still fragile, there's very little error checking and user input is only nominally validated. So far. I wanted to prove to myself that I could take a slightly larger than my usual program and make it work.

Thanks for sharing it.

Shalom,
M.
 
I did leave a comment in the repo about DB vs flat files. Essentially serializing to/from JSON or XML may be easier, and SQLite, assuming your classes inherit from a base class that has the DB stuff integrated, is another option.

Thanks for the Hobbit present: I do need to learn Ruby (we use Rails at work) but so far am stuck in the world of Filemaker (basically Access for Macs). We are converting the FM stuff to Rails for a variety of reasons, and this could be a low barrier way for me to pick it up (as mentioned, Ruby, and especially Rails, has some opinions I just don't agree with, but hey, I am an old developer with old habits. And get off my lawn!)

coliver88, I replied to your comment on github so others could see the design process and join in the conversation. My real assumption is that folks might take the code and change it to suit their needs. Making that easier is a design goal. However, there's also the design goal of "have a project to demo for a job interview". :D So making it too simplistic can be an issue, as well.

At this point there's data in two formats; plain text with one "thing" per line, and the SQLite DB for names. That makes it very easy to add or change, and if someone wants to re-write the entire thing in Go or Python, they are welcome to. Well, I can save them some time in Go, some of it is already written.
 
Saw a DriveThru advert for an adventure seed generator or somesuch. One place it had adventures starting was in a bar, which made me think it needed people. Mangled the starship crew into a list of patrons at a bar. Still needs work, but here's a sample:

Code:
Welcome to Joe's Bar and Blowfish Emporium, a small club

Patrons:

    Rayna Forbes [ F ] 7B4288 ( 5 terms) Age: 39    Brawling-1, Computer-1, Gamble-1
    Abigail Seguin [ F ] C69665 ( 2 terms) Age: 27    Carouse-1, Survival-1
    Jade Rivero [ F ] 68888A ( 2 terms) Age: 27    Carouse-1, GunCbt-1
    Erminia Ramos [ F ] 7549BB ( 5 terms) Age: 39    Admin-2, Legal-1
    Sonny Cornelis [ M ] 879954 ( 4 terms) Age: 34    Brawling-1, Gamble-1, Stealth-1
 
Back
Top