Working hard, decided that we need to commit to Git
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
**/doc
|
||||
**/.byebug*
|
||||
**/.yard*
|
||||
@@ -0,0 +1,98 @@
|
||||
# Goals:
|
||||
|
||||
|
||||
Make a multiplayer game that will run in the browser. This game should be a
|
||||
planet conquest type game where you can create a lobby and then players can
|
||||
join. Once you start a game only those players can play. This game should be
|
||||
time based. You will start with a system of planets and then over time you will
|
||||
gain ships and resources. The goal is to either eliminate all of the other
|
||||
players or to control a portion of the universe. As you explore you can
|
||||
encounter other planets and players. Each planet will have specific
|
||||
bonuses. Some can produce ships faster, others will produce more resources and
|
||||
in others you can find bonuses for different kinds of ships. I want to make it
|
||||
so that you can also upgrade the planets to improve the value of them.
|
||||
|
||||
The maximum player count in a game will be 20 however I want this to be scalable.
|
||||
|
||||
# Thoughts:
|
||||
|
||||
|
||||
I do not want the players to directly communicate with each other. I want each
|
||||
one to talk to the server and then the server to use an API for getting updates
|
||||
for each player and their stuff. This means that potentially there could be
|
||||
multiple clients for the game however I want to start with a web based client
|
||||
as I feel that is easiest for me.
|
||||
|
||||
Each player should be able to log in and then see what games they are playing
|
||||
in and select a game to resume. The game will continue even when the player is
|
||||
not logged in. This means that the player could be attacked even when they are
|
||||
gone. This means that the worlds need to be persistent.
|
||||
|
||||
As a follow up that means that each world will be always running. This means
|
||||
that if there is a main loop for the game it should be very lightweight so that
|
||||
it does not consume massive amounts of resources.
|
||||
|
||||
I think that each universe should be randomly generated that way the players
|
||||
have to explore it.
|
||||
|
||||
I do eventually want to have AI players however for now I just want human
|
||||
players. Make sure that you help me to keep this easy as I am programming.
|
||||
|
||||
Here are the resources that I am thinking of for now:
|
||||
- Food
|
||||
- Metal
|
||||
- Fuel/energy
|
||||
|
||||
How do we have resources travel be twee planets? I am not sure yet. Maybe have
|
||||
another type of ship called a transport that can transport resources. This
|
||||
should be automated though so that needed resources are transported
|
||||
auto-magically.
|
||||
|
||||
I also want there to be some form of tech tree that the player can choose and
|
||||
can research. Maybe add some rare resources.
|
||||
|
||||
# Vocab:
|
||||
|
||||
|
||||
- Ship: a space ship. There are several different types:
|
||||
- Explorer: Has a high vision range and can see far. It can not however
|
||||
attack or defend
|
||||
- Fighter: This is a ship that can fight other ships. It will also have sub
|
||||
classes as well
|
||||
- Colonizer: This ship is used to colonize a planet and is defenseless while
|
||||
flying. However when a planet is colonized the ship can be used to defend
|
||||
the planet
|
||||
- Universe: The entire game space. It contains planets and other objects
|
||||
- Planet: A planet that can be colonized/owned by a player. It can produce
|
||||
resources and ships
|
||||
- Planet Defense: Structures that can be built on a planet that will defend it
|
||||
from attack.
|
||||
|
||||
|
||||
# Final thoughts:
|
||||
|
||||
|
||||
I am comfortable with Python and Ruby mostly. I would rather separate the game
|
||||
into the server stuff which will be API driven. I have done some Ruby on Rails
|
||||
however I am not very good at it. This means that I would prefer if we used
|
||||
rails for it to be purely an API.
|
||||
|
||||
I also am very inexperienced at authentication. I think for now I will just
|
||||
have player names. Anyone can use any name. This does mean however that if two
|
||||
people use the same name they will be indistinguishable in the server. Probably
|
||||
just taking a password and hashing it on the client and then using that hash as
|
||||
a 'token' of sorts would fix this. I am not super concerned with player account
|
||||
security however the server does need to be secure.
|
||||
|
||||
# API overview:
|
||||
|
||||
|
||||
The `Universe` class will contain everything in the universe. This means planets, ships, and other stelar objects. This will be the API that I can think of:
|
||||
|
||||
- universe/
|
||||
- ships/
|
||||
- create/
|
||||
- update/
|
||||
- move/
|
||||
- planets/
|
||||
- update/
|
||||
@@ -0,0 +1,27 @@
|
||||
# Nathan Hinton 2 Oct 2025
|
||||
# Rake file
|
||||
|
||||
|
||||
desc 'Run RSpec tests'
|
||||
task :test do
|
||||
begin
|
||||
require 'rspec/core/rake_task'
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
ENV['RUN_ALL_TESTS'] = 'true'
|
||||
Rake::Task['spec'].invoke
|
||||
rescue LoadError
|
||||
puts 'Failed to load RSpec to run tests... Try installing rspec'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
desc 'Run the server for clients to connect to'
|
||||
task :serve do
|
||||
raise NotImplementedError.new('Server task not yet implimented!')
|
||||
end
|
||||
|
||||
|
||||
desc 'Create the YARD documentation for the project'
|
||||
task :doc do
|
||||
res = sh 'yard doc *.rb'
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
# Nathan Hinton 1 Oct 2025
|
||||
|
||||
|
||||
# Mostly for testing right now:
|
||||
require './universe'
|
||||
|
||||
universe = Universe.new('test universe')
|
||||
universe.print_universe(simple: true)
|
||||
@@ -0,0 +1,36 @@
|
||||
# Nathan Hinton 2 Oct 2025
|
||||
|
||||
|
||||
# A helper class for storing and converting universe point formats:
|
||||
class Position
|
||||
attr_reader :x_pos, :y_pos, :a, :b, :c
|
||||
def initialize(*args)
|
||||
if args.length == 2
|
||||
# initialize with x, y position:
|
||||
if args.sum.odd?
|
||||
raise ArgumentError.new('A position created in (x, y) must sum to an even number!')
|
||||
end
|
||||
x_pos = args[0]
|
||||
y_pos = args[1]
|
||||
elsif args.length == 3
|
||||
# initialize with a, b, c position
|
||||
raise NotImplementedError.new('(a, b, c) positioning not implimented!')
|
||||
else
|
||||
raise ArgumentError.new('Creation of a position requires two or three integer args for a position.')
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the corrdinates in the 2d plane in a 3 axis notation.
|
||||
#
|
||||
# @return [Array<Integer>] The (a, b, c) position
|
||||
def two_d_hexagonal
|
||||
return [a, b, c]
|
||||
end
|
||||
|
||||
# Returns the coordinates in the 2d plane
|
||||
#
|
||||
# @return [Array<Integer>] The (x, y) position
|
||||
def two_d_cartesian
|
||||
return [x_pos, y_pos]
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1 @@
|
||||
# Nathan Hinton 2 Oct 2025
|
||||
@@ -0,0 +1,15 @@
|
||||
# Nathan Hinton 1 Oct 2025
|
||||
|
||||
PLANET_PRODUCTION_RESOURCES = [:ships]
|
||||
|
||||
# This class holds information about a planet.
|
||||
class Planet
|
||||
attr_reader :owner
|
||||
# Create a planet
|
||||
def initialize(random)
|
||||
@random = random
|
||||
@prod_rate = @random.rand
|
||||
@resource = PLANET_PRODUCTION_RESOURCES[(@random.rand * PLANET_PRODUCTION_RESOURCES.length).floor]
|
||||
@owner = nil
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
# Nathan Hinton 2 Oct 2025
|
||||
|
||||
|
||||
# This class will be the container for ships. For now they are all the same
|
||||
class Ship
|
||||
def initialize(x_pos, y_pos)
|
||||
@position = [x_pos, y_pos]
|
||||
@speed = 0.1
|
||||
end
|
||||
|
||||
# Called every game tick
|
||||
def tick
|
||||
if @moving != [0, 0]
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# Move function. This will move a ship. For now you can only move one hop,
|
||||
# there is no way to move more than one at the moment. This position should
|
||||
# be only *one* spot away from where we are.
|
||||
#
|
||||
# @param x_pos [Integer] The target x position
|
||||
# @param y_pos [Integer] The target y position
|
||||
def move(x_pos, y_pos)
|
||||
#Validate coordinates:
|
||||
if (x_pos + y_pos).odd?
|
||||
raise ArgumentError.new('The x, y coordinate for movement must add to be even!')
|
||||
end
|
||||
|
||||
# Ensure we are not too far:
|
||||
if ((x_pos + y_pos) - @position.sum).abs != 2
|
||||
raise ArgumentError.new('The x, y coordinates for moevement must be to an adjcent space!')
|
||||
end
|
||||
|
||||
end # Function move
|
||||
|
||||
# Move_direction. Takes a direction and then sets the moving variable equal that direction.
|
||||
#
|
||||
# @param direction [Integer] A value between (0, 5) that determines the direction (think unit circle)
|
||||
def move_direction(direction)
|
||||
if (direction < 0 || direction > 5)
|
||||
raise ArgumentError.new('When moving using direction based movement, x must be between (0..5)!')
|
||||
end
|
||||
# This means that the direction can range from 0 to 5 (think of unit circle)
|
||||
case direction
|
||||
when 0
|
||||
@moving = [2, 0] # Right
|
||||
when 1
|
||||
@moving = [1, 1] # Right up
|
||||
when 2
|
||||
@moving = [-1, 1] # Left up
|
||||
when 3
|
||||
@moving = [-2, 0] # Left
|
||||
when 4
|
||||
@moving = [-1, -1] # Left down
|
||||
when 5
|
||||
@moving = [1, -1] # Right down
|
||||
end
|
||||
end # Function move_direction
|
||||
end
|
||||
@@ -0,0 +1,95 @@
|
||||
# Nathan Hinton 2 Oct 2025
|
||||
|
||||
# Test file for the ship object
|
||||
|
||||
require './ship'
|
||||
|
||||
RSpec.describe Ship do
|
||||
let(:initial_x) { 0 }
|
||||
let(:initial_y) { 0 }
|
||||
subject(:ship) { Ship.new(initial_x, initial_y) }
|
||||
|
||||
describe '#initialize' do
|
||||
it 'stores the given position' do
|
||||
expect(ship.instance_variable_get(:@position)).to eq([initial_x, initial_y])
|
||||
end
|
||||
|
||||
it 'sets the speed to 0.1' do
|
||||
expect(ship.instance_variable_get(:@speed)).to eq(0.1)
|
||||
end
|
||||
|
||||
it 'does not set @moving until a direction is chosen' do
|
||||
expect(ship.instance_variable_get(:@moving)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#tick' do
|
||||
it 'does nothing (but does not raise an exception)' do
|
||||
expect { ship.tick }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe '#move' do
|
||||
context 'when coordinates are valid' do
|
||||
it 'accepts adjacent moves whose sum is even' do
|
||||
# adjacent positions that satisfy the rules
|
||||
expect { ship.move(1, 1) }.not_to raise_error # sum = 2
|
||||
expect { ship.move(2, 0) }.not_to raise_error # sum = 2
|
||||
expect { ship.move(0, 2) }.not_to raise_error # sum = 2
|
||||
expect { ship.move(-1, -1) }.not_to raise_error # sum = -2
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the x + y sum is odd' do
|
||||
it 'raises an ArgumentError' do
|
||||
expect { ship.move(0, 1) }.to raise_error(
|
||||
ArgumentError,
|
||||
/must add to be even/
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the target is not adjacent' do
|
||||
it 'raises an ArgumentError' do
|
||||
# distance > 1: difference of sums != 2
|
||||
expect { ship.move(3, 3) }.to raise_error(
|
||||
ArgumentError,
|
||||
/must be to an adjcent space/
|
||||
)
|
||||
expect { ship.move(0, 0) }.to raise_error(
|
||||
ArgumentError,
|
||||
/must be to an adjcent space/
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#move_direction' do
|
||||
it 'accepts direction values between 0 and 5' do
|
||||
(0..5).each do |direction|
|
||||
expect { ship.move_direction(direction) }.not_to raise_error
|
||||
# verify the @moving vector matches the spec
|
||||
expected = case direction
|
||||
when 0 then [2, 0]
|
||||
when 1 then [1, 1]
|
||||
when 2 then [-1, 1]
|
||||
when 3 then [-2, 0]
|
||||
when 4 then [-1, -1]
|
||||
when 5 then [1, -1]
|
||||
end
|
||||
expect(ship.instance_variable_get(:@moving)).to eq(expected)
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises an ArgumentError for invalid directions' do
|
||||
expect { ship.move_direction(-1) }.to raise_error(
|
||||
ArgumentError,
|
||||
/must be between \(0..5\)/
|
||||
)
|
||||
expect { ship.move_direction(6) }.to raise_error(
|
||||
ArgumentError,
|
||||
/must be between \(0..5\)/
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,284 @@
|
||||
# Nathan Hinton 1 Oct 2025
|
||||
|
||||
|
||||
require './planet'
|
||||
|
||||
# Universe class. Holds a universe and provides the api for it. Universes are
|
||||
# created on a 2d grid. I would like it to be hexagonal movement type so that
|
||||
# it feels less like a grid and more like a circle. This means that we will
|
||||
# have some interesting point systems. For now I am thinking that we will have
|
||||
# three directions, a, b, c which will corespond to moving along one of the
|
||||
# lines to another system. Here is an ascii art:
|
||||
#
|
||||
#
|
||||
# (0, 0, 1) (0, 1, 0)
|
||||
# \ /
|
||||
# \ /
|
||||
# \ /
|
||||
# (+c) (+b)
|
||||
# \ /
|
||||
# \ /
|
||||
# \ /
|
||||
# (-1, 0, 0) <--- (-a) --- (0, 0, 0) --- (+a) ---> (1, 0, 0)
|
||||
# / \
|
||||
# / \
|
||||
# /
|
||||
# (-b) (-c)
|
||||
# / \
|
||||
# / \
|
||||
# / \
|
||||
# (0, -1, 0) (0, 0, -1)
|
||||
#
|
||||
#
|
||||
# This means that we are adding vector together. I do not think that this will
|
||||
# work super well though with a system that is other than 2D. I think that will
|
||||
# be fine.
|
||||
#
|
||||
# After thinking some more I will have the universe class hold everything in
|
||||
# the universe. It will be in charge of holding all of the ships and
|
||||
# planets. Then the Player class will be connected to the ships and planets
|
||||
# that they own/control
|
||||
#
|
||||
# @param name [String] The name of the game
|
||||
# @param universe_size [Integer] Controlls the size of the generated universe. This is a radius from the center point.
|
||||
class Universe
|
||||
def initialize(name, universe_size: 4, create_chances: {planet: 1}, seed: nil, verbose: true, debug: false)
|
||||
@name = name
|
||||
@universe_size = universe_size
|
||||
@create_chances = create_chances
|
||||
@verbose = verbose
|
||||
@debug = debug
|
||||
|
||||
# Setup internal lists:
|
||||
@player_list = []
|
||||
@ship_list = []
|
||||
|
||||
# initizlize RNG
|
||||
if seed.nil?
|
||||
@random = Random.new()
|
||||
@seed = @random.seed
|
||||
else
|
||||
@seed = seed
|
||||
@random = Random.new(@seed)
|
||||
end
|
||||
|
||||
# Set center of universe
|
||||
@center = Position.new([@universe_size + 2, @universe_size ])
|
||||
|
||||
puts "Generating Universe '#{@name}' with seed #{@seed}" if @verbose
|
||||
puts "Center is #{@center}"
|
||||
@universe_map = []
|
||||
# Generate the universe. First generate the x values:
|
||||
(0 .. (@universe_size * 2)).each do |y_pos|
|
||||
@universe_map[y_pos] = []
|
||||
(0 .. (@universe_size * 2 + 2)).each do |x_pos|
|
||||
# Make the grid work right, x is actually skipping every other.
|
||||
x_pos *= 2
|
||||
x_pos += 1 if y_pos.odd?
|
||||
position = Position.new([x_pos, y_pos])
|
||||
|
||||
# Skip if the node is too far
|
||||
if distance(@center, position) >= @universe_size
|
||||
next
|
||||
end
|
||||
|
||||
# Get what the planet should be:
|
||||
spot = nil
|
||||
if @random.rand < @create_chances[:planet]
|
||||
spot = Planet.new(@random)
|
||||
end
|
||||
puts "Creating something at (#{position.x_pos} #{position.y_pos})" if @debug
|
||||
@universe_map[position.y_pos][position.x_pos] = spot
|
||||
end # Create y points
|
||||
end # Create x points
|
||||
end # Function initialize
|
||||
|
||||
# Returns the distance between points. This is returned as a number which
|
||||
# indicates how far you have to go to get to a point. This is actually
|
||||
# supurisingly hard...
|
||||
#
|
||||
# @param position_a [Position] A start point in the universe
|
||||
# @param position_b [Position] Another point in the universe
|
||||
# @return [Integer] The distance between points in the universe.
|
||||
def distance(position_a, position_b)
|
||||
result = 0 # We can just add the abs diff of each direction.
|
||||
dist_x = (position_b.x_pos - position_a.x_pos).abs
|
||||
dist_y = (position_b.y_pos - position_a.y_pos).abs
|
||||
|
||||
# Sanity check, our coordinates should add to be even:
|
||||
if (dist_x + dist_y).odd?
|
||||
raise RangeError.new('When calculating the distance we calculated a non even number. This is not allowed!')
|
||||
end
|
||||
|
||||
res = (dist_x / 2) + dist_y
|
||||
if dist_x >= dist_y
|
||||
res = (dist_x + dist_y) / 2
|
||||
end
|
||||
puts "Distance: #{point_a} is #{point_b} #{res} units away" if @debug
|
||||
return res
|
||||
end # Function distance
|
||||
|
||||
# Prints the universe to the screen.
|
||||
def print_universe(simple: false)
|
||||
(0 .. (@universe_size * 2)).each do |y_pos|
|
||||
# Print empty space before chart (for angles)
|
||||
nextline = ''
|
||||
if y_pos < @universe_size
|
||||
nextline += ' ' * ((@universe_size - y_pos).abs - 1)
|
||||
else
|
||||
nextline += ' ' * ((@universe_size - y_pos).abs)
|
||||
end
|
||||
|
||||
# Print more empty space for the odd places (provides offset)
|
||||
if y_pos.odd?
|
||||
print ' '
|
||||
end
|
||||
|
||||
#Actually loop through everything
|
||||
(0 .. (@universe_size * 2)).each do |x_pos|
|
||||
# Make the grid work right, x is actually skipping every other.
|
||||
x_pos *= 2
|
||||
x_pos += 1 if y_pos.odd?
|
||||
|
||||
# Print empty space if we are outside the universe (For items)
|
||||
if distance(@center, [x_pos, y_pos]) >= @universe_size
|
||||
print ' '
|
||||
next
|
||||
end
|
||||
|
||||
# Print what we are:
|
||||
position = @universe_map[y_pos][x_pos]
|
||||
nextline += ' '
|
||||
if [x_pos, y_pos] == @center
|
||||
print 'O'
|
||||
elsif position.class == Planet
|
||||
print 'P'
|
||||
else
|
||||
print ' '
|
||||
end
|
||||
|
||||
# Calculate what we should print on the next line and if we should print dashes
|
||||
if y_pos < @universe_size
|
||||
nextline += '/ \\'
|
||||
end
|
||||
if distance(@center, [x_pos + 2, y_pos]) < @universe_size
|
||||
print '---'
|
||||
if y_pos >= @universe_size
|
||||
nextline += '\\ /'
|
||||
end
|
||||
end
|
||||
end # For each col in row
|
||||
puts ''
|
||||
if (y_pos + 1) / 2 < @universe_size && !simple
|
||||
puts nextline
|
||||
end
|
||||
end # For each row
|
||||
end # Function print_universe
|
||||
|
||||
##################################################
|
||||
################### UNIVERSE #####################
|
||||
##################################################
|
||||
|
||||
# This is where API stuff for the universe should go
|
||||
|
||||
# Gets a position from the universe for a player. Eventually this will take
|
||||
# into account that the player can not actually see the whole universe
|
||||
#
|
||||
# @param player [Player] The player who is asking for the position
|
||||
# @param position [Position] The position that is being requested
|
||||
def get_position(player, position)
|
||||
|
||||
end
|
||||
|
||||
# Sets a position as explored for a player. This should be called as ships
|
||||
# move around and explore the universe.
|
||||
#
|
||||
# @param player [Player] The player who should be set
|
||||
# @param position [Position] The position that is being modified
|
||||
def explore_position(player, position)
|
||||
end
|
||||
|
||||
|
||||
##################################################
|
||||
##################### SHIPS ######################
|
||||
##################################################
|
||||
|
||||
# Create a ship in the universe. This ship is registered to a specific player
|
||||
#
|
||||
# @param player [Player] The player who owns the ship
|
||||
# @param position [Position] The position that the ship should be created at
|
||||
def create_ship(player, position)
|
||||
end
|
||||
|
||||
# Move a player's ship to a given position
|
||||
#
|
||||
# @param player [Player] The player whose ship should be moved
|
||||
# @param ship [Ship] The ship that should be moved
|
||||
# @param position [Position] The position the ship should be moved to.
|
||||
def move_ship(player, ship, position)
|
||||
end
|
||||
|
||||
|
||||
##################################################
|
||||
##################### PLANETS ####################
|
||||
##################################################
|
||||
|
||||
# As all planets are created when the galaxy is generated there are no create
|
||||
# planet functions. It is possible that we want to remove them though
|
||||
|
||||
# Remove a planet from the universe
|
||||
#
|
||||
# @param planet [Planet] The planet that should be removed
|
||||
# @param position [Position] The position that it should be removed from
|
||||
def remove_planet(planet, position)
|
||||
end
|
||||
|
||||
##################################################
|
||||
##################### PLAYER #####################
|
||||
##################################################
|
||||
|
||||
# Add a player to the player list in the universe
|
||||
#
|
||||
# @param player [Player] The player who should be added to the universe
|
||||
def add_player(player)
|
||||
@player_list.push(player)
|
||||
return 'Added player to universe'
|
||||
end
|
||||
|
||||
# Remove a player from the list in this universe
|
||||
#
|
||||
# @param player [Player] The player that should be removed from the player list.
|
||||
def remove_player(player)
|
||||
if @player_list.delete(player).nil?
|
||||
return 'Failed to remove player! Does not exist in this universe!'
|
||||
end
|
||||
return 'Removed player from universe'
|
||||
end
|
||||
|
||||
# Returns a list of ships owned by the player
|
||||
#
|
||||
# @param player [Player] The player who wants to get their ships.
|
||||
def get_player_ships(player)
|
||||
result = []
|
||||
@ship_list.each do |ship|
|
||||
if ship.owner == player
|
||||
result.push(ship)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end # Function get_player_ships
|
||||
|
||||
# Returns a list of planets owned by the player
|
||||
#
|
||||
# @param player [Player] The player who wants to get their planets.
|
||||
def get_player_planets(player)
|
||||
result = []
|
||||
@planet_list.each do |planet|
|
||||
if planet.owner == player
|
||||
result.push(planet)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
end # Class Universe
|
||||
@@ -0,0 +1,32 @@
|
||||
# Nathan Hinton 1 Oct 2025
|
||||
# Create a custom hash class for the universe.
|
||||
|
||||
|
||||
# This will contain the universe hash inside it. It will allow for array type
|
||||
# indexing as well as point type indexing
|
||||
class UniverseHash
|
||||
def initialize()
|
||||
@universe_hash = {}
|
||||
end
|
||||
|
||||
# Setter for values in the hash
|
||||
def =[](key, value)
|
||||
if key.class == Array
|
||||
@universe_hash[key[0]] = {} if @universe_hash[key[0]].nil?
|
||||
@universe_hash[key[0]][key[1]] = {} if @universe_hash[key[0]][key[1]].nil?
|
||||
@universe_hash[key[0]][key[1]][key[2]] = value
|
||||
else
|
||||
raise NotImplementedError.new('You can only set based on point values.')
|
||||
end
|
||||
end
|
||||
|
||||
def [](key)
|
||||
if key.class == Array
|
||||
return @universe_hash[key[0]][key[1]][key[2]]
|
||||
elsif key.class == Integer
|
||||
return @universe_hash[key]
|
||||
else
|
||||
raise NotImplementedError
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user