Project

General

Profile

Download (13.8 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / screens / RubikScreenSolver.java @ 8739593d

1 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6 3782bd44 Leszek Koltunski
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10 fcd5b990 Leszek Koltunski
package org.distorted.screens;
11 7289fd6c Leszek Koltunski
12 3f7a4363 Leszek Koltunski
import java.lang.ref.WeakReference;
13
14 7289fd6c Leszek Koltunski
import android.content.SharedPreferences;
15
import android.graphics.Bitmap;
16
import android.graphics.Canvas;
17
import android.graphics.Paint;
18 473611ee Leszek Koltunski
import android.graphics.PorterDuff;
19
import android.graphics.drawable.Drawable;
20 ca292407 Leszek Koltunski
import android.os.Bundle;
21 66e777b0 Leszek Koltunski
import androidx.core.content.ContextCompat;
22 7289fd6c Leszek Koltunski
import android.view.View;
23
import android.widget.ImageButton;
24
import android.widget.LinearLayout;
25
26 2afc6754 Leszek Koltunski
import org.distorted.objectlib.main.ObjectControl;
27 d8cf6f49 Leszek Koltunski
import org.distorted.objectlib.main.ObjectSignatures;
28 3f7a4363 Leszek Koltunski
import org.distorted.objectlib.main.TwistyObject;
29
30 ca292407 Leszek Koltunski
import org.distorted.dialogs.RubikDialogSolverError;
31 55e6be1d Leszek Koltunski
import org.distorted.helpers.TransparentImageButton;
32 1f9772f3 Leszek Koltunski
import org.distorted.main.R;
33
import org.distorted.main.RubikActivity;
34 d8cf6f49 Leszek Koltunski
import org.distorted.objectlib.shape.ShapeDiamond;
35
import org.distorted.objectlib.shape.ShapeDodecahedron;
36
import org.distorted.objectlib.shape.ShapeHexahedron;
37
import org.distorted.objectlib.shape.ShapeOctahedron;
38
import org.distorted.objectlib.shape.ShapeTetrahedron;
39 400ff34d Leszek Koltunski
import org.distorted.objects.RubikObjectList;
40 373fa45f Leszek Koltunski
import org.distorted.solvers.ImplementedSolversList;
41 a304ee64 Leszek Koltunski
import org.distorted.solvers.SolverMain;
42 7289fd6c Leszek Koltunski
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44
45 fcd5b990 Leszek Koltunski
public class RubikScreenSolver extends RubikScreenAbstract
46 7289fd6c Leszek Koltunski
  {
47 7a60305a Leszek Koltunski
  private static final int RESET_DURATION = 1000;
48
49 7289fd6c Leszek Koltunski
  private static Bitmap[] mBitmap;
50
  private ImageButton[] mColorButton;
51 7a60305a Leszek Koltunski
  private TransparentImageButton mResetButton,mBackButton, mSolveButton;
52 5660465b Leszek Koltunski
  private boolean mSolving;
53 1f9772f3 Leszek Koltunski
  private int mCurrentColor;
54 41748f19 Leszek Koltunski
  private int[] mFaceColors;
55 57dea1ac Leszek Koltunski
  private int mNumColors;
56 7ea57482 Leszek Koltunski
  private float mBitmapSize;
57 373fa45f Leszek Koltunski
  private WeakReference<RubikActivity> mWeakAct;
58
59 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
60
61 f5da732a Leszek Koltunski
  void leaveScreen(RubikActivity act)
62 7289fd6c Leszek Koltunski
    {
63 9523ae28 Leszek Koltunski
    ObjectControl control = act.getControl();
64
    control.unsetLock();
65 7289fd6c Leszek Koltunski
    }
66
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68
69 f5da732a Leszek Koltunski
  void enterScreen(final RubikActivity act)
70 7289fd6c Leszek Koltunski
    {
71 9523ae28 Leszek Koltunski
    ObjectControl control = act.getControl();
72
    control.setLock(false);
73
74 e3c74c0f Leszek Koltunski
    float width = act.getScreenWidthInPixels();
75 6d4d56cb Leszek Koltunski
    float heigh = act.getScreenHeightInPixels();
76 7ea57482 Leszek Koltunski
77 373fa45f Leszek Koltunski
    mWeakAct = new WeakReference<>(act);
78 5660465b Leszek Koltunski
    mSolving = false;
79
80 67d7fb28 Leszek Koltunski
    int solverIndex= act.getSolverIndex();
81
    ImplementedSolversList currentSolver = ImplementedSolversList.getSolver(solverIndex);
82
    int currentObject = currentSolver.getObject();
83 b20e89d2 Leszek Koltunski
    act.changeIfDifferent(currentObject,control);
84 33f6abfd Leszek Koltunski
    control.solveOnly();
85 1088a219 Leszek Koltunski
    RubikObjectList.setCurrObject(currentObject);
86 7289fd6c Leszek Koltunski
87 d8cf6f49 Leszek Koltunski
    generateFaceColors(currentObject);
88 20931cf6 Leszek Koltunski
89 57dea1ac Leszek Koltunski
    final float BUTTON_RATIO = 0.75f;
90
    int sizeV = (int)(heigh*RubikActivity.RATIO_BAR*BUTTON_RATIO);
91
    int sizeH = (int)((width/mNumColors)*BUTTON_RATIO);
92
    mBitmapSize = Math.min(sizeV,sizeH);
93
94 7289fd6c Leszek Koltunski
    // TOP ////////////////////////////
95
    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
96
    layoutTop.removeAllViews();
97
98 57dea1ac Leszek Koltunski
    if( mNumColors>0 )
99 41748f19 Leszek Koltunski
      {
100 7ebd72f7 Leszek Koltunski
      setupBitmaps();
101 ad0c8e0e Leszek Koltunski
      setupColorButtons(act,width);
102 41748f19 Leszek Koltunski
      markButton(act);
103
      }
104 473611ee Leszek Koltunski
105 7289fd6c Leszek Koltunski
    for(ImageButton button: mColorButton) layoutTop.addView(button);
106
107
    // BOT ////////////////////////////
108 57dea1ac Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1);
109
110
    LinearLayout layoutL = new LinearLayout(act);
111
    layoutL.setLayoutParams(params);
112
    LinearLayout layoutM = new LinearLayout(act);
113
    layoutM.setLayoutParams(params);
114
    LinearLayout layoutR = new LinearLayout(act);
115
    layoutR.setLayoutParams(params);
116
117 92843d3b Leszek Koltunski
    LinearLayout layoutBot = act.findViewById(R.id.lowerBar);
118
    layoutBot.removeAllViews();
119 264af0ad Leszek Koltunski
120 7a60305a Leszek Koltunski
    setupResetButton(act);
121 dd874ae8 Leszek Koltunski
    setupSolveButton(act);
122
    setupBackButton(act);
123 7289fd6c Leszek Koltunski
124 7a60305a Leszek Koltunski
    layoutL.addView(mResetButton);
125
    layoutM.addView(mSolveButton);
126 57dea1ac Leszek Koltunski
    layoutR.addView(mBackButton);
127 af133d41 Leszek Koltunski
128 57dea1ac Leszek Koltunski
    layoutBot.addView(layoutL);
129
    layoutBot.addView(layoutM);
130
    layoutBot.addView(layoutR);
131 7289fd6c Leszek Koltunski
    }
132
133 4ab3d91b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
134 d8cf6f49 Leszek Koltunski
// This doesn't quite work in many cases, but in case of the solvers that will pop up in foreseeable
135
// future it should be ok.
136 4ab3d91b Leszek Koltunski
137 d8cf6f49 Leszek Koltunski
  public void generateFaceColors(int object)
138 4ab3d91b Leszek Koltunski
    {
139 d8cf6f49 Leszek Koltunski
    if( object== ObjectSignatures.PYRA_3 ||
140
        object== ObjectSignatures.PYRA_4 ||
141
        object== ObjectSignatures.PYRA_5 ||
142
        object== ObjectSignatures.PDUO_2 ||
143
        object== ObjectSignatures.JING_2 ||
144
        object== ObjectSignatures.MORP_2 ||
145
        object== ObjectSignatures.MORP_3 ||
146
        object== ObjectSignatures.MORP_4  )
147
      {
148 57dea1ac Leszek Koltunski
      mNumColors  = ShapeTetrahedron.NUM_FACES;
149 d8cf6f49 Leszek Koltunski
      mFaceColors = ShapeTetrahedron.FACE_COLORS;
150
      }
151
    else if( object== ObjectSignatures.DIAM_2 ||
152
        object== ObjectSignatures.DIAM_3 ||
153
        object== ObjectSignatures.DIAM_4 ||
154
        object== ObjectSignatures.TRAJ_3 ||
155
        object== ObjectSignatures.TRAJ_4 ||
156
        object== ObjectSignatures.PDIA_3  )
157
      {
158 57dea1ac Leszek Koltunski
      mNumColors  = ShapeOctahedron.NUM_FACES;
159 d8cf6f49 Leszek Koltunski
      mFaceColors = ShapeOctahedron.FACE_COLORS;
160
      }
161
    else if( object== ObjectSignatures.CRYS_3 ||
162
        object== ObjectSignatures.STAR_3 ||
163
        object== ObjectSignatures.PENT_2 ||
164
        object== ObjectSignatures.KILO_3 ||
165
        object== ObjectSignatures.KILO_5 ||
166
        object== ObjectSignatures.MEGA_3 ||
167
        object== ObjectSignatures.MEGA_5  )
168
      {
169 57dea1ac Leszek Koltunski
      mNumColors  = ShapeDodecahedron.NUM_FACES;
170 d8cf6f49 Leszek Koltunski
      mFaceColors = ShapeDodecahedron.FACE_COLORS;
171
      }
172
    else if( object== ObjectSignatures.BALL_4 )
173
      {
174 57dea1ac Leszek Koltunski
      mNumColors  = ShapeDiamond.NUM_FACES;
175 d8cf6f49 Leszek Koltunski
      mFaceColors = ShapeDiamond.FACE_COLORS;
176
      }
177
    else
178
      {
179 57dea1ac Leszek Koltunski
      mNumColors  = ShapeHexahedron.NUM_FACES;
180 d8cf6f49 Leszek Koltunski
      mFaceColors = ShapeHexahedron.FACE_COLORS;
181
      }
182 4ab3d91b Leszek Koltunski
    }
183
184 5660465b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
185 7289fd6c Leszek Koltunski
186 7ebd72f7 Leszek Koltunski
  private void setupBitmaps()
187 7289fd6c Leszek Koltunski
    {
188 1bd07548 Leszek Koltunski
    final int SIZE = (int)mBitmapSize;
189
    final float R = SIZE*0.15f;
190
    final float M = SIZE*0.08f;
191 7289fd6c Leszek Koltunski
192 57dea1ac Leszek Koltunski
    mBitmap = new Bitmap[mNumColors];
193 7289fd6c Leszek Koltunski
194
    Paint paint = new Paint();
195
    paint.setColor(0xff008800);
196
    paint.setStyle(Paint.Style.FILL);
197
198
    paint.setAntiAlias(true);
199
    paint.setTextAlign(Paint.Align.CENTER);
200
    paint.setStyle(Paint.Style.FILL);
201
202 57dea1ac Leszek Koltunski
    for(int i=0; i<mNumColors; i++)
203 7289fd6c Leszek Koltunski
      {
204
      mBitmap[i] = Bitmap.createBitmap(SIZE, SIZE, Bitmap.Config.ARGB_8888);
205
      Canvas canvas = new Canvas(mBitmap[i]);
206
207
      paint.setColor(0xff000000);
208
      canvas.drawRect(0, 0, SIZE, SIZE, paint);
209
210 41748f19 Leszek Koltunski
      paint.setColor(mFaceColors[i]);
211 7289fd6c Leszek Koltunski
      canvas.drawRoundRect( M, M, SIZE-M, SIZE-M, R, R, paint);
212
      }
213
    }
214
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216
217 ad0c8e0e Leszek Koltunski
  private void setupColorButtons(final RubikActivity act, final float width)
218 7289fd6c Leszek Koltunski
    {
219 57dea1ac Leszek Koltunski
    mColorButton = new ImageButton[mNumColors];
220 ad0c8e0e Leszek Koltunski
    int padding = (int)(width*RubikActivity.PADDING);
221 c651024f Leszek Koltunski
    int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
222 7289fd6c Leszek Koltunski
223 57dea1ac Leszek Koltunski
    for(int i=0; i<mNumColors; i++)
224 7289fd6c Leszek Koltunski
      {
225
      final int ii = i;
226 ad0c8e0e Leszek Koltunski
      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
227
      params.topMargin    = margin;
228
      params.bottomMargin = margin;
229
      params.leftMargin   = margin;
230
      params.rightMargin  = margin;
231
232 7289fd6c Leszek Koltunski
      mColorButton[i] = new ImageButton(act);
233 ad0c8e0e Leszek Koltunski
      mColorButton[i].setLayoutParams(params);
234 7289fd6c Leszek Koltunski
      mColorButton[i].setPadding(padding,0,padding,0);
235
      mColorButton[i].setImageBitmap(mBitmap[i]);
236
237
      mColorButton[i].setOnClickListener( new View.OnClickListener()
238
        {
239
        @Override
240
        public void onClick(View view)
241
          {
242 473611ee Leszek Koltunski
          mCurrentColor = ii;
243
          markButton(act);
244 7289fd6c Leszek Koltunski
          }
245
        });
246
      }
247
    }
248
249 7a60305a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
250
251
  private void setupResetButton(final RubikActivity act)
252
    {
253
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_reset,R.drawable.ui_medium_reset, R.drawable.ui_big_reset, R.drawable.ui_huge_reset);
254
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
255
    mResetButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
256
257
    mResetButton.setOnClickListener( new View.OnClickListener()
258
      {
259
      @Override
260
      public void onClick(View v)
261
        {
262
        ObjectControl control = act.getControl();
263
        control.resetTextureMapsEffect(RESET_DURATION);
264
        }
265
      });
266
    }
267
268 264af0ad Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
269
270 dd874ae8 Leszek Koltunski
  private void setupSolveButton(final RubikActivity act)
271 264af0ad Leszek Koltunski
    {
272 23ac2462 Leszek Koltunski
    final int icon = RubikActivity.getDrawable(R.drawable.ui_small_solve,R.drawable.ui_medium_solve, R.drawable.ui_big_solve, R.drawable.ui_huge_solve);
273 b600ccd9 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
274
    mSolveButton = new TransparentImageButton(act,icon,TransparentImageButton.GRAVITY_MIDDLE,params);
275 264af0ad Leszek Koltunski
276
    mSolveButton.setOnClickListener( new View.OnClickListener()
277
      {
278
      @Override
279
      public void onClick(View v)
280
        {
281 5660465b Leszek Koltunski
        if( !mSolving )
282
          {
283
          mSolving = true;
284 9c2f0c91 Leszek Koltunski
          TwistyObject object = act.getObject();
285 ecf3f149 Leszek Koltunski
          SolverMain solver = new SolverMain( act.getResources(), object );
286 f0336037 Leszek Koltunski
          solver.start();
287 5660465b Leszek Koltunski
          }
288 264af0ad Leszek Koltunski
        }
289
      });
290
    }
291
292 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
293
294 dd874ae8 Leszek Koltunski
  private void setupBackButton(final RubikActivity act)
295 7289fd6c Leszek Koltunski
    {
296 4fb1fc0d Leszek Koltunski
    final int icon = RubikActivity.getDrawable(R.drawable.ui_small_back,R.drawable.ui_medium_back, R.drawable.ui_big_back, R.drawable.ui_huge_back);
297 b600ccd9 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
298
    mBackButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
299 7289fd6c Leszek Koltunski
300
    mBackButton.setOnClickListener( new View.OnClickListener()
301
      {
302
      @Override
303
      public void onClick(View v)
304
        {
305 2afc6754 Leszek Koltunski
        ObjectControl control = act.getControl();
306
        control.resetAllTextureMaps();
307 fcd5b990 Leszek Koltunski
        ScreenList.goBack(act);
308 7289fd6c Leszek Koltunski
        }
309
      });
310
    }
311
312 473611ee Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
313
314
  private void markButton(RubikActivity act)
315
    {
316 57dea1ac Leszek Koltunski
    for(int b=0; b<mNumColors; b++)
317 473611ee Leszek Koltunski
      {
318
      Drawable d = mColorButton[b].getBackground();
319
320
      if( b==mCurrentColor )
321
        {
322
        d.setColorFilter(ContextCompat.getColor(act,R.color.red), PorterDuff.Mode.MULTIPLY);
323
        }
324
      else
325
        {
326
        d.clearColorFilter();
327
        }
328
      }
329
    }
330
331 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
332
333
  public void savePreferences(SharedPreferences.Editor editor)
334
    {
335 1f9772f3 Leszek Koltunski
    editor.putInt("stateSolver_color", mCurrentColor);
336 7289fd6c Leszek Koltunski
    }
337
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339
340
  public void restorePreferences(SharedPreferences preferences)
341
    {
342 1f9772f3 Leszek Koltunski
    mCurrentColor = preferences.getInt("stateSolver_color", 0);
343 7289fd6c Leszek Koltunski
    }
344 473611ee Leszek Koltunski
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346
347
  public int getCurrentColor()
348
    {
349
    return mCurrentColor;
350
    }
351 f0336037 Leszek Koltunski
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353
354 373fa45f Leszek Koltunski
  public void setSolved(final String moves)
355 f0336037 Leszek Koltunski
    {
356
    mSolving = false;
357 373fa45f Leszek Koltunski
    final RubikActivity act = mWeakAct.get();
358 f0336037 Leszek Koltunski
359 373fa45f Leszek Koltunski
    if( act!=null )
360 f0336037 Leszek Koltunski
      {
361 373fa45f Leszek Koltunski
      act.runOnUiThread(new Runnable()
362 f0336037 Leszek Koltunski
        {
363 373fa45f Leszek Koltunski
        @Override
364
        public void run()
365
          {
366 f5da732a Leszek Koltunski
          ScreenList.switchScreen(act, ScreenList.SOLU);
367
          RubikScreenSolution solution = (RubikScreenSolution) ScreenList.SOLU.getScreenClass();
368 373fa45f Leszek Koltunski
          solution.setupMoves(act, moves);
369
          }
370
        });
371
      }
372 f0336037 Leszek Koltunski
    }
373
374 277401c0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
375
376
  public void setSolved(final int[][] moves)
377
    {
378
    mSolving = false;
379
    final RubikActivity act = mWeakAct.get();
380
381
    if( act!=null )
382
      {
383
      act.runOnUiThread(new Runnable()
384
        {
385
        @Override
386
        public void run()
387
          {
388
          ScreenList.switchScreen(act, ScreenList.SOLU);
389
          RubikScreenSolution solution = (RubikScreenSolution) ScreenList.SOLU.getScreenClass();
390
          solution.setupMoves(act, moves);
391
          }
392
        });
393
      }
394
    }
395
396 f0336037 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
397
398 c02fa107 Leszek Koltunski
  public void displayErrorDialog(String message)
399 f0336037 Leszek Koltunski
    {
400
    mSolving = false;
401 373fa45f Leszek Koltunski
    RubikActivity act = mWeakAct.get();
402 f0336037 Leszek Koltunski
403 373fa45f Leszek Koltunski
    if( act!=null )
404
      {
405
      RubikDialogSolverError dialog = new RubikDialogSolverError();
406
      Bundle bundle = new Bundle();
407 c02fa107 Leszek Koltunski
      bundle.putString("argument", message );
408 373fa45f Leszek Koltunski
      dialog.setArguments(bundle);
409
      dialog.show( act.getSupportFragmentManager(), null);
410
      }
411 f0336037 Leszek Koltunski
    }
412 7289fd6c Leszek Koltunski
  }