diff --git a/cmd/gmars/main.go b/cmd/gmars/main.go index 5df4231..703a45a 100644 --- a/cmd/gmars/main.go +++ b/cmd/gmars/main.go @@ -46,53 +46,49 @@ func main() { args := flag.Args() - if *assembleFlag { - if len(args) != 1 { - fmt.Println("wrong number of arguments") - os.Exit(1) - } - } else if len(args) < 2 || len(args) > 2 { - fmt.Println("only 2 warrior battles supported") + if len(args) > 2 { + fmt.Fprintf(os.Stderr, "only 2 warrior battles supported") os.Exit(1) } - w1file, err := os.Open(args[0]) - if err != nil { - fmt.Printf("error opening warrior file '%s': %s\n", args[0], err) - os.Exit(1) + warriors := make([]gmars.WarriorData, 0) + for _, arg := range args { + in, err := os.Open(arg) + if err != nil { + fmt.Printf("error opening warrior file '%s': %s\n", arg, err) + os.Exit(1) + } + defer in.Close() + + warrior, err := gmars.CompileWarrior(in, config) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing warrior file '%s': %s\n", arg, err) + os.Exit(1) + } + + warriors = append(warriors, warrior) } - defer w1file.Close() - w1data, err := gmars.CompileWarrior(w1file, config) - if err != nil { - fmt.Printf("error parsing warrior file '%s': %s\n", args[0], err) + + if len(warriors) == 0 { + fmt.Fprintf(os.Stderr, "no warriors specified\n") os.Exit(1) } - w1file.Close() - if *assembleFlag { sim, err := gmars.NewSimulator(config) if err != nil { fmt.Printf("error creating sim: %s", err) } - w1, err := sim.AddWarrior(&w1data) - if err != nil { - fmt.Printf("error loading warrior: %s", err) + + for _, warriorData := range warriors { + w, err := sim.AddWarrior(&warriorData) + if err != nil { + fmt.Printf("error loading warrior: %s", err) + } + fmt.Println(w.LoadCode()) } - fmt.Println(w1.LoadCode()) - return - } - w2file, err := os.Open(args[1]) - if err != nil { - fmt.Printf("error opening warrior file '%s': %s\n", args[1], err) - os.Exit(1) - } - defer w1file.Close() - w2data, err := gmars.CompileWarrior(w2file, config) - if err != nil { - fmt.Printf("error parsing warrior file '%s': %s\n", args[1], err) + return } - w1file.Close() rounds := *roundFlag @@ -117,42 +113,58 @@ func main() { w2start = rand.Intn(int(startRange)+1) + int(minStart) } - w1, err := sim.AddWarrior(&w1data) + w1, err := sim.AddWarrior(&warriors[0]) if err != nil { fmt.Printf("error adding warrior 1: %s", err) + os.Exit(1) } err = sim.SpawnWarrior(0, 0) if err != nil { fmt.Printf("error adding warrior 1: %s", err) + os.Exit(1) } - w2, err := sim.AddWarrior(&w2data) - if err != nil { - fmt.Printf("error adding warrior 2: %s", err) - } - err = sim.SpawnWarrior(1, gmars.Address(w2start)) - if err != nil { - fmt.Printf("error spawning warrior 1: %s", err) + var w2 gmars.Warrior + if len(warriors) > 1 { + w, err := sim.AddWarrior(&warriors[1]) + if err != nil { + fmt.Printf("error adding warrior 2: %s", err) + os.Exit(1) + } + err = sim.SpawnWarrior(1, gmars.Address(w2start)) + if err != nil { + fmt.Printf("error spawning warrior 1: %s", err) + os.Exit(1) + } + w2 = w } sim.Run() - if w1.Alive() { - if w2.Alive() { - w1tie += 1 - } else { + if len(warriors) == 1 { + if w1.Alive() { w1win += 1 } - } - - if w2.Alive() { + } else if len(warriors) == 2 { if w1.Alive() { - w2tie += 1 - } else { - w2win += 1 + if w2.Alive() { + w1tie += 1 + } else { + w1win += 1 + } + } + + if w2.Alive() { + if w1.Alive() { + w2tie += 1 + } else { + w2win += 1 + } } } } fmt.Printf("%d %d\n", w1win, w1tie) - fmt.Printf("%d %d\n", w2win, w2tie) + if len(warriors) > 1 { + fmt.Printf("%d %d\n", w2win, w2tie) + } } diff --git a/cmd/vmars/draw.go b/cmd/vmars/draw.go index 10228ac..eec0cf1 100644 --- a/cmd/vmars/draw.go +++ b/cmd/vmars/draw.go @@ -94,28 +94,30 @@ func (g *Game) Draw(screen *ebiten.Image) { // draw results if finished if g.finished { - w1a := g.sim.GetWarrior(0).Alive() - w2a := g.sim.GetWarrior(1).Alive() - - if w1a || w2a { - - var msg string - op = &text.DrawOptions{} - op.GeoM.Translate(115, 465) - if w1a && w2a { - op.ColorScale = warriorColors[0] - msg = "tie" - } else if w1a { - op.ColorScale = warriorColors[1] - msg = fmt.Sprintf("%s wins", g.sim.GetWarrior(0).Name()) - } else if w2a { - op.ColorScale = warriorColors[2] - msg = fmt.Sprintf("%s wins", g.sim.GetWarrior(1).Name()) + if g.sim.WarriorCount() > 1 { + w1a := g.sim.GetWarrior(0).Alive() + w2a := g.sim.GetWarrior(1).Alive() + + if w1a || w2a { + + var msg string + op = &text.DrawOptions{} + op.GeoM.Translate(115, 465) + if w1a && w2a { + op.ColorScale = warriorColors[0] + msg = "tie" + } else if w1a { + op.ColorScale = warriorColors[1] + msg = fmt.Sprintf("%s wins", g.sim.GetWarrior(0).Name()) + } else if w2a { + op.ColorScale = warriorColors[2] + msg = fmt.Sprintf("%s wins", g.sim.GetWarrior(1).Name()) + } + text.Draw(screen, msg, &text.GoTextFace{ + Source: mplusFaceSource, + Size: 10, + }, op) } - text.Draw(screen, msg, &text.GoTextFace{ - Source: mplusFaceSource, - Size: 10, - }, op) } } else if !g.running { op = &text.DrawOptions{} diff --git a/cmd/vmars/game.go b/cmd/vmars/game.go index a50e4bd..b66df49 100644 --- a/cmd/vmars/game.go +++ b/cmd/vmars/game.go @@ -45,16 +45,17 @@ func (g *Game) handleInput() { g.sim.Reset() g.sim.SpawnWarrior(0, 0) - w2start := g.fixedStart - if w2start == 0 { - minStart := 2 * g.config.Length - maxStart := g.config.CoreSize - g.config.Length - 1 - startRange := maxStart - minStart - w2start = rand.Intn(int(startRange)+1) + int(minStart) + if g.sim.WarriorCount() > 1 { + w2start := g.fixedStart + if w2start == 0 { + minStart := 2 * g.config.Length + maxStart := g.config.CoreSize - g.config.Length - 1 + startRange := maxStart - minStart + w2start = rand.Intn(int(startRange)+1) + int(minStart) + } + g.sim.SpawnWarrior(1, gmars.Address(w2start)) } - g.sim.SpawnWarrior(1, gmars.Address(w2start)) - g.finished = false } else if inpututil.IsKeyJustPressed(ebiten.KeyDown) { g.slowDown() @@ -78,7 +79,9 @@ func (g *Game) runCycle() { return } - if g.sim.WarriorLivingCount() > 1 && g.sim.CycleCount() < g.sim.MaxCycles() { + count := g.sim.WarriorCount() + living := g.sim.WarriorLivingCount() + if ((count > 1 && living > 1) || living > 0) && g.sim.CycleCount() < g.sim.MaxCycles() { g.sim.RunCycle() } else { g.finished = true diff --git a/cmd/vmars/main.go b/cmd/vmars/main.go index c07fab0..87b4b5a 100644 --- a/cmd/vmars/main.go +++ b/cmd/vmars/main.go @@ -89,35 +89,28 @@ func main() { args := flag.Args() - if len(args) < 2 || len(args) > 2 { - fmt.Println("only 2 warrior battles supported") + if len(args) > 2 { + fmt.Fprintf(os.Stderr, "only 2 warrior battles supported") os.Exit(1) } - w1file, err := os.Open(args[0]) - if err != nil { - fmt.Printf("error opening warrior file '%s': %s\n", args[0], err) - os.Exit(1) - } - defer w1file.Close() - w1data, err := gmars.CompileWarrior(w1file, config) - if err != nil { - fmt.Printf("error parsing warrior file '%s': %s\n", args[0], err) - os.Exit(1) - } - w1file.Close() + warriors := make([]gmars.WarriorData, 0) + for _, arg := range args { + in, err := os.Open(arg) + if err != nil { + fmt.Printf("error opening warrior file '%s': %s\n", arg, err) + os.Exit(1) + } + defer in.Close() - w2file, err := os.Open(args[1]) - if err != nil { - fmt.Printf("error opening warrior file '%s': %s\n", args[1], err) - os.Exit(1) - } - defer w1file.Close() - w2data, err := gmars.CompileWarrior(w2file, config) - if err != nil { - fmt.Printf("error parsing warrior file '%s': %s\n", args[1], err) + warrior, err := gmars.CompileWarrior(in, config) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing warrior file '%s': %s\n", arg, err) + os.Exit(1) + } + + warriors = append(warriors, warrior) } - w1file.Close() sim, err := gmars.NewReportingSimulator(config) if err != nil { @@ -130,19 +123,23 @@ func main() { rec.SetRecordRead(*showReadFlag) sim.AddReporter(rec) - w2start := *fixedFlag - if w2start == 0 { - minStart := 2 * config.Length - maxStart := config.CoreSize - config.Length - 1 - startRange := maxStart - minStart - w2start = rand.Intn(int(startRange)+1) + int(minStart) + sim.AddWarrior(&warriors[0]) + if len(warriors) > 1 { + sim.AddWarrior(&warriors[1]) } - sim.AddWarrior(&w1data) - sim.AddWarrior(&w2data) - sim.SpawnWarrior(0, 0) - sim.SpawnWarrior(1, gmars.Address(w2start)) + + if len(warriors) > 1 { + w2start := *fixedFlag + if w2start == 0 { + minStart := 2 * config.Length + maxStart := config.CoreSize - config.Length - 1 + startRange := maxStart - minStart + w2start = rand.Intn(int(startRange)+1) + int(minStart) + } + sim.SpawnWarrior(1, gmars.Address(w2start)) + } game := &Game{ sim: sim, @@ -153,7 +150,11 @@ func main() { } ebiten.SetWindowSize(screenWidth, screenHeight) - ebiten.SetWindowTitle(fmt.Sprintf("gMARS - '%s' vs '%s'", w1data.Name, w2data.Name)) + if len(warriors) > 1 { + ebiten.SetWindowTitle(fmt.Sprintf("gMARS - '%s' vs '%s'", warriors[0].Name, warriors[1].Name)) + } else { + ebiten.SetWindowTitle(fmt.Sprintf("gMARS - '%s'", warriors[0].Name)) + } if err := ebiten.RunGame(game); err != nil { log.Fatal(err) }