So let's start by thinking about how the game will work. Pretty much, I want it to be command-line interactive and turn based. So you enter a command, and then something happens, and then you can enter another thing, and so on. You should be able to turn left or right and move forward and backward, and check what's in front of you. You should also be able to shoot.
I'm thinking sensible commands would be:
left
right
forward (maybe also go)
back
shoot (also pew or pewpew)
look (or check)
everything should be lower case for now. There'll be buildings randomly placed about, and when you are facing them and shoot, they should blow up. Maybe an extra command,
map
would be useful so you can see there's a building (demarcated by a B) somewhere, and a blown up building (demarcated by an X) somewhere else, and you the player, demarcated by a P. Later, I could make you be one of ^ v > < depending on your facing or something. A score for how many buildings you blown up would be neat too.
COOL!
So where do we begin? Well, if I want it to be interactive I'm going to have to have some kind of game-loop. I *could* just make this a game you play by issuing Class.command commands in irb or something, but that feels cheap. So it makes sense to me that I'd have some sort of controller class I'll call Game. I'm also going to need a Player.. or a Robot who moves around. Yeah, I like the thought of Robot being the thing that shoots. Then I'm gonna need Buildings, and a Map.
So, the Game will have a Robot, Buildings and a Map.
each Building will have a location and a status: either it exists or it doesn't!
the Robot will have a location, a direction, and maybe a name.
the Map will have to show the Robot and the Buildings, and eventually (I hope) the facing.
So let's get started already!!!
First, Iteration 1: Let's make the Game class and the main loop inside it, which will receive commands. What do we do now? That's right, we write some tests!
I'm going to lift some code pretty closely out of Ruby Best Practices here, because it does just about exactly what we want:
class GameTest < Test::Unit::TestCasenot having run this yet or ever done testing in ruby before, I have /no idea/ if this will actually work. Having written it though, I'm going to throw my Game class together (which now essentially writes itself)
def setup
@commandlist = ["left", "right", "forward",
"go", "back", "shoot", "pew",
"pewpew", "map", "look", "check"]
@input = StringIO.new
@game = Game.new(@input)
end
commandlist.each do |command|
must "set the inputted command correctly when parsing #{command}" do
provide_input(command)
Game.get_command
assert_equal Game.command, command
end
end
def provide_input(string)
@input << string
@input.rewind
end
end
class GameI don't have rake or rubygems on this computer, so I can't test this yet! I'll have to do so a little later - after a quick manual test of the Game class, it looks like it is in the right place. I realized while making it though, that I forgot to test that I'm not taking inappropriate commands! Fortunately I built it into the game class, and I'll modify the test soon to check for it.
attr_reader :command
def initialize(readin=STDIN, output=STDOUT)
@input = readin
@output = output
@command_list = ["left", "right", "go", "back",
"shoot", "check", "look", "pew",
"pewpew", "exit", "map", "forward"]
end
def get_command
temp_command = @input.gets
temp_command.chomp!
if @command_list.index(temp_command) != nil then
@command = temp_command
end
end
def loop
while @command != "exit"
get_command
puts @command
end
end
end
Also of note, my directory structure at the moment:
/ah, and what exactly is in the rakefile? I've never used rake before! But again lifting from Ruby Best Practices (a fantastic book!), I've got
/Rakefile
/src/
/src/game.rb
/test/
/test/test_game.rb
require "rake/testtask"And that's where I'll leave it for now. More later when I can actually run tests and find out all the things I've done incorrectly. :)
task :default => [:test]
Rake::TestTask.new do |test|
test.libs << "test"
test.test_files = Dir[ "test/test_*.rb" ]
test.verbose = true
end
No comments:
Post a Comment