Project

General

Profile

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

magiccube / src / main / java / org / distorted / screens / RubikScreenSolver.java @ 379b3273

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