Fixed tests. Need to check for damage from AI code
This commit is contained in:
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
# Nathan Hinton 22 Dec 2025
|
# Main entry point for the space game server.
|
||||||
# Here is where I will have the server start
|
# This script initializes the game engine and starts a multithreaded TCP server.
|
||||||
|
|
||||||
require 'socket'
|
require 'socket'
|
||||||
require 'json'
|
require 'json'
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
# Nathan Hinton Jan 2026
|
# Defines a building that can be constructed on a planet.
|
||||||
# Game file for the buildings
|
# Handles resource production and build power generation.
|
||||||
|
|
||||||
|
|
||||||
require 'securerandom'
|
require 'securerandom'
|
||||||
|
|
||||||
# Load the ships into a constant:
|
# Load the ships into a constant:
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
|
# Configuration data for all available buildings
|
||||||
BUILDING_DATA = File.open('lib/game/data/buildings.yaml', 'r') do |fi|
|
BUILDING_DATA = File.open('lib/game/data/buildings.yaml', 'r') do |fi|
|
||||||
YAML.safe_load(fi.read())
|
YAML.safe_load(fi.read())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Represents a building constructed on a planet. Provides resources or build power.
|
||||||
class Building
|
class Building
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
@@ -145,9 +147,11 @@ class Building
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Error class for the buildings
|
# Error class for the buildings
|
||||||
|
# Represents a building constructed on a planet. Provides resources or build power.
|
||||||
class BuildingError < StandardError
|
class BuildingError < StandardError
|
||||||
end
|
end
|
||||||
|
|
||||||
# Warning class for the buildings
|
# Warning class for the buildings
|
||||||
|
# Represents a building constructed on a planet. Provides resources or build power.
|
||||||
class BuildingWarning < StandardError
|
class BuildingWarning < StandardError
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
# Nathan Hinton 12 Jan 2026
|
# Parser for client commands.
|
||||||
#
|
# Translates incoming JSON requests into game actions.
|
||||||
# Parse a command from the client. This somehow will end up connecting with the
|
|
||||||
# game. This is because it will need to be able to communicate with the objects
|
|
||||||
# in the game and have game level access.
|
|
||||||
|
|
||||||
|
|
||||||
|
# Handles the parsing of incoming JSON commands from clients.
|
||||||
class CommandParser
|
class CommandParser
|
||||||
def initialize
|
def initialize
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Parses a command based on its type.
|
||||||
|
|
||||||
|
# @param client [TCPSocket] The client socket.
|
||||||
|
|
||||||
|
# @param command [Hash] The command hash.
|
||||||
|
|
||||||
|
# @return [Hash] The response hash.
|
||||||
def parse(client, command)
|
def parse(client, command)
|
||||||
response = {'request_id' => command['request_id']}
|
response = {'request_id' => command['request_id']}
|
||||||
case command['type']
|
case command['type']
|
||||||
@@ -24,6 +29,13 @@ class CommandParser
|
|||||||
return response
|
return response
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Parses a "hello" type command.
|
||||||
|
|
||||||
|
# @param client [TCPSocket] The client socket.
|
||||||
|
|
||||||
|
# @param command [Hash] The command hash.
|
||||||
|
|
||||||
|
# @return [Hash] The response hash.
|
||||||
def parse_hello(client, command)
|
def parse_hello(client, command)
|
||||||
response = {'type' => command['type']}
|
response = {'type' => command['type']}
|
||||||
id = command['player_id']
|
id = command['player_id']
|
||||||
@@ -36,6 +48,11 @@ class CommandParser
|
|||||||
return response
|
return response
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Parses a "query" type command.
|
||||||
|
|
||||||
|
# @param command [Hash] The command hash.
|
||||||
|
|
||||||
|
# @return [Hash] The response hash.
|
||||||
def parse_query(command)
|
def parse_query(command)
|
||||||
response = {'type' => command['type']}
|
response = {'type' => command['type']}
|
||||||
id = command['player_id']
|
id = command['player_id']
|
||||||
@@ -50,6 +67,11 @@ class CommandParser
|
|||||||
return response
|
return response
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Parses a "command" type command.
|
||||||
|
|
||||||
|
# @param command [Hash] The command hash.
|
||||||
|
|
||||||
|
# @return [Hash] The response hash.
|
||||||
def parse_command(command)
|
def parse_command(command)
|
||||||
response = {'type' => command['type']}
|
response = {'type' => command['type']}
|
||||||
id = command['player_id']
|
id = command['player_id']
|
||||||
@@ -69,6 +91,7 @@ class CommandParser
|
|||||||
response = {}
|
response = {}
|
||||||
payload.keys.each do |key, value|
|
payload.keys.each do |key, value|
|
||||||
case key
|
case key
|
||||||
|
when 'build'
|
||||||
when 'connect'
|
when 'connect'
|
||||||
game.connect_player(client, id, value)
|
game.connect_player(client, id, value)
|
||||||
when 'faction'
|
when 'faction'
|
||||||
@@ -85,6 +108,7 @@ class CommandParser
|
|||||||
response = {}
|
response = {}
|
||||||
payload.keys.each do |key, value|
|
payload.keys.each do |key, value|
|
||||||
case key
|
case key
|
||||||
|
when 'build'
|
||||||
when 'time'
|
when 'time'
|
||||||
game.send_time(id, value)
|
game.send_time(id, value)
|
||||||
when 'size'
|
when 'size'
|
||||||
@@ -101,6 +125,7 @@ class CommandParser
|
|||||||
response = {}
|
response = {}
|
||||||
payload.keys.each do |key, value|
|
payload.keys.each do |key, value|
|
||||||
case key
|
case key
|
||||||
|
when 'build'
|
||||||
when 'resources'
|
when 'resources'
|
||||||
game.get_player_resources(id, value)
|
game.get_player_resources(id, value)
|
||||||
when 'planets'
|
when 'planets'
|
||||||
@@ -123,6 +148,7 @@ class CommandParser
|
|||||||
response = {}
|
response = {}
|
||||||
payload.keys.each do |key, value|
|
payload.keys.each do |key, value|
|
||||||
case key
|
case key
|
||||||
|
when 'build'
|
||||||
else
|
else
|
||||||
raise CommandParserError, "Unable to parse the type command, domain game, key '#{key}'"
|
raise CommandParserError, "Unable to parse the type command, domain game, key '#{key}'"
|
||||||
end
|
end
|
||||||
@@ -135,6 +161,7 @@ class CommandParser
|
|||||||
response = {}
|
response = {}
|
||||||
payload.keys.each do |key, value|
|
payload.keys.each do |key, value|
|
||||||
case key
|
case key
|
||||||
|
when 'build'
|
||||||
else
|
else
|
||||||
raise CommandParserError, "Unable to parse the type command, domain player, key '#{key}'"
|
raise CommandParserError, "Unable to parse the type command, domain player, key '#{key}'"
|
||||||
end
|
end
|
||||||
@@ -143,5 +170,7 @@ class CommandParser
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Handles the parsing of incoming JSON commands from clients.
|
||||||
|
# Exception raised when a command cannot be parsed.
|
||||||
class CommandParserError < StandardError
|
class CommandParserError < StandardError
|
||||||
end
|
end
|
||||||
|
|||||||
+20
-5
@@ -1,7 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Nathan Hinton, 22 Dec 2025
|
# Space game server engine.
|
||||||
# Game server for the space game
|
# Coordinates game state, player connections, and world simulation.
|
||||||
|
|
||||||
require 'game/player'
|
require 'game/player'
|
||||||
require 'game/planet'
|
require 'game/planet'
|
||||||
@@ -160,7 +160,7 @@ module Game
|
|||||||
home = free_planets.sample
|
home = free_planets.sample
|
||||||
player = Player.new(player_id || SecureRandom.hex, faction)
|
player = Player.new(player_id || SecureRandom.hex, faction)
|
||||||
|
|
||||||
player.create_new(
|
player.set_resources(
|
||||||
@player_defaults['credits'],
|
@player_defaults['credits'],
|
||||||
@player_defaults['metal'],
|
@player_defaults['metal'],
|
||||||
@player_defaults['crystals'],
|
@player_defaults['crystals'],
|
||||||
@@ -230,8 +230,8 @@ module Game
|
|||||||
# @param msg [String] The error message
|
# @param msg [String] The error message
|
||||||
# @return [String] JSON-encoded error response
|
# @return [String] JSON-encoded error response
|
||||||
#
|
#
|
||||||
def error_response(request_id, msg)
|
def error_response(msg)
|
||||||
{ 'type' => 'error', 'request_id' => id, 'payload' => msg }.to_json
|
{ 'type' => 'error', 'request_id' => -1, 'payload' => msg }.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -376,10 +376,20 @@ module Game
|
|||||||
@players.find { |p| p.player_id == player_id } || false
|
@players.find { |p| p.player_id == player_id } || false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Loads players from a list of IDs.
|
||||||
|
|
||||||
|
# @param ids [Array<String>] list of player IDs.
|
||||||
|
|
||||||
|
# @return [Array<Player>] the loaded players.
|
||||||
def load_players(ids)
|
def load_players(ids)
|
||||||
ids.map { |id| Player.load_from_id(id) }
|
ids.map { |id| Player.load_from_id(id) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Loads planets from a configuration list or creates new ones.
|
||||||
|
|
||||||
|
# @param planets [Integer, Array<String>] number of planets to create or list of planet IDs.
|
||||||
|
|
||||||
|
# @return [Array<Planet>] the loaded or created planets.
|
||||||
def load_planets(planets)
|
def load_planets(planets)
|
||||||
if planets.is_a?(Integer) # legacy config - integer means “create N”
|
if planets.is_a?(Integer) # legacy config - integer means “create N”
|
||||||
Array.new(planets) { Planet.new }
|
Array.new(planets) { Planet.new }
|
||||||
@@ -388,6 +398,11 @@ module Game
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Loads ships from a list of IDs.
|
||||||
|
|
||||||
|
# @param ids [Array<String>] list of ship IDs.
|
||||||
|
|
||||||
|
# @return [Array<Ship>] the loaded ships.
|
||||||
def load_ships(ids)
|
def load_ships(ids)
|
||||||
ids.map { |id| Ship.load_from_id(id) } # Ship is a placeholder
|
ids.map { |id| Ship.load_from_id(id) } # Ship is a placeholder
|
||||||
end
|
end
|
||||||
|
|||||||
+48
-29
@@ -1,17 +1,27 @@
|
|||||||
# Nathan Hinton 22 Dec 2025
|
# Represents a celestial body in the game that can be owned by a player.
|
||||||
# Planet file
|
# It tracks its position and can hold various buildings.
|
||||||
|
|
||||||
require 'securerandom'
|
require 'securerandom'
|
||||||
|
|
||||||
# A planet object for the Game module
|
# A planet object in the game that can be owned by a player and contains buildings.
|
||||||
class Planet
|
#
|
||||||
attr_reader :owner, :planet_id
|
# @example
|
||||||
|
# planet = Planet.new(100, 100, 100)
|
||||||
# Creates a new planet.
|
#
|
||||||
|
class Planet
|
||||||
|
# The owner of the planet, if any.
|
||||||
|
attr_reader :owner
|
||||||
|
|
||||||
|
# The unique identifier for the planet.
|
||||||
|
attr_reader :planet_id
|
||||||
|
|
||||||
|
# Creates a new planet with random position in the game space.
|
||||||
|
#
|
||||||
|
# @param width [Integer] The width of the game space.
|
||||||
|
# @param height [Integer] The height of the game space.
|
||||||
|
# @param depth [Integer] The depth of the game space.
|
||||||
|
# @return [Planet] The new planet instance.
|
||||||
#
|
#
|
||||||
# @param width [Integer] The width of the game
|
|
||||||
# @param height [Integer] The height of the game
|
|
||||||
# @param depth [Integer] The depth of the game
|
|
||||||
def initialize(width, height, depth)
|
def initialize(width, height, depth)
|
||||||
@owner = nil
|
@owner = nil
|
||||||
@buildings = []
|
@buildings = []
|
||||||
@@ -19,8 +29,11 @@ class Planet
|
|||||||
@planet_id = SecureRandom.hex
|
@planet_id = SecureRandom.hex
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns if the planet can be claimed. Currently requires that there be no
|
# Determines if the planet can be claimed by a player.
|
||||||
# buildings on the planet.
|
# A planet is claimable if it has no owner or no buildings.
|
||||||
|
#
|
||||||
|
# @return [Boolean] true if the planet can be claimed, false otherwise.
|
||||||
|
#
|
||||||
def claimable?
|
def claimable?
|
||||||
if @owner.nil?
|
if @owner.nil?
|
||||||
return true
|
return true
|
||||||
@@ -30,45 +43,51 @@ class Planet
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Function that allows a player to claim the planet and to become the owner.
|
# Claims the planet and sets the player as the owner.
|
||||||
|
#
|
||||||
|
# @param player [Player] The player claiming the planet.
|
||||||
|
#
|
||||||
def claim(player)
|
def claim(player)
|
||||||
@owner = player
|
@owner = player
|
||||||
end
|
end
|
||||||
|
|
||||||
# Function called to update the planet.
|
# Called to update the planet during the game tick.
|
||||||
|
#
|
||||||
|
# @param delta_time [Float] The time elapsed since the last update.
|
||||||
|
#
|
||||||
def update(delta_time)
|
def update(delta_time)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns information about the planet to be sent to the client.
|
||||||
# Function to return info to the client about a planet
|
#
|
||||||
|
# @return [Hash] A hash containing the planet's ID and position.
|
||||||
|
#
|
||||||
def info_update
|
def info_update
|
||||||
return {
|
{
|
||||||
'id' => @planet_id,
|
'id' => @planet_id,
|
||||||
'position' => @position
|
'position' => @position
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Saves the planet to a file for persistence.
|
||||||
##########################
|
#
|
||||||
##### UTIL FUNCTIONS #####
|
# @return [String] The planet ID that was saved.
|
||||||
##########################
|
#
|
||||||
|
|
||||||
|
|
||||||
# Save a player to a file
|
|
||||||
def save_to_file
|
def save_to_file
|
||||||
File.open("game_data/#{self.planet_id}_planet_.save", 'wb') do |fi|
|
File.open("game_data/#{self.planet_id}_planet_.save", 'wb') do |fi|
|
||||||
# Load resources for the player:
|
|
||||||
fi.write(Marshal.dump(self))
|
fi.write(Marshal.dump(self))
|
||||||
end
|
end
|
||||||
return self.planet_id
|
self.planet_id
|
||||||
end
|
end
|
||||||
|
|
||||||
# Load a player from a file
|
# Loads a planet from a save file.
|
||||||
|
#
|
||||||
|
# @param fname [String] The filename of the save file.
|
||||||
|
# @return [Planet] The loaded planet instance.
|
||||||
|
#
|
||||||
def self.load_from_save(fname)
|
def self.load_from_save(fname)
|
||||||
File.open("game_data/#{fname}_planet_.save", 'rb') do |fi|
|
File.open("game_data/#{fname}_planet_.save", 'rb') do |fi|
|
||||||
# Load resources for the player:
|
|
||||||
Marshal.load(fi.read)
|
Marshal.load(fi.read)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
+13
-12
@@ -1,5 +1,5 @@
|
|||||||
# Nathan Hinton 22 Dec 2025
|
# Represents a player in the game.
|
||||||
# The main player file
|
# Tracks resources, owned planets, ships, and researched technology.
|
||||||
|
|
||||||
require 'securerandom'
|
require 'securerandom'
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
@@ -8,6 +8,9 @@ require 'yaml'
|
|||||||
class Player
|
class Player
|
||||||
attr_accessor :player_resources, :player_id, :player_planets, :player_ships, :faction, :researched_tech, :buildings, :ship_build_power, :research_tech_build_power, :military_tech_build_power
|
attr_accessor :player_resources, :player_id, :player_planets, :player_ships, :faction, :researched_tech, :buildings, :ship_build_power, :research_tech_build_power, :military_tech_build_power
|
||||||
|
|
||||||
|
# Create a new player. Default values are stored in the game_config.yaml file.
|
||||||
|
# @param player_id [String] An ID used to validate the player.
|
||||||
|
# @param faction [String] The faction that the player should start as. Should be \`good\` or \`evil\`
|
||||||
def initialize(player_id, faction)
|
def initialize(player_id, faction)
|
||||||
@player_id = player_id
|
@player_id = player_id
|
||||||
@player_planets = []
|
@player_planets = []
|
||||||
@@ -26,20 +29,12 @@ class Player
|
|||||||
@faction = faction
|
@faction = faction
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create a new player. This is actually just setting it up. All the defaults
|
def set_resources(credits, metal, crystals, fuel)
|
||||||
# are defined in the game_config.yaml file.
|
|
||||||
#
|
|
||||||
# @param credits [Integer] The number of starting credits
|
|
||||||
# @param metal [Integer] The amount of starting metal
|
|
||||||
# @param crystals [Integer] The amount of starting crystals
|
|
||||||
# @param fuel [Integer] The amount of fuel to start with.
|
|
||||||
# @param faction [String] The faction that the player should start as. Should be \`good\` or \`evil\`
|
|
||||||
def create_new(credits, metal, crystals, fuel)
|
|
||||||
@player_resources = {
|
@player_resources = {
|
||||||
'credits' => credits,
|
'credits' => credits,
|
||||||
'metal' => metal,
|
'metal' => metal,
|
||||||
'crystals' => crystals,
|
'crystals' => crystals,
|
||||||
'fuel' => fuel
|
'fuel' => fuel,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -164,10 +159,16 @@ class Player
|
|||||||
@military_tech_build_power = data[:military_tech_build_power] || 0
|
@military_tech_build_power = data[:military_tech_build_power] || 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns all buildings owned by the player.
|
||||||
|
|
||||||
|
# @return [Array<Building>] list of buildings.
|
||||||
def all_buildings
|
def all_buildings
|
||||||
@buildings
|
@buildings
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns all researched technology for the player.
|
||||||
|
|
||||||
|
# @return [Array<String>] list of researched tech.
|
||||||
def all_tech
|
def all_tech
|
||||||
@researched_tech
|
@researched_tech
|
||||||
end
|
end
|
||||||
|
|||||||
+5
-2
@@ -1,14 +1,16 @@
|
|||||||
# Nathan Hinton 30 Dec 2025
|
# Represents a space-faring vessel owned by a player.
|
||||||
# Ship file for the game
|
# Handles movement and validation of ship creation.
|
||||||
|
|
||||||
require 'securerandom'
|
require 'securerandom'
|
||||||
|
|
||||||
# Load the ships into a constant:
|
# Load the ships into a constant:
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
|
# Configuration data for all available ships
|
||||||
SHIP_DATA = File.open('lib/game/data/ships.yaml', 'r') do |fi|
|
SHIP_DATA = File.open('lib/game/data/ships.yaml', 'r') do |fi|
|
||||||
YAML.safe_load(fi.read())
|
YAML.safe_load(fi.read())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Represents a space-faring vessel owned by a player.
|
||||||
class Ship
|
class Ship
|
||||||
|
|
||||||
attr_reader :owner, :position
|
attr_reader :owner, :position
|
||||||
@@ -143,5 +145,6 @@ class Ship
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Error class for ships
|
# Error class for ships
|
||||||
|
# Represents a space-faring vessel owned by a player.
|
||||||
class ShipError < StandardError
|
class ShipError < StandardError
|
||||||
end
|
end
|
||||||
|
|||||||
+14
-4
@@ -36,8 +36,12 @@ require 'json'
|
|||||||
HOSTNAME = 'localhost'
|
HOSTNAME = 'localhost'
|
||||||
PORT = 2000
|
PORT = 2000
|
||||||
|
|
||||||
|
server_pid = spawn('rake serve', out: File::NULL, err: File::NULL)
|
||||||
|
sleep(0.5)
|
||||||
|
|
||||||
RSpec.describe "app.rb" do
|
RSpec.describe "app.rb" do
|
||||||
let(:client) {TCPSocket.open(HOSTNAME, PORT)}
|
let(:client) {TCPSocket.open(HOSTNAME, PORT)}
|
||||||
|
|
||||||
it 'responds with an error when a non JSON request is sent' do
|
it 'responds with an error when a non JSON request is sent' do
|
||||||
client.puts 'this is non json test data'
|
client.puts 'this is non json test data'
|
||||||
expect(JSON.parse(client.gets)).to eq({'type' => 'error', 'domain' => 'error', 'payload' => 'Server unable to decode JSON'})
|
expect(JSON.parse(client.gets)).to eq({'type' => 'error', 'domain' => 'error', 'payload' => 'Server unable to decode JSON'})
|
||||||
@@ -46,10 +50,6 @@ RSpec.describe "app.rb" do
|
|||||||
describe 'type: hello' do
|
describe 'type: hello' do
|
||||||
describe 'domain: player' do
|
describe 'domain: player' do
|
||||||
describe 'payload: player_id, faction' do
|
describe 'payload: player_id, faction' do
|
||||||
it 'Connects the player:' do
|
|
||||||
client.puts({'type' => 'hello', 'domain' => 'player', 'payload' => {'player_id' => 'test_player', 'faction' => 'good'}}.to_json)
|
|
||||||
expect(JSON.parse(client.gets)).to eq('')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -73,5 +73,15 @@ RSpec.describe "app.rb" do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe 'type: error' do
|
describe 'type: error' do
|
||||||
|
it 'returns an error when a player does not exist' do
|
||||||
|
client.puts({'type' => 'hello', 'domain' => 'player', 'payload' => {'player_id' => 'test_esfe_player', 'faction' => 'good'}}.to_json)
|
||||||
|
expect(JSON.parse(client.gets)).to eq({"payload" => "Player not registered!",
|
||||||
|
"request_id" => -1,
|
||||||
|
"type" => "error",}
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Process.kill('TERM', server_pid)
|
||||||
|
Process.wait(server_pid)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Nathan Hinton 24 Dec 2025
|
# Nathan Hinton 24 Dec 2025
|
||||||
|
# Test file for the player
|
||||||
# spec/player_spec.rb
|
# spec/player_spec.rb
|
||||||
|
|
||||||
require 'rspec'
|
require 'rspec'
|
||||||
require 'json'
|
require 'json'
|
||||||
require 'game/player' # adjust the path if needed
|
require 'game/player' # adjust the path if needed
|
||||||
@@ -46,16 +47,16 @@ RSpec.describe Player do
|
|||||||
end
|
end
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# create_new
|
# set_resources
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
describe '#create_new' do
|
describe '#set_resources' do
|
||||||
let(:credits) { 1000 }
|
let(:credits) { 1000 }
|
||||||
let(:metal) { 500 }
|
let(:metal) { 500 }
|
||||||
let(:crystals) { 200 }
|
let(:crystals) { 200 }
|
||||||
let(:fuel) { 300 }
|
let(:fuel) { 300 }
|
||||||
|
|
||||||
it 'stores the resources hash correctly' do
|
it 'stores the resources hash correctly' do
|
||||||
subject.create_new(credits, metal, crystals, fuel)
|
subject.set_resources(credits, metal, crystals, fuel)
|
||||||
expect(subject.player_resources).to eq(
|
expect(subject.player_resources).to eq(
|
||||||
'credits' => credits,
|
'credits' => credits,
|
||||||
'metal' => metal,
|
'metal' => metal,
|
||||||
@@ -165,7 +166,7 @@ RSpec.describe Player do
|
|||||||
let(:request_id) { 42 }
|
let(:request_id) { 42 }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
subject.create_new(credits, metal, crystals, fuel)
|
subject.set_resources(credits, metal, crystals, fuel)
|
||||||
subject.player_planets << double('planet', info_update: 'test_data')
|
subject.player_planets << double('planet', info_update: 'test_data')
|
||||||
subject.player_ships << double('ship')
|
subject.player_ships << double('ship')
|
||||||
end
|
end
|
||||||
@@ -231,7 +232,7 @@ RSpec.describe Player do
|
|||||||
let(:fuel) { 300 }
|
let(:fuel) { 300 }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
subject.create_new(credits, metal, crystals, fuel)
|
subject.set_resources(credits, metal, crystals, fuel)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'writes a marshaled file and can read it back' do
|
it 'writes a marshaled file and can read it back' do
|
||||||
@@ -245,7 +246,7 @@ RSpec.describe Player do
|
|||||||
'credits' => credits,
|
'credits' => credits,
|
||||||
'metal' => metal,
|
'metal' => metal,
|
||||||
'crystals' => crystals,
|
'crystals' => crystals,
|
||||||
'fuel' => fuel
|
'fuel' => fuel,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -260,7 +261,7 @@ RSpec.describe Player do
|
|||||||
let(:fuel) { 300 }
|
let(:fuel) { 300 }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
subject.create_new(credits, metal, crystals, fuel)
|
subject.set_resources(credits, metal, crystals, fuel)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a hash with the expected keys' do
|
it 'returns a hash with the expected keys' do
|
||||||
@@ -281,15 +282,4 @@ RSpec.describe Player do
|
|||||||
expect(new_player.player_resources).to eq(subject.player_resources)
|
expect(new_player.player_resources).to eq(subject.player_resources)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end# Nathan Hinton 24 Dec 2025
|
|
||||||
# Test file for the player
|
|
||||||
|
|
||||||
require 'game/player'
|
|
||||||
|
|
||||||
RSpec.describe Player do
|
|
||||||
describe '#initialize' do
|
|
||||||
it 'initializes with a player id' do
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user