Attempting to Learn Go
Here you can find the code I've been writing for my Attempting to Learn Go posts that I've been writing and posting over on Dev.to.
Posted on April 14, 2019
Welcome back to another post in my rogue-ish Golang series. This week is going to be a very short post which doesn't cover much of the "game" itself. It's more a bit of a brain dump as I'm trying to decide on how I want to tackle adding creatures to the game.
There are a bunch of ways to do this. I'm trying to figure out what would be most appropriate for this and not complicate the code. We don't need any real display code since we'll just write our tests out to the console. We'll need to iterate on this throughout the next several weeks until we arrive at what we're looking for. And now...
We are keeping everything very basic for this code we're not going to include tcell
or anything other than a die roller.
package main
import (
"fmt"
"math/rand"
"time"
"github.com/shindakun/die"
)
One of the things we want to be able to do is a loop through our entire set of actors. So, we have an Actors
struct which is a slice of the Actor
struct. Actor
is going to hold our basic "creature" information. That is the position (x,y), what floor they are on, and the Creature
interface.
type Actors struct {
Actors []Actor
}
type Actor struct {
X int
Y int
Floor int
Creature Creature
}
Now we can create a simple method to "create" actors. We call newActor()
and pass in where we want the actor to start on our stage and which floor. Our creature is also created and given "life" in this step. We'll see that a bit later on though...
func newActor(x, y, f int, c Creature) Actor {
return Actor{
X: x,
Y: y,
Floor: f,
Creature: c,
}
}
The creature interface declares all the methods a creature contains. We're trying it this way so each creature can have its own set of functions. We could move the methods on to Actor
if this doesn't work. Which it may not. This way leads to a bit of code duplication since we're rewriting the same methods for each creature type.
type Creature interface {
GetRune() rune
GetHealth() int
GetDescription() string
TakeDamage(int)
}
Here we have the majestic pig
struct! I've already added JSON tags since I can imagine us loading basic creature data from disk. Currently, we have a rune (p
), health (10
), and a description (I'm a pig!
). Not too exciting but it should work for now.
type Pig struct {
R rune `json:"r,omitempty"`
Health int `json:"health,omitempty"`
Description string `json:"description,omitempty"`
}
To complete our pig "creature" we need to implement the parts of our Creature
interface. The code is pretty descriptive so we won't touch on it too much.
func (p *Pig) GetRune() rune {
return p.R
}
func (p *Pig) GetHealth() int {
return p.Health
}
func (p *Pig) GetDescription() string {
return p.Description
}
func (p *Pig) TakeDamage(i int) {
p.Health = p.Health - i
}
We need to be thinking about our actors moving around the world. So, I've created a basic Move()
method which will allow our "pig" to move about. To do this we roll a four-sided die and move our pig based on the roll. 1 for North, 2 for East, 3 for South, 4 for West. We could update this at some point to allow for eight-way movement but for simplicity, we'll keep it at four for now.
Again, the code is pretty self-explanatory so we'll keep it brief. We roll for our direction and update the actor's position based on the results.
func (a *Actor) Move(floor int) {
if floor == a.Floor {
/*
1
4+2
3
*/
rand.Seed(time.Now().UTC().UnixNano())
var xx, yy int
d, err := die.Roll("1d4")
if err != nil {
panic("die roll")
}
switch d {
case 1:
xx = -1
case 2:
yy = 1
case 3:
xx = 1
case 4:
yy = -1
}
a.X = a.X + xx
a.Y = a.Y + yy
}
}
We come now to the main()
of our test. We will create our a
"Actors".
func main() {
a := &Actors{}
Then take a.Actors
and start appending "new actors" to it. We create the new actor and setup the creature all in one go. Then we just print some stuff to the screen to test.
a.Actors = append(a.Actors, newActor(1, 1, 1, &Pig{'p', 10, "From the realm of Paradox... the Pig."}))
a.Actors = append(a.Actors, newActor(2, 2, 1, &Pig{'p', 10, "Oink."}))
fmt.Printf("%#v\n\n", a)
fmt.Printf("%#v\n\n", a.Actors[0])
fmt.Printf("%#v\n\n", string(a.Actors[0].Creature.GetRune()))
fmt.Printf("%#v\n\n", a.Actors[0].Creature.GetHealth())
a.Actors[0].Creature.TakeDamage(5)
fmt.Printf("%#v\n\n", a.Actors[0].Creature.GetHealth())
fmt.Printf("%#v\n\n", a.Actors[1].Creature.GetDescription())
for i := range a.Actors {
a.Actors[i].Move(1)
}
fmt.Printf("%#v\n\n", a.Actors)
}
Seems to work alright, which is nice. If I have some time in the next day or so I'll try and work this into our code from last week to see how it goes.
You can find the code for this and most of the other Attempting to Learn Go posts in the repo on GitHub.
Here you can find the code I've been writing for my Attempting to Learn Go posts that I've been writing and posting over on Dev.to.
Enjoy this post? |
---|
How about buying me a coffee? |
Posted on April 14, 2019
Sign up to receive the latest update from our blog.