Commit a8b8e2dc authored by Boris Mühmer's avatar Boris Mühmer
Browse files

move sub-directory into sub-module



Signed-off-by: default avatarBoris Mühmer <boris@muehmer.de>
parents
Loading
Loading
Loading
Loading

main.go

0 → 100644
+106 −0
Original line number Diff line number Diff line
package main

import (
	"fmt"
	"strconv"
	"time"

	"repositories.muehmer.net/boris.muehmer/wator/wator"
)

func main() {
	// setup environment
	w := &wator.Wator{
		Debug:             false, //true,
		Width:             72,    //32,
		Height:            36,    //14,
		InitialFishes:     400,   //200,
		InitialSharks:     40,    //20,
		BreedFish:         3,
		BreedShark:        30,
		StarveShark:       2,
		SleepMilliseconds: 50 * time.Millisecond,
	}

	initialize(w)
	print(w)
	repl(w)
}

func repl(w *wator.Wator) {
	cycles := read()
	if cycles == 0 {
		return
	}
	for i := 0; i < cycles; i++ {
		if i > 0 {
			time.Sleep(w.SleepMilliseconds)
		}
		evaluate(w)
		print(w)
	}
	repl(w)
}

func initialize(w *wator.Wator) {
	if err := w.Populate(); err != nil {
		panic(err)
	}
}

func print(w *wator.Wator) {
	fmt.Printf("\033[H\033[2J") // TBD: remove this hack
	if err := w.Display(); err != nil {
		panic(err)
	}
	fmt.Printf("%s\n", w)
}

func evaluate(w *wator.Wator) {
	if err := w.Next(); err != nil {
		panic(err)
	}
}

func read() int {
	cycles := 1
	done := false
	for !done {
		fmt.Printf("Command: ")
		var s string
		n, err := fmt.Scanf("%s", &s)
		if n == 0 {
			s = "n"
			err = nil
		}
		if err != nil {
			panic(err)
		}
		if num, err := strconv.Atoi(s); (err == nil) && (num > 0) && (num <= 100000) {
			done = true
			cycles = num
		}
		if !done {
			switch s {
			case "?", "h", "help":
				usage()
			case "n", "next":
				done = true
			case "q", "quit":
				cycles = 0
				done = true
			default:
				fmt.Printf("Unknown command \"%s\"\n", s)
			}
		}
	}
	return cycles
}

func usage() {
	fmt.Println("--- Commands ---")
	fmt.Println("?, h, help: show this usage information")
	fmt.Println("n, next   : calculate next iteration")
	fmt.Println("<number>  : do <number> iterations")
	fmt.Println("q, quit   : terminate wator")
}

wator/cell.go

0 → 100644
+7 −0
Original line number Diff line number Diff line
package wator

type celler interface {
	String() string
	Age() int
	SetAge(int)
}

wator/fish.go

0 → 100644
+25 −0
Original line number Diff line number Diff line
package wator

// Fish is the representation for a fish.
type Fish struct {
	age int
}

const (
	fish = "·" // "f" // "🐟"
)

// String return the representation.
func (f *Fish) String() string {
	return fish
}

// Age returns the age of the fish.
func (f *Fish) Age() int {
	return f.age
}

// SetAge sets the age of the fish.
func (f *Fish) SetAge(a int) {
	f.age = a
}

wator/fish_test.go

0 → 100644
+25 −0
Original line number Diff line number Diff line
package wator

import "testing"

func TestFish(t *testing.T) {
	f := &Fish{}

	if f == nil {
		t.Errorf("failed to create a new fish")
	}

	if ss := f.String(); ss != fish {
		t.Errorf("f.String() = %s, expected %s", ss, fish)
	}

	if a := f.Age(); a != 0 {
		t.Errorf("f.Age() = %d, expected 0", a)
	}

	n := 42
	f.SetAge(n)
	if a := f.Age(); a != n {
		t.Errorf("f.Age() = %d, expected %d", a, n)
	}
}

wator/ocean.go

0 → 100644
+97 −0
Original line number Diff line number Diff line
package wator

import (
	"math/rand"
)

// Ocean is the container for fish and sharks.
type Ocean struct {
	cells  map[position]celler
	fishes map[position]*Fish
	sharks map[position]*Shark
}

// CreateOcean initializes a new ocean.
func createOcean() (*Ocean, error) {
	o := &Ocean{cells: make(map[position]celler)}
	o.fishes = make(map[position]*Fish)
	o.sharks = make(map[position]*Shark)
	return o, nil
}

func (o *Ocean) populateWater(w *Wator) error {
	for x := 0; x < w.Width; x++ {
		for y := 0; y < w.Height; y++ {
			p := position{x: x, y: y}
			o.cells[p] = &Water{}
		}
	}
	return nil
}

func (o *Ocean) populateFishes(w *Wator) error {
	for i := 0; i < w.InitialFishes; i++ {
		done := false
		for !done {
			x := rand.Intn(w.Width)
			y := rand.Intn(w.Height)
			p := position{x: x, y: y}
			switch o.cells[p].(type) {
			case *Water:
				a := rand.Intn(w.BreedFish)
				f := &Fish{age: a}
				o.cells[p] = f
				o.fishes[p] = f
				done = true
			}
		}
	}
	return nil
}

func (o *Ocean) populateSharks(w *Wator) error {
	for i := 0; i < w.InitialSharks; i++ {
		done := false
		for !done {
			x := rand.Intn(w.Width)
			y := rand.Intn(w.Height)
			p := position{x: x, y: y}
			switch o.cells[p].(type) {
			case *Water:
				a := rand.Intn(w.BreedShark)
				s := &Shark{age: a}
				o.cells[p] = s
				o.sharks[p] = s
				done = true
			}
		}
	}
	return nil
}

func (o *Ocean) isWater(p position) bool {
	r := false
	switch o.cells[p].(type) {
	case *Water:
		r = true
	}
	return r
}

func (o *Ocean) isFish(p position) bool {
	r := false
	switch o.cells[p].(type) {
	case *Fish:
		r = true
	}
	return r
}

func (o *Ocean) isShark(p position) bool {
	r := false
	switch o.cells[p].(type) {
	case *Shark:
		r = true
	}
	return r
}