| @@ -0,0 +1,22 @@ | ||
| Copyright (c) 2015 Kevin Burke. | ||
| Permission is hereby granted, free of charge, to any person | ||
| obtaining a copy of this software and associated documentation | ||
| files (the "Software"), to deal in the Software without | ||
| restriction, including without limitation the rights to use, | ||
| copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the | ||
| Software is furnished to do so, subject to the following | ||
| conditions: | ||
| The above copyright notice and this permission notice shall be | ||
| included in all copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
| OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
| WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| OTHER DEALINGS IN THE SOFTWARE. |
| @@ -1,16 +1,30 @@ | ||
| .PHONY: test serve install experiment | ||
| test: | ||
| go test ./... | ||
| # need to skip the wip directory | ||
| all: install test | ||
| install: | ||
| go get github.com/jmhodges/justrun | ||
| go install github.com/jmhodges/justrun | ||
| go get ./... | ||
| go install ./... | ||
| go install ./bits/... ./genetic/... ./geo/... ./image/... ./rle/... ./server/... ./td6/... ./tracks/... | ||
| test: | ||
| go test -race -timeout 1s \ | ||
| ./bits/... \ | ||
| ./genetic/... \ | ||
| ./geo/... \ | ||
| ./image/... \ | ||
| ./physics/... \ | ||
| ./rle/... \ | ||
| ./server/... \ | ||
| ./td6/... \ | ||
| ./tracks/... | ||
| serve: | ||
| find . -name '*.go' -o -name '*.html' | justrun -stdin -v=true -c 'go run server/main.go --template-directory="$(PWD)/server/templates" --static-directory="$(PWD)/server/static"' | ||
| experiment: | ||
| go run genetic/runners/main.go | ||
| experiment: install | ||
| run_experiment --package-root ~/code/go/src/github.com/kevinburke/rct | ||
| compress: install | ||
| get_old_experiments | bash scripts/compress.bash |
| @@ -0,0 +1,278 @@ | ||
| package main | ||
| import ( | ||
| "bufio" | ||
| "fmt" | ||
| "strings" | ||
| "github.com/kevinburke/rct/tracks" | ||
| ) | ||
| func main() { | ||
| blah := ` { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 16, 0, 0 }, | ||
| { 0, 0, 0, 64, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 32, 0, 0 }, | ||
| { 0, 0, 0, 32, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 16, 0, 0, 0 }, | ||
| { 0, 0, 64, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 32, 0, 0, 0 }, | ||
| { 0, 0, 32, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 3, 0, 0, -64, -64 }, | ||
| { 0, 1, 0, 0, -64, 64 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 3, 0, 0, -64, -64 }, | ||
| { 0, 1, 0, 0, -64, 64 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 3, 0, 64, -64, -64 }, | ||
| { 0, 1, 0, 64, -64, 64 }, | ||
| { 0, 3, 64, 0, -64, -64 }, | ||
| { 0, 1, 64, 0, -64, 64 }, | ||
| { 0, 0, 0, 0, -64, -32 }, | ||
| { 0, 0, 0, 0, -64, 32 }, | ||
| { 0, 0, 0, 0, -32, -32 }, | ||
| { 0, 0, 0, 0, -32, 32 }, | ||
| { 0, 3, 0, 0, -32, -32 }, | ||
| { 0, 1, 0, 0, -32, 32 }, | ||
| { 0, 3, 0, 0, -32, -32 }, | ||
| { 0, 1, 0, 0, -32, 32 }, | ||
| { 0, 3, 0, 32, -32, -32 }, | ||
| { 0, 1, 0, 32, -32, 32 }, | ||
| { 0, 3, 32, 0, -32, -32 }, | ||
| { 0, 1, 32, 0, -32, 32 }, | ||
| { 0, 3, 0, 0, 0, 0 }, | ||
| { 0, 1, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 16, -64, 0 }, | ||
| { 0, 0, 0, 16, -64, 0 }, | ||
| { 0, 0, 0, -16, -64, 0 }, | ||
| { 0, 0, 0, -16, -64, 0 }, | ||
| { 0, 2, 0, 152, -32, 0 }, | ||
| { 0, 2, 0, -152, 32, 0 }, | ||
| { 0, 3, 0, 80, -32, -32 }, | ||
| { 0, 1, 0, 80, -32, 32 }, | ||
| { 0, 3, 0, -80, -32, -32 }, | ||
| { 0, 1, 0, -80, -32, 32 }, | ||
| { 0, 0, 0, 24, 0, 0 }, | ||
| { 0, 0, 0, 24, 0, 0 }, | ||
| { 0, 0, 24, 0, 0, 0 }, | ||
| { 0, 0, 24, 0, 0, 0 }, | ||
| { 0, 0, 0, 96, 32, 0 }, | ||
| { 0, 0, 0, 32, 32, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 16, 0, 0 }, | ||
| { 0, 0, 0, 64, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 32, 0, 0 }, | ||
| { 0, 0, 0, 32, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 16, 0, 0, 0 }, | ||
| { 0, 0, 64, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 32, 0, 0, 0 }, | ||
| { 0, 0, 32, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 3, 0, 0, -64, -64 }, | ||
| { 0, 1, 0, 0, -64, 64 }, | ||
| { 0, 0, 0, 0, -64, -32 }, | ||
| { 0, 0, 0, 0, -64, 32 }, | ||
| { 0, 3, 0, 0, -32, -32 }, | ||
| { 0, 1, 0, 0, -32, 32 }, | ||
| { 0, 2, 0, 16, 0, -96 }, | ||
| { 0, 2, 0, 16, 0, 96 }, | ||
| { 0, 2, 16, 0, 0, -96 }, | ||
| { 0, 2, 16, 0, 0, 96 }, | ||
| { 0, 2, 0, 16, 0, -160 }, | ||
| { 0, 2, 0, 16, 0, 160 }, | ||
| { 0, 2, 16, 0, 0, -160 }, | ||
| { 0, 2, 16, 0, 0, 160 }, | ||
| { 0, 3, 0, 64, 0, 0 }, | ||
| { 0, 1, 0, 64, 0, 0 }, | ||
| { 0, 3, 64, 0, 0, 0 }, | ||
| { 0, 1, 64, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 3, 0, 16, -64, -64 }, | ||
| { 0, 1, 0, 16, -64, 64 }, | ||
| { 0, 3, 16, 0, -64, -64 }, | ||
| { 0, 1, 16, 0, -64, 64 }, | ||
| { 0, 3, 0, 16, -64, -64 }, | ||
| { 0, 1, 0, 16, -64, 64 }, | ||
| { 0, 3, 16, 0, -64, -64 }, | ||
| { 0, 1, 16, 0, -64, 64 }, | ||
| { 0, 0, 0, 16, 0, 0 }, | ||
| { 0, 0, 0, 16, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 16, 0, 0, 0 }, | ||
| { 0, 0, 16, 0, 0, 0 }, | ||
| { 0, 0, 16, 16, -128, 0 }, | ||
| { 0, 0, 0, 88, -96, 0 }, | ||
| { 0, 0, 0, 88, -96, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 88, 0, -96, 0 }, | ||
| { 0, 0, 88, 0, -96, 0 }, | ||
| { 0, 0, 0, -96, -96, 0 }, | ||
| { 0, 0, 0, 240, -160, 0 }, | ||
| { 0, 0, 0, 80, 32, 0 }, | ||
| { 0, 0, 0, 32, 32, 0 }, | ||
| { 0, 0, 32, 0, 32, 0 }, | ||
| { 0, 0, 0, 56, 32, 0 }, | ||
| { 0, 0, 56, 0, 0, 0 }, | ||
| { 0, 0, 0, 56, 0, 0 }, | ||
| { 0, 0, 56, 0, 32, 0 }, | ||
| { 0, 0, 24, 0, 0, 0 }, | ||
| { 0, 7, 0, 0, -64, -32 }, | ||
| { 0, 4, 0, 0, -64, 32 }, | ||
| { 4, 0, 0, 0, -64, 32 }, | ||
| { 4, 1, 0, 0, -32, 64 }, | ||
| { 0, 7, 0, 0, -64, -32 }, | ||
| { 0, 4, 0, 0, -64, 32 }, | ||
| { 4, 0, 0, 0, -64, 32 }, | ||
| { 4, 1, 0, 0, -32, 64 }, | ||
| { 4, 4, 0, 0, -32, 32 }, | ||
| { 4, 4, 0, 16, -32, 32 }, | ||
| { 4, 4, 0, 64, -32, 32 }, | ||
| { 4, 4, 0, 8, -32, 32 }, | ||
| { 4, 4, 0, 32, -32, 32 }, | ||
| { 4, 4, 0, 32, -32, 32 }, | ||
| { 4, 4, 0, 8, -32, 32 }, | ||
| { 4, 4, 16, 0, -32, 32 }, | ||
| { 4, 4, 64, 0, -32, 32 }, | ||
| { 4, 4, 8, 0, -32, 32 }, | ||
| { 4, 4, 32, 0, -32, 32 }, | ||
| { 4, 4, 32, 0, -32, 32 }, | ||
| { 4, 4, 8, 0, -32, 32 }, | ||
| { 4, 4, 0, 24, -32, 32 }, | ||
| { 4, 4, 0, 24, -32, 32 }, | ||
| { 4, 4, 24, 0, -32, 32 }, | ||
| { 4, 4, 24, 0, -32, 32 }, | ||
| { 4, 4, 0, 0, -32, 32 }, | ||
| { 4, 4, 0, 0, -32, 32 }, | ||
| { 4, 4, 0, 0, -32, 32 }, | ||
| { 4, 4, 0, 0, -32, 32 }, | ||
| { 4, 4, 0, 8, -32, 32 }, | ||
| { 4, 4, 0, 8, -32, 32 }, | ||
| { 4, 4, 0, 8, -32, 32 }, | ||
| { 4, 4, 0, 8, -32, 32 }, | ||
| { 4, 4, 8, 0, -32, 32 }, | ||
| { 4, 4, 8, 0, -32, 32 }, | ||
| { 4, 4, 8, 0, -32, 32 }, | ||
| { 4, 4, 8, 0, -32, 32 }, | ||
| { 4, 4, 0, 0, -32, 32 }, | ||
| { 4, 4, 0, 0, -32, 32 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 0, 0, 32, -64, 0 }, | ||
| { 0, 0, 0, 32, -64, 0 }, | ||
| { 0, 0, 0, -32, -64, 0 }, | ||
| { 0, 0, 0, -32, -64, 0 }, | ||
| { 0, 3, 0, 24, -32, -32 }, | ||
| { 0, 1, 0, 24, -32, 32 }, | ||
| { 0, 3, 24, 0, -32, -32 }, | ||
| { 0, 1, 24, 0, -32, 32 }, | ||
| { 0, 0, 0, 16, 0, 0 }, | ||
| { 0, 2, 0, 280, -64, -32 }, | ||
| { 0, 2, 0, 280, -64, 32 }, | ||
| { 0, 2, 0, -280, 64, -32 }, | ||
| { 0, 2, 0, -280, 64, 32 }, | ||
| { 0, 0, 0, -16, -64, 0 }, | ||
| { 0, 0, 0, -16, -64, 0 }, | ||
| { 0, 0, 0, 16, -64, 0 }, | ||
| { 0, 0, 0, 16, -64, 0 }, | ||
| { 0, 2, 0, 120, -32, 0 }, | ||
| { 0, 2, 0, -120, 32, 0 }, | ||
| { 0, 3, 0, 48, -32, -32 }, | ||
| { 0, 1, 0, 48, -32, 32 }, | ||
| { 0, 3, 0, -48, -32, -32 }, | ||
| { 0, 1, 0, -48, -32, 32 }, | ||
| { 0, 2, 0, 32, 0, 0 }, | ||
| { 0, 2, 0, -32, 0, 0 }, | ||
| { 0, 0, 0, 0, -160, 0 }, | ||
| { 0, 0, 0, 0, -160, 0 }, | ||
| { 0, 0, 0, 0, -32, 0 }, | ||
| { 0, 0, 0, 0, -32, 0 }, | ||
| { 0, 0, 0, 0, -32, 0 }, | ||
| { 0, 1, 0, 0, -32, 32 }, | ||
| { 0, 3, 0, 0, -32, -32 }, | ||
| { 0, 2, 0, -96, -96, 0 }, | ||
| { 0, 2, 0, 128, 64, 0 }, | ||
| { 0, 2, 0, -128, -96, 0 }, | ||
| { 0, 3, 0, 16, -32, -32 }, | ||
| { 0, 1, 0, 16, -32, 32 }, | ||
| { 0, 0, 0, 0, -64, 0 }, | ||
| { 0, 0, 0, 0, -64, 0 }, | ||
| { 0, 0, 0, 0, -32, 0 }, | ||
| { 0, 0, 80, 0, 32, 0 }, | ||
| { 0, 0, 240, 0, -160, 0 }, | ||
| { 0, 0, 0, 0, 0, 0 }, | ||
| { 0, 3, 0, 32, -32, -32 }, | ||
| { 0, 1, 0, 32, -32, 32 }, | ||
| { 0, 3, 32, 0, -32, -32 }, | ||
| { 0, 1, 32, 0, -32, 32 }, | ||
| { 0, 3, 0, 64, -64, -64 }, | ||
| { 0, 1, 0, 64, -64, 64 }, | ||
| { 0, 3, 64, 0, -64, -64 }, | ||
| { 0, 1, 64, 0, -64, 64 }, | ||
| { 0, 0, 0, 16, 0, 0 }, | ||
| { 0, 0, 0, 16, 0, 0 }, | ||
| { 0, 0, 0, 16, 0, 0 }, | ||
| { 0, 0, 0, 16, 0, 0 }, | ||
| { 0, 0, 16, 0, 0, 0 }, | ||
| { 0, 0, 16, 0, 0, 0 }, | ||
| { 0, 0, 16, 0, 0, 0 }, | ||
| { 0, 0, 16, 0, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 0, 8, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 0, 8, 0, 0, 0 }, | ||
| { 0, 3, 0, 96, 0, 32 }, | ||
| { 0, 1, 0, 96, 0, -32 }, | ||
| { 0, 3, 96, 0, 0, 32 }, | ||
| { 0, 1, 96, 0, 0, -32 }, | ||
| { 0, 2, 0, 96, 64, 0 }, | ||
| { 0, 2, 0, -128, -96, 0 }, | ||
| { 0, 2, 0, 128, 64, 0 }` | ||
| scanner := bufio.NewScanner(strings.NewReader(blah)) | ||
| count := 0 | ||
| for scanner.Scan() { | ||
| if count < len(tracks.ElementNames) { | ||
| fmt.Printf("%s\t// %s\n", scanner.Text(), tracks.ElementNames[count]) | ||
| count++ | ||
| } else { | ||
| fmt.Printf("%s\n", scanner.Text()) | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,72 @@ | ||
| package main | ||
| import ( | ||
| "os" | ||
| "github.com/kevinburke/rct/exe_reader" | ||
| "github.com/kevinburke/rct/tracks" | ||
| ) | ||
| // taken from track_data.h | ||
| const RCT_DIRECTION_ADDR = 0x005968BB | ||
| const RCT_DIRECTION_WIDTH = 10 | ||
| const RCT_BANK_SLOPE_ADDR = 0x00597c9d | ||
| const RCT_BANK_SLOPE_WIDTH = 8 | ||
| // Follows the format in TrackCoordinates | ||
| /* | ||
| sint8 rotation_negative; // 0x00 | ||
| sint8 rotation_positive; // 0x01 | ||
| sint16 z_negative; // 0x02 | ||
| sint16 z_positive; // 0x04 | ||
| sint16 x; // 0x06 | ||
| // my sideways delta | ||
| sint16 y; // 0x08 | ||
| */ | ||
| const RCT_FORWARD_ADDR = 0x005968bb | ||
| const RCT_FORWARD_WIDTH = 0x0A | ||
| func main() { | ||
| f, err := os.Open(os.Getenv("HOME") + "/code/OpenRCT2/openrct2.exe") | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| defer f.Close() | ||
| b := make([]byte, 256*RCT_DIRECTION_WIDTH) | ||
| f.ReadAt(b, int64(RCT_DIRECTION_ADDR)) | ||
| c := make([]byte, 256*RCT_BANK_SLOPE_WIDTH) | ||
| f.ReadAt(c, RCT_BANK_SLOPE_ADDR) | ||
| d := make([]byte, 256*RCT_FORWARD_WIDTH) | ||
| f.ReadAt(d, RCT_FORWARD_ADDR) | ||
| for i := 0; i < len(tracks.ElementNames); i++ { | ||
| //fmt.Println(i) | ||
| //fmt.Printf("%55s ", tracks.ElementNames[i]) | ||
| //fmt.Printf("%4d ", b[i*WIDTH]) | ||
| //fmt.Printf("\n") | ||
| idx := i * RCT_DIRECTION_WIDTH | ||
| bitSubset := b[idx : idx+RCT_DIRECTION_WIDTH] | ||
| // xxx - there are 2 pieces to direction change, the first one is for | ||
| // diagonal to straight. we're ignoring diagonals for the moment. | ||
| //fmt.Printf("%s: %v\n", tracks.ElementNames[i], bitSubset[0]) | ||
| //fmt.Printf("%s: %v\n", tracks.ElementNames[i], bitSubset[8]) | ||
| bankIdx := i * RCT_BANK_SLOPE_WIDTH | ||
| bankBitSubset := c[bankIdx : bankIdx+RCT_BANK_SLOPE_WIDTH] | ||
| forwardIdx := i * RCT_FORWARD_WIDTH | ||
| forwardBitSubset := d[forwardIdx : forwardIdx+RCT_FORWARD_WIDTH] | ||
| exe_reader.PrintValues(i, tracks.ElementNames[i], int(bitSubset[1]), int(bitSubset[8]), int(bitSubset[2]), int(bitSubset[4]), bankBitSubset, forwardBitSubset) | ||
| } | ||
| //fmt.Printf("%#v\n", tracks.TS_MAP) | ||
| //fmt.Printf("%T\n", tracks.TS_MAP) | ||
| } |
| @@ -0,0 +1,25 @@ | ||
| package exe_reader | ||
| import "testing" | ||
| var sidewaysTests = []struct { | ||
| in int | ||
| expected int | ||
| }{ | ||
| {0, 0}, | ||
| {32, -2}, | ||
| {64, -3}, | ||
| {96, -4}, | ||
| {160, 4}, | ||
| {192, 3}, | ||
| {224, 2}, | ||
| } | ||
| func TestSidewaysDelta(t *testing.T) { | ||
| for _, tt := range sidewaysTests { | ||
| out := SidewaysDelta(tt.in) | ||
| if out != tt.expected { | ||
| t.Errorf("expected SidewaysDelta(%d) to be %d, was %d", tt.in, tt.expected, out) | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,66 @@ | ||
| package genetic | ||
| import ( | ||
| "encoding/json" | ||
| "io/ioutil" | ||
| "os" | ||
| "path/filepath" | ||
| "time" | ||
| ) | ||
| // GetExperimentFiles returns a list of directories containing experiments | ||
| func GetExperimentFiles() (folders []string, err error) { | ||
| expDir := filepath.Join(*directory, "experiments") | ||
| finfo, err := ioutil.ReadDir(expDir) | ||
| if err != nil { | ||
| return folders, err | ||
| } | ||
| for _, dir := range finfo { | ||
| path := filepath.Join(expDir, dir.Name()) | ||
| folders = append(folders, path) | ||
| } | ||
| return folders, nil | ||
| } | ||
| func GetOldFiles(d time.Duration) []string { | ||
| var oldFolders []string | ||
| files, err := GetExperimentFiles() | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| now := time.Now().UTC() | ||
| for _, dir := range files { | ||
| metaPath := filepath.Join(dir, "meta.json") | ||
| em, err := ReadMetadata(metaPath) | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| duration := now.Sub(em.Date) | ||
| if duration > d { | ||
| oldFolders = append(oldFolders, dir) | ||
| } | ||
| } | ||
| return oldFolders | ||
| } | ||
| // encode writes the given interface to the disk. | ||
| func encode(name string, v interface{}) error { | ||
| f, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| defer f.Close() | ||
| enc := json.NewEncoder(f) | ||
| return enc.Encode(v) | ||
| } | ||
| func ReadMetadata(filename string) (ExperimentMetadata, error) { | ||
| f, err := os.Open(filename) | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| var em ExperimentMetadata | ||
| js := json.NewDecoder(f) | ||
| err = js.Decode(&em) | ||
| return em, err | ||
| } |
| @@ -0,0 +1,102 @@ | ||
| package genetic | ||
| import ( | ||
| "testing" | ||
| "github.com/kevinburke/rct/tracks" | ||
| ) | ||
| func TestSwap(t *testing.T) { | ||
| a := &Member{ | ||
| Track: []tracks.Element{ | ||
| {Segment: tracks.TS_MAP[tracks.ELEM_FLAT]}, | ||
| {Segment: tracks.TS_MAP[tracks.ELEM_25_DEG_UP]}, | ||
| }, | ||
| } | ||
| b := &Member{ | ||
| Track: []tracks.Element{ | ||
| {Segment: tracks.TS_MAP[tracks.ELEM_25_DEG_DOWN]}, | ||
| {Segment: tracks.TS_MAP[tracks.ELEM_60_DEG_DOWN]}, | ||
| }, | ||
| } | ||
| c, d := Swap(a, b, 1, 1) | ||
| cexpected := []tracks.Element{ | ||
| {Segment: tracks.TS_MAP[tracks.ELEM_FLAT]}, | ||
| {Segment: tracks.TS_MAP[tracks.ELEM_60_DEG_DOWN]}, | ||
| } | ||
| if c.Track[0] != cexpected[0] || c.Track[1] != cexpected[1] { | ||
| t.Errorf("expected c to be %v, was %v", cexpected, c.Track) | ||
| } | ||
| dexpected := []tracks.Element{ | ||
| {Segment: tracks.TS_MAP[tracks.ELEM_25_DEG_DOWN]}, | ||
| {Segment: tracks.TS_MAP[tracks.ELEM_25_DEG_UP]}, | ||
| } | ||
| if d.Track[0] != dexpected[0] || d.Track[1] != dexpected[1] { | ||
| t.Errorf("expected d to be %v, was %v", dexpected, d.Track) | ||
| } | ||
| } | ||
| func elem(s tracks.SegmentType) tracks.Element { | ||
| return tracks.Element{ | ||
| Segment: tracks.TS_MAP[s], | ||
| } | ||
| } | ||
| func TestCrossover(t *testing.T) { | ||
| parent1 := &Member{ | ||
| Track: []tracks.Element{ | ||
| elem(tracks.ELEM_BEGIN_STATION), | ||
| elem(tracks.ELEM_MIDDLE_STATION), | ||
| elem(tracks.ELEM_MIDDLE_STATION), | ||
| elem(tracks.ELEM_MIDDLE_STATION), | ||
| elem(tracks.ELEM_END_STATION), | ||
| elem(tracks.ELEM_FLAT_TO_RIGHT_BANK), | ||
| elem(tracks.ELEM_RIGHT_QUARTER_TURN_3_TILES_BANK), | ||
| elem(tracks.ELEM_RIGHT_QUARTER_TURN_3_TILES_BANK), | ||
| elem(tracks.ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_DOWN), | ||
| elem(tracks.ELEM_RIGHT_BANK_TO_25_DEG_DOWN), | ||
| elem(tracks.ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN), | ||
| elem(tracks.ELEM_25_DEG_DOWN_TO_LEFT_BANK), | ||
| elem(tracks.ELEM_LEFT_BANK_TO_25_DEG_UP), | ||
| elem(tracks.ELEM_25_DEG_UP_TO_FLAT), | ||
| elem(tracks.ELEM_FLAT_TO_25_DEG_UP), | ||
| elem(tracks.ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP), | ||
| }, | ||
| } | ||
| parent2 := &Member{ | ||
| Track: []tracks.Element{ | ||
| elem(tracks.ELEM_BEGIN_STATION), | ||
| elem(tracks.ELEM_MIDDLE_STATION), | ||
| elem(tracks.ELEM_MIDDLE_STATION), | ||
| elem(tracks.ELEM_MIDDLE_STATION), | ||
| elem(tracks.ELEM_END_STATION), | ||
| elem(tracks.ELEM_S_BEND_RIGHT), | ||
| elem(tracks.ELEM_LEFT_QUARTER_TURN_5_TILES), | ||
| elem(tracks.ELEM_LEFT_QUARTER_TURN_3_TILES), | ||
| elem(tracks.ELEM_FLAT_TO_RIGHT_BANK), | ||
| elem(tracks.ELEM_RIGHT_BANK_TO_25_DEG_UP), | ||
| elem(tracks.ELEM_25_DEG_UP_TO_LEFT_BANK), | ||
| elem(tracks.ELEM_LEFT_BANK), | ||
| elem(tracks.ELEM_LEFT_HALF_BANKED_HELIX_UP_SMALL), | ||
| elem(tracks.ELEM_LEFT_HALF_BANKED_HELIX_DOWN_SMALL), | ||
| elem(tracks.ELEM_LEFT_HALF_BANKED_HELIX_DOWN_LARGE), | ||
| elem(tracks.ELEM_LEFT_HALF_BANKED_HELIX_UP_SMALL), | ||
| }, | ||
| } | ||
| checkCompatible := func(track []tracks.Element) { | ||
| for i, elem := range track[:len(track)-1] { | ||
| if tracks.Compatible(elem, track[i+1]) == false { | ||
| t.Errorf("Crossover generated incompatible segments: %s, %s", elem.Segment.String(), track[i+1].Segment.String()) | ||
| } | ||
| } | ||
| } | ||
| child1, child2 := crossoverOne(parent1, parent2, 11) | ||
| checkCompatible(child1.Track) | ||
| checkCompatible(child2.Track) | ||
| // Reverse and try again. | ||
| child1, child2 = crossoverOne(parent2, parent1, 10) | ||
| checkCompatible(child1.Track) | ||
| checkCompatible(child2.Track) | ||
| } |