Итак, я создаю приложение для лабиринта (я читаю из массива строк в лабиринте, а после этого с сенсорными событиями направляет мяч через него). Удалось создать все до сих пор, приложение работает отлично. Но я хочу включить опцию для ее решения автоматически.Автоматическое решение лабиринта
Я использую этот рекурсивный алгоритм найден здесь: https://en.wikipedia.org/wiki/Maze_solving_algorithm
В основном я получаю путь в булевом многомерном массиве (то есть размер лабиринта).
Пытался достичь MWC, как дизайн, так что у меня есть следующие классы:
LabyrinthView - ручки все, что связанно с рисованием лабиринта, и рисования мяча LabyrinthModel - инициализировать лабиринт, ручки движения мяча, и я проверьте здесь конец лабиринта и реализовали рекурсивную серию здесь, чтобы LabyrinthActivity - вот где я собираю все вместе
Как я уже говорил, решение лабиринта вручную работает как шарм. Не знаю, как анимировать автоматическое решение. Итак, позвольте мне дать вам лабиринте пример:
<string-array name="labyrinthEasy">
<item>0000000001</item>
<item>0111110110</item>
<item>0100000110</item>
<item>0101111000</item>
<item>0101000010</item>
<item>0101011010</item>
<item>0101011110</item>
<item>0101000010</item>
<item>0101111010</item>
<item>0100000010</item>
<item>0111111110</item>
<item>1000000000</item>
</string-array>
Это будет выглядеть примерно так (E-Entry, F-финиш):
И решение:
Вот как далеко я добрался:
private void selectControlMode() {
final CharSequence[] items = {"Human","Machine"};
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
dialog.dismiss();
break;
case 1:
dialog.dismiss();
boolean temp;
temp = labyrinthModel.solveMaze();
if(temp){
new MazeSolver().execute();
}else{
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setMessage("The maze is unsolvable!");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
dialog.dismiss();
Intent intent1 = new Intent(LabyrinthActivity.this, MainActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent1);
break;
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
break;
}
}
});
}
В основном я выбираю между человеческим и машинным решением из диалога. Если выбран человек, выберите диалог и ничего (приложение продолжает и ждет ручного решения). Если машина выбрана, я получаю путь, и если она может быть решена, я думаю, что я должен начать новую тему здесь, где я могу анимировать автоматическое решение, иначе, если ее не решить, я вернусь в главное меню приложения. Теперь здесь возникает моя проблема, так как я действительно не знаю, как реализовать это в моем классе AsyncTask.
Я делаю логику в методе doInBackgroung, но не могу понять логику, как следовать правильному пути. Потому что, если я повторяю по массиву по строкам, шарик перескакивает из строки в строку и не будет следовать текучести пути. Также я думаю, что после каждой итерации я должен перерисовать свой прогресс, используя метод onProgressUpdate.
Это как моя ручная логика работы (движение и рисунок):
labyrinthView.setOnTouchListener(new View.OnTouchListener() {
float x1 = 0, x2 = 0, y1 = 0, y2 = 0;
float dx, dy;
@Override
public boolean onTouch(View v, MotionEvent event) {
float MIN_DIST = 5;
switch (event.getAction()){
case (MotionEvent.ACTION_DOWN):
x1 = event.getX();
y1 = event.getY();
break;
case (MotionEvent.ACTION_UP):
x2 = event.getX();
y2 = event.getY();
dx = x2-x1;
dy = y2-y1;
Log.v("log", dx + " " + dy);
if(Math.abs(dx) > MIN_DIST || Math.abs(dy) > MIN_DIST){
if (Math.abs(dx) > Math.abs(dy)){
if(dx > 0) {
labyrinthModel.right();
finishMessage();
}
else {
labyrinthModel.left();
finishMessage();
}
}else{
if(dy > 0) {
labyrinthModel.down();
finishMessage();
}
else {
labyrinthModel.up();
finishMessage();
}
}
}
break;
}
labyrinthView.invalidate();
return true;
}
});
И это то, что я сделал до сих пор в моей assync задачи:
private class MazeSolver extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... params) {
for (int row = 0; row < labyrinthModel.correctPath.length; row ++)
for (int col = 0; col < labyrinthModel.correctPath[0].length; col++){
if(labyrinthModel.correctPath[row][col + 1]){
labyrinthModel.moveRight();
}
//here to do the implementaion of the path following logic???
}
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
// here to redraw the progress ????
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
Если вы можете указать мне в правильном направлении я был бы очень благодарен.