Too much crap for one commit

Breaking out console runner into its own file, adding an empty web
runner, and starting to test that games and game states are able to
represent themselves as images.
This commit is contained in:
Dan Buch 2012-12-16 17:59:54 -05:00
parent 3bfa23fff2
commit 3e013ce1a5
6 changed files with 114 additions and 46 deletions

47
conway/console.go Normal file
View File

@ -0,0 +1,47 @@
package conway
import (
"fmt"
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
func RunConsoleGame(height, width, sleepMs int, mutate bool) (int, error) {
sleepInterval := time.Duration(sleepMs * 1000 * 1000)
game := NewGameOfLife(height, width)
err := game.ImportRandomState()
if err != nil {
return 2, err
}
genTicks, err := game.Generations()
if err != nil {
return 3, err
}
for genTick := range genTicks {
fmt.Printf("\nGeneration %v\n%v\n", genTick.N, time.Now())
fmt.Println(game)
if genTick.Error != nil {
return 4, genTick.Error
}
if len(genTick.Message) > 0 {
fmt.Println(genTick.Message)
}
if mutate && genTick.N%2 == 0 {
game.Mutate()
}
time.Sleep(sleepInterval)
}
return 0, nil
}

View File

@ -91,7 +91,7 @@ func TestDeadCellWithExactlyThreeLiveNeighborsBecomesAlive(t *testing.T) {
}
}
func TestGameOfLifeCanDisplayItself(t *testing.T) {
func TestGameOfLifeCanDisplayItselfAsAString(t *testing.T) {
game := newTestGameOfLife()
grid := fmt.Sprintf("%s\n", game)
@ -103,6 +103,10 @@ func TestGameOfLifeCanDisplayItself(t *testing.T) {
}
}
func TestGameOfLifeCanDisplayItselfAsAnImage(t *testing.T) {
t.Fail()
}
func TestNewGameOfLifeHasCorrectDimensions(t *testing.T) {
game := newTestGameOfLife()
@ -172,7 +176,7 @@ func TestGameOfLifeCanImportRandomState(t *testing.T) {
}
}
func TestGameStateCanDisplayItself(t *testing.T) {
func TestGameStateCanDisplayItselfAsAString(t *testing.T) {
state := newTestGameState()
grid := fmt.Sprintf("%s\n", state)
@ -190,6 +194,27 @@ func TestGameStateCanDisplayItself(t *testing.T) {
}
}
func TestGameStateCanDisplayItselfAsAnImage(t *testing.T) {
state := newTestGameState()
img, err := state.Image(1, 1)
if err != nil {
t.Error(err)
return
}
bounds := img.Bounds()
if bounds.Max.Y < 16 {
t.Errorf("image.Max.Y < 16!: %d", bounds.Max.Y)
return
}
if bounds.Max.X < 16 {
t.Errorf("image.Max.X < 16!: %d", bounds.Max.X)
return
}
}
func TestNewGameStatesAreAllDead(t *testing.T) {
state := NewGameState(4, 4)
for x := 0; x < 3; x++ {

View File

@ -14,6 +14,7 @@ var (
height = flag.Int("height", 40, "Game height")
width = flag.Int("width", 80, "Game width")
mutate = flag.Bool("mutate", false, "Mutate every other generation")
web = flag.Bool("web", false, "Run server for web-based game")
sleepMs = flag.Int("sleep.ms", 200,
"Millisecond sleep interval per generation")
)
@ -21,10 +22,22 @@ var (
func main() {
flag.Parse()
retCode, err := RunConsoleGame(*height, *width, *sleepMs, *mutate)
var (
retCode int
err error
)
if *web {
retCode, err = RunWebGame(*height, *width, *sleepMs, *mutate)
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
}
} else {
retCode, err = RunConsoleGame(*height, *width, *sleepMs, *mutate)
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
}
}
os.Exit(retCode)
}

View File

@ -3,54 +3,14 @@ package conway
import (
"errors"
"fmt"
"image"
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
type GameOfLife struct {
State *GameState
}
func RunConsoleGame(height, width, sleepMs int, mutate bool) (int, error) {
sleepInterval := time.Duration(sleepMs * 1000 * 1000)
game := NewGameOfLife(height, width)
err := game.ImportRandomState()
if err != nil {
return 2, err
}
genTicks, err := game.Generations()
if err != nil {
return 3, err
}
for genTick := range genTicks {
fmt.Printf("\nGeneration %v\n%v\n", genTick.N, time.Now())
fmt.Println(game)
if genTick.Error != nil {
return 4, genTick.Error
}
if len(genTick.Message) > 0 {
fmt.Println(genTick.Message)
}
if mutate && genTick.N%2 == 0 {
game.Mutate()
}
time.Sleep(sleepInterval)
}
return 0, nil
}
func (game *GameOfLife) Mutate() {
game.State.Mutate()
}
@ -142,6 +102,10 @@ func (game *GameOfLife) String() string {
return fmt.Sprintf("%s\n", game.State)
}
func (game *GameOfLife) Image(xMult, yMult int) (*image.Gray16, error) {
return game.State.Image(xMult, yMult)
}
func (game *GameOfLife) emitGenerations(genTicks chan *GenerationTick) {
defer close(genTicks)
n := 0

View File

@ -4,6 +4,7 @@ import (
"crypto/sha1"
"errors"
"fmt"
"image"
"math"
"math/rand"
"strings"
@ -173,3 +174,7 @@ func (state *GameState) String() string {
}
return strings.Join(rows, "\n")
}
func (state *GameState) Image(xMult, yMult int) (*image.Gray16, error) {
return nil, errors.New("Not implemented!")
}

14
conway/web.go Normal file
View File

@ -0,0 +1,14 @@
package conway
import (
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
func RunWebGame(height, width, sleepMs int, mutate bool) (int, error) {
return -1, nil
}