Exemple #1
0
    static bool CheckDeadlock(TopLeftTodo topLeftTodo, SokowahnField view, ushort playerTopLeft)
    {
      HashSet<ulong> bHash;
      int boxesCount = topLeftTodo.state.Length - 1;
      if (boxesHash.TryGetValue(boxesCount, out bHash))
      {
        ulong crc = Crc64.Start.Crc64Update(playerTopLeft).Crc64Update(topLeftTodo.state, 1, boxesCount);
        if (!bHash.Contains(crc))
        {
          return true;
        }
      }
      else
      {
        // --- schnelle Vorprüfung ---
        for (int b = 1; b < topLeftTodo.state.Length; b++)
        {
          if (invalidBoxes.Contains(topLeftTodo.state[b])) return true;
        }

        // --- bestmögliche Hashprüfung ---
        int boxesCountMin = boxesHash.Count;
        bHash = boxesHash[boxesCountMin];
        var checkBoxes = topLeftTodo.state.Skip(1).Where(b => b != topLeftTodo.lastBox).ToArray();
        var checkState = new ushort[1 + boxesCountMin];
        checkState[0] = playerTopLeft;
        foreach (var variant in SokoTools.FieldBoxesVariantsStatic(checkBoxes.Length, boxesCountMin - 1))
        {
          for (int v = 0; v < variant.Length; v++) checkState[v + 1] = checkBoxes[variant[v]];
          AppendBoxes(checkState, topLeftTodo.lastBox);
          view.SetGameState(checkState);
          view.SetPlayerTopLeft();
          ulong crc = view.GetGameStateCrc();
          if (!bHash.Contains(crc))
          {
            return true;
          }
        }
      }
      return false;
    }
Exemple #2
0
    static ushort[] TestScan(int width, TopLeftTodo topLeftTodo, HashSet<ushort> ways, SokowahnField view, bool debug = true)
    {
      var state = topLeftTodo.state;
      view.SetGameState(state);

      var result = ScanBestTopLeftWay(state[0], width, ways, new HashSet<ushort>(state.Skip(1)));

      if (state.Length > 1 && CheckDeadlock(topLeftTodo, view, result[result.Count - 1])) return null;

      if (debug)
      {
        Console.SetCursorPosition(0, Math.Max(0, Console.CursorTop - 2));
        Console.WriteLine(new string(' ', Console.WindowWidth - 1));

        Console.SetCursorPosition(0, 1);
        Console.WriteLine(view.ToString());
        Console.WriteLine();

        string line = state[0] + " - " + string.Join(", ", result.Skip(1));
        Console.WriteLine(line);
        Console.WriteLine();
      }

      var known = new HashSet<ushort>(topLeftTodo.known);

      if (known.Contains(result[result.Count - 1])) return new[] { result[result.Count - 1] };

      var resultFiltered = result.Where(f => !known.Contains(f)).ToArray();

      return resultFiltered;
    }