func SetOrder(c common.WSContext) (result interface{}, err error) { var base64DecodedId []byte if base64DecodedId, err = base64.URLEncoding.DecodeString(c.Data().GetString("GameId")); err != nil { return } err = c.DB().Transact(func(d *kol.DB) (err error) { game := Game{Id: base64DecodedId} if err = d.Get(&game); err != nil { return } var member *Member if member, err = game.Member(d, c.Principal()); err != nil { return } var phase *Phase if _, phase, err = game.Phase(d, 0); err != nil { return } if phase == nil { err = fmt.Errorf("No phase for %+v found", game) return } nationOrders, found := phase.Orders[member.Nation] if !found { nationOrders = map[dip.Province][]string{} phase.Orders[member.Nation] = nationOrders } order := c.Data().GetStringSlice("Order") if len(order) == 1 { delete(nationOrders, dip.Province(order[0])) } else { var parsedOrder dip.Order parsedOrder, err = orders.Parse(order) if err != nil { return } var state *state.State state, err = phase.State() if err != nil { return } if err = parsedOrder.Validate(state); err != nil { return } nationOrders[dip.Province(order[0])] = order[1:] } if err = d.Set(phase); err != nil { return } return }) return }
func verifyPosition(t *testing.T, s *state.State, match []string, scCollector map[dip.Province]dip.Nation, unitCollector, dislodgedCollector map[dip.Province]dip.Unit, fails *int) { if match[2] == "supply" { if nation, _, ok := s.SupplyCenter(dip.Province(match[3])); ok && nation == dip.Nation(match[1]) { scCollector[dip.Province(match[3])] = nation } else { t.Errorf("%v: Expected %v to own SC in %v, but found %v, %v", s.Phase(), match[1], match[3], nation, ok) *fails += 1 } } else if match[2] == "army" { if unit, _, ok := s.Unit(dip.Province(match[3])); ok && unit.Nation == dip.Nation(match[1]) && unit.Type == cla.Army { unitCollector[dip.Province(match[3])] = unit } else { t.Errorf("%v: Expected to find %v %v in %v, but found %v, %v", s.Phase(), match[1], cla.Army, match[3], unit, ok) *fails += 1 } } else if match[2] == "fleet" { if unit, _, ok := s.Unit(dip.Province(match[3])); ok && unit.Nation == dip.Nation(match[1]) && unit.Type == cla.Fleet { unitCollector[dip.Province(match[3])] = unit } else { t.Errorf("%v: Expected to find %v %v in %v, but found %v, %v", s.Phase(), match[1], cla.Fleet, match[3], unit, ok) *fails += 1 } } else if match[2] == "fleet/dislodged" { if unit, _, ok := s.Dislodged(dip.Province(match[3])); ok && unit.Nation == dip.Nation(match[1]) && unit.Type == cla.Fleet { dislodgedCollector[dip.Province(match[3])] = unit } else { t.Errorf("%v: Expected to find %v %v dislodged in %v, but found %v, %v", s.Phase(), match[1], cla.Army, match[3], unit, ok) *fails += 1 } } else if match[2] == "army/dislodged" { if unit, _, ok := s.Dislodged(dip.Province(match[3])); ok && unit.Nation == dip.Nation(match[1]) && unit.Type == cla.Army { dislodgedCollector[dip.Province(match[3])] = unit } else { t.Errorf("%v: Expected to find %v %v dislodged in %v, but found %v, %v", s.Phase(), match[1], cla.Army, match[3], unit, ok) *fails += 1 } } else { t.Fatalf("Unknown position description %v", match) } }
func Parse(bits []string) (result dip.Adjudicator, err error) { if len(bits) > 1 { switch dip.OrderType(bits[1]) { case (&build{}).DisplayType(): if len(bits) == 3 { result = Build(dip.Province(bits[0]), dip.UnitType(bits[2]), time.Now()) } case (&convoy{}).DisplayType(): if len(bits) == 4 { result = Convoy(dip.Province(bits[0]), dip.Province(bits[2]), dip.Province(bits[3])) } case (&disband{}).DisplayType(): if len(bits) == 2 { result = Disband(dip.Province(bits[0]), time.Now()) } case (&hold{}).DisplayType(): if len(bits) == 2 { result = Hold(dip.Province(bits[0])) } case (&move{}).DisplayType(): if len(bits) == 3 { result = Move(dip.Province(bits[0]), dip.Province(bits[2])) } case (&move{flags: map[dip.Flag]bool{cla.ViaConvoy: true}}).DisplayType(): if len(bits) == 3 { result = Move(dip.Province(bits[0]), dip.Province(bits[2])).ViaConvoy() } case (&support{}).DisplayType(): if len(bits) == 4 { if bits[2] == bits[3] { result = SupportHold(dip.Province(bits[0]), dip.Province(bits[2])) } else { result = SupportMove(dip.Province(bits[0]), dip.Province(bits[2]), dip.Province(bits[3])) } } } } if result == nil { err = fmt.Errorf("Invalid order %+v", bits) } return }
Graph: start.Graph(), Phase: classical.Phase, OrderTypes: orders.OrderTypes(), Nations: cla.Nations, PhaseTypes: cla.PhaseTypes, Seasons: cla.Seasons, UnitTypes: cla.UnitTypes, }, Variant{ Name: FleetRome, Graph: start.Graph(), Start: func() (result *state.State, err error) { if result, err = classical.Start(); err != nil { return } result.RemoveUnit(dip.Province("rom")) if err = result.SetUnit(dip.Province("rom"), dip.Unit{ Type: cla.Fleet, Nation: cla.Italy, }); err != nil { return } return }, Blank: classical.Blank, Phase: classical.Phase, ParseOrders: orders.ParseAll, ParseOrder: orders.Parse, OrderTypes: orders.OrderTypes(), Nations: cla.Nations, PhaseTypes: cla.PhaseTypes,
func assertGame(t *testing.T, name string) (phases, ords, positions, fails int, s *state.State) { file, err := os.Open(fmt.Sprintf("games/%v", name)) if err != nil { t.Fatalf("%v", err) } if s, err = classical.Start(); err != nil { t.Fatalf("%v", err) } lines := bufio.NewReader(file) var match []string state := inNothing scCollector, unitCollector, dislodgedCollector := make(map[dip.Province]dip.Nation), make(map[dip.Province]dip.Unit), make(map[dip.Province]dip.Unit) for line, err := lines.ReadString('\n'); err == nil; line, err = lines.ReadString('\n') { line = strings.TrimSpace(line) switch state { case inNothing: if match = phaseReg.FindStringSubmatch(line); match != nil { phases += 1 setPhase(t, &s, match) } else if line == positionsTag { state = inPositions } else { t.Fatalf("Unknown line for state inNothing: %v", line) } case inPositions: if match = posReg.FindStringSubmatch(line); match != nil { positions += 1 verifyPosition(t, s, match, scCollector, unitCollector, dislodgedCollector, &fails) } else if line == ordersTag { verifyReversePositions(t, s, scCollector, unitCollector, dislodgedCollector, &fails) if fails > 0 { return } dip.ClearLog() scCollector, unitCollector, dislodgedCollector = make(map[dip.Province]dip.Nation), make(map[dip.Province]dip.Unit), make(map[dip.Province]dip.Unit) state = inOrders } else { t.Fatalf("Unknown line for state inPositions: %v", line) } case inOrders: ords += 1 if match = moveReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Move(dip.Province(match[1]), dip.Province(match[2]))) } else if match = moveViaConvoyReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Move(dip.Province(match[1]), dip.Province(match[2])).ViaConvoy()) } else if match = supportMoveReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.SupportMove(dip.Province(match[1]), dip.Province(match[2]), dip.Province(match[3]))) } else if match = supportHoldReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.SupportHold(dip.Province(match[1]), dip.Province(match[2]))) } else if match = holdReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Hold(dip.Province(match[1]))) } else if match = convoyReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Convoy(dip.Province(match[1]), dip.Province(match[2]), dip.Province(match[3]))) } else if match = buildReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[2]), orders.Build(dip.Province(match[2]), dip.UnitType(match[1]), time.Now())) } else if match = removeReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Disband(dip.Province(match[1]), time.Now())) } else if match = disbandReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Disband(dip.Province(match[1]), time.Now())) } else if match = phaseReg.FindStringSubmatch(line); match != nil { ords -= 1 phases += 1 setPhase(t, &s, match) state = inNothing } else { t.Fatalf("Unknown line for state inOrders: %v", line) } default: t.Fatalf("Unknown state %v", state) } } return }