コード例 #1
0
ファイル: classical.go プロジェクト: arlm/godip
func BackupRule(state dip.State, deps []dip.Province) (err error) {
	only_moves := true
	convoys := false
	for _, prov := range deps {
		if order, _, ok := state.Order(prov); ok {
			if order.Type() != cla.Move {
				only_moves = false
			}
			if order.Type() == cla.Convoy {
				convoys = true
			}
		}
	}

	if only_moves {
		for _, prov := range deps {
			state.SetResolution(prov, nil)
		}
		return
	}
	if convoys {
		for _, prov := range deps {
			if order, _, ok := state.Order(prov); ok && order.Type() == cla.Convoy {
				state.SetResolution(prov, cla.ErrConvoyParadox)
			}
		}
		return
	}

	err = fmt.Errorf("Unknown circular dependency between %v", deps)
	return
}
コード例 #2
0
ファイル: move.go プロジェクト: arlm/godip
func (self *move) Execute(state dip.State) {
	if state.Phase().Type() == cla.Retreat {
		state.Retreat(self.targets[0], self.targets[1])
	} else {
		state.Move(self.targets[0], self.targets[1], !cla.MustConvoy(state, self.targets[0]))
	}
}
コード例 #3
0
ファイル: disband.go プロジェクト: arlm/godip
func (self *disband) Execute(state dip.State) {
	if state.Phase().Type() == cla.Adjustment {
		state.RemoveUnit(self.targets[0])
	} else {
		state.RemoveDislodged(self.targets[0])
	}
}
コード例 #4
0
ファイル: phase.go プロジェクト: arlm/godip
func (self *phase) sortedUnits(s dip.State, n dip.Nation) (result []dip.Province, err error) {
	provs := remoteUnitSlice{
		distances: make(map[dip.Province]int),
		units:     make(map[dip.Province]dip.Unit),
	}
	provs.provinces, _, _ = s.Find(func(p dip.Province, o dip.Order, u *dip.Unit) bool {
		if u != nil && u.Nation == n {
			if provs.distances[p], err = self.shortestDistance(s, p, s.Graph().SCs(n)); err != nil {
				return false
			}
			provs.units[p] = *u
			return true
		}
		return false
	})
	if err != nil {
		return
	}
	sort.Sort(provs)
	dip.Logf("Sorted units for %v is %v", n, provs)
	result = provs.provinces
	return
}
コード例 #5
0
ファイル: phase.go プロジェクト: arlm/godip
func (self *phase) shortestDistance(s dip.State, src dip.Province, dst []dip.Province) (result int, err error) {
	var unit dip.Unit
	var ok bool
	unit, src, ok = s.Unit(src)
	if !ok {
		err = fmt.Errorf("No unit at %v", src)
		return
	}
	var filter dip.PathFilter
	found := false
	for _, destination := range dst {
		if unit.Type == cla.Fleet {
			filter = func(p dip.Province, edgeFlags, nodeFlags map[dip.Flag]bool, sc *dip.Nation) bool {
				return edgeFlags[cla.Sea] && nodeFlags[cla.Sea]
			}
		} else {
			filter = func(p dip.Province, edgeFlags, nodeFlags map[dip.Flag]bool, sc *dip.Nation) bool {
				if p.Super() == destination.Super() {
					return true
				}
				u, _, ok := s.Unit(p)
				return (edgeFlags[cla.Land] && nodeFlags[cla.Land]) || (ok && !nodeFlags[cla.Land] && u.Nation == unit.Nation && u.Type == cla.Fleet)
			}
		}
		for _, coast := range s.Graph().Coasts(destination) {
			for _, srcCoast := range s.Graph().Coasts(src) {
				if srcCoast == destination {
					result = 0
					found = true
				} else {
					if path := s.Graph().Path(srcCoast, coast, filter); path != nil {
						if !found || len(path) < result {
							result = len(path)
							found = true
						}
					}
					if path := s.Graph().Path(srcCoast, coast, nil); path != nil {
						if !found || len(path) < result {
							result = len(path)
							found = true
						}
					}
				}
			}
		}
	}
	return
}
コード例 #6
0
ファイル: phase.go プロジェクト: arlm/godip
func (self *phase) PostProcess(s dip.State) (err error) {
	if self.typ == cla.Retreat {
		for prov, _ := range s.Dislodgeds() {
			s.RemoveDislodged(prov)
			s.SetResolution(prov, cla.ErrForcedDisband)
		}
		s.ClearDislodgers()
		s.ClearBounces()
		if self.season == cla.Fall {
			s.Find(func(p dip.Province, o dip.Order, u *dip.Unit) bool {
				if u != nil {
					if s.Graph().SC(p) != nil {
						s.SetSC(p.Super(), u.Nation)
					}
				}
				return false
			})
		}
	} else if self.typ == cla.Adjustment {
		for _, nationality := range cla.Nations {
			_, _, balance := cla.AdjustmentStatus(s, nationality)
			if balance < 0 {
				var su []dip.Province
				if su, err = self.sortedUnits(s, nationality); err != nil {
					return
				}
				su = su[:-balance]
				for _, prov := range su {
					dip.Logf("Removing %v due to forced disband", prov)
					s.RemoveUnit(prov)
					s.SetResolution(prov, cla.ErrForcedDisband)
				}
			}
		}
	} else if self.typ == cla.Movement {
		for prov, unit := range s.Dislodgeds() {
			hasRetreat := false
			for edge, _ := range s.Graph().Edges(prov) {
				if _, _, ok := s.Unit(edge); !ok && !s.Bounce(prov, edge) {
					if cla.HasEdge(s, unit.Type, prov, edge) {
						dip.Logf("%v can retreat to %v", prov, edge)
						hasRetreat = true
						break
					}
				}
			}
			if !hasRetreat {
				s.RemoveDislodged(prov)
				dip.Logf("Removing %v since it has no retreat", prov)
			}
		}
	}
	return
}