public void BeFast() { int[,] heights = new int[10, 10]; Vec[][] units = { new[] { new Vec(0, 0), new Vec(2, 2) }, new[] { new Vec(4, 4), new Vec(6, 6) } }; var deads = new[] { false, false }; var scores = new[] { 0, 0 }; var state = new State(heights, units, deads, scores); for (int i = 0; i < 3000; i++) { foreach (var pos in Vec.Area(state.Size)) { for (int h = 0; h < 5; h++) { // Пересчёт значений должен быть на порядок быстрее, чем рассчёт хэша с нуля. state.SetHeight(pos, h); GetHashValue(state); // var v = new ZobristHasher(state).HashValue; // Это рассчёт снуля. Можно раскомментировать и проверить, что это медленнее. } } } }
public void EnsureValid() { var badCell = Vec.Area(Size, Size).FirstOrDefault(h => !HeightAt(h).InRange(0, 4)); if (badCell != null) { throw new Exception($"cell {badCell} has height {HeightAt(badCell)}"); } foreach (var unit in units.SelectMany(us => us)) { if (unit.X >= 0 && !HeightAt(unit).InRange(0, 3)) { throw new Exception($"unit {unit} stands on cell with height {HeightAt(unit)}"); } } }
public void HashHeights() { var state = GetState(); var oldHash = GetHashValue(state); foreach (var pos in Vec.Area(state.Size)) { var oldHeight = state.HeightAt(pos); for (int h = 0; h < 5; h++) { if (h != oldHeight) { state.SetHeight(pos, h); GetHashValue(state).Should().NotBe(oldHash); state.SetHeight(pos, oldHeight); GetHashValue(state).Should().Be(oldHash); } } } }
public void HashUnits() { var state = GetState(); var oldHash = GetHashValue(state); foreach (var player in new[] { 0, 1 }) { var units = state.GetUnits(player); int unitsCount = units.Count; for (int iUnit = 0; iUnit < unitsCount; iUnit++) { var unit = units[iUnit]; foreach (var pos in Vec.Area(state.Size).Where(p => unit.X < 0 || state.CanMove(unit, p))) { state.MoveUnit(player, iUnit, pos); GetHashValue(state).Should().NotBe(oldHash); state.MoveUnit(player, iUnit, unit); GetHashValue(state).Should().Be(oldHash); } } } }