Project

General

Profile

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

magiccube / src / main / java / org / distorted / states / RubikStateSolver.java @ e3c74c0f

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.states;
21

    
22
import android.content.SharedPreferences;
23
import android.graphics.Bitmap;
24
import android.graphics.Canvas;
25
import android.graphics.Paint;
26
import android.graphics.PorterDuff;
27
import android.graphics.drawable.Drawable;
28
import android.os.Bundle;
29
import androidx.core.content.ContextCompat;
30
import android.util.DisplayMetrics;
31
import android.util.TypedValue;
32
import android.view.View;
33
import android.widget.Button;
34
import android.widget.ImageButton;
35
import android.widget.LinearLayout;
36

    
37
import org.distorted.dialogs.RubikDialogSolverError;
38
import org.distorted.main.R;
39
import org.distorted.main.RubikActivity;
40
import org.distorted.main.RubikPreRender;
41
import org.distorted.objects.RubikObject;
42
import org.distorted.objects.RubikObjectList;
43
import org.distorted.solvers.ImplementedSolversList;
44
import org.distorted.solvers.SolverMain;
45

    
46
import java.lang.ref.WeakReference;
47

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

    
50
public class RubikStateSolver extends RubikStateAbstract
51
  {
52
  private static final int BITMAP_SIZE = 35;
53

    
54
  private static Bitmap[] mBitmap;
55
  private ImageButton[] mColorButton;
56
  private Button mBackButton, mSolveButton;
57
  private boolean mSolving;
58
  private int mCurrentColor;
59
  private int[] mFaceColors;
60
  private int mNumFaces;
61
  private float mTitleSize, mButtonSize;
62

    
63
  private RubikObjectList mCurrentObject;
64
  private int mCurrentObjectSize;
65

    
66
  private WeakReference<RubikActivity> mWeakAct;
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  void leaveState(RubikActivity act)
71
    {
72

    
73
    }
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
  void enterState(final RubikActivity act)
78
    {
79
    float width = act.getScreenWidthInPixels();
80
    mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
81
    mTitleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
82

    
83
    mWeakAct = new WeakReference<>(act);
84

    
85
    mSolving = false;
86

    
87
    mCurrentObject     = ImplementedSolversList.getObject(0);
88
    mCurrentObjectSize = ImplementedSolversList.getObjectSize(0);
89

    
90
    act.setupObject(mCurrentObject, mCurrentObjectSize, null);
91
    RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
92
    play.setObjectAndSize(act, mCurrentObject, mCurrentObjectSize);
93

    
94
    mFaceColors = RubikObjectList.retFaceColors(mCurrentObject);
95
    mNumFaces   = mFaceColors!=null ? mFaceColors.length : 0;
96

    
97
    DisplayMetrics metrics = act.getResources().getDisplayMetrics();
98
    final float scale = metrics.density;
99

    
100
    // TOP ////////////////////////////
101
    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
102
    layoutTop.removeAllViews();
103

    
104
    if( mNumFaces>0 )
105
      {
106
      setupBitmaps(scale);
107
      setupColorButtons(act,scale);
108

    
109
      markButton(act);
110
      }
111

    
112
    for(ImageButton button: mColorButton) layoutTop.addView(button);
113

    
114
    // BOT ////////////////////////////
115
    setupSolveButton(act,scale);
116

    
117
    LinearLayout layoutLeft = act.findViewById(R.id.mainBarLeft);
118
    layoutLeft.removeAllViews();
119
    layoutLeft.addView(mSolveButton);
120

    
121
    setupBackButton(act,scale);
122

    
123
    LinearLayout layoutRight = act.findViewById(R.id.mainBarRight);
124
    layoutRight.removeAllViews();
125
    layoutRight.addView(mBackButton);
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  private void setupBitmaps(float scale)
131
    {
132
    final int SIZE = (int)(scale*BITMAP_SIZE);
133
    final float R = SIZE*0.10f;
134
    final float M = SIZE*0.05f;
135

    
136
    mBitmap = new Bitmap[mNumFaces];
137

    
138
    Paint paint = new Paint();
139
    paint.setColor(0xff008800);
140
    paint.setStyle(Paint.Style.FILL);
141

    
142
    paint.setAntiAlias(true);
143
    paint.setTextAlign(Paint.Align.CENTER);
144
    paint.setStyle(Paint.Style.FILL);
145

    
146
    for(int i=0; i<mNumFaces; i++)
147
      {
148
      mBitmap[i] = Bitmap.createBitmap(SIZE, SIZE, Bitmap.Config.ARGB_8888);
149
      Canvas canvas = new Canvas(mBitmap[i]);
150

    
151
      paint.setColor(0xff000000);
152
      canvas.drawRect(0, 0, SIZE, SIZE, paint);
153

    
154
      paint.setColor(mFaceColors[i]);
155
      canvas.drawRoundRect( M, M, SIZE-M, SIZE-M, R, R, paint);
156
      }
157
    }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
  private void setupColorButtons(final RubikActivity act, final float scale)
162
    {
163
    mColorButton = new ImageButton[mNumFaces];
164

    
165
    for(int i=0; i<mNumFaces; i++)
166
      {
167
      final int ii = i;
168
      int padding = (int)(3*scale + 0.5f);
169
      LinearLayout.LayoutParams objectParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
170
      mColorButton[i] = new ImageButton(act);
171
      mColorButton[i].setLayoutParams(objectParams);
172
      mColorButton[i].setPadding(padding,0,padding,0);
173
      mColorButton[i].setImageBitmap(mBitmap[i]);
174

    
175
      mColorButton[i].setOnClickListener( new View.OnClickListener()
176
        {
177
        @Override
178
        public void onClick(View view)
179
          {
180
          mCurrentColor = ii;
181
          markButton(act);
182
          }
183
        });
184
      }
185
    }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
  private void setupSolveButton(final RubikActivity act, final float scale)
190
    {
191
    int padding = (int)(3*scale + 0.5f);
192
    LinearLayout.LayoutParams backParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
193
    mSolveButton = new Button(act);
194
    mSolveButton.setLayoutParams(backParams);
195
    mSolveButton.setPadding(padding,0,padding,0);
196
    mSolveButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
197
    mSolveButton.setText(R.string.solve);
198

    
199
    mSolveButton.setOnClickListener( new View.OnClickListener()
200
      {
201
      @Override
202
      public void onClick(View v)
203
        {
204
        if( !mSolving )
205
          {
206
          mSolving = true;
207
          RubikObject object = act.getObject();
208
          String objectString = object.retObjectString();
209
          SolverMain solver = new SolverMain( act.getResources(), mCurrentObject, mCurrentObjectSize, objectString );
210
          solver.start();
211
          }
212
        }
213
      });
214
    }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

    
218
  private void setupBackButton(final RubikActivity act, final float scale)
219
    {
220
    int padding = (int)(3*scale + 0.5f);
221
    LinearLayout.LayoutParams backParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
222
    mBackButton = new Button(act);
223
    mBackButton.setLayoutParams(backParams);
224
    mBackButton.setPadding(padding,0,padding,0);
225
    mBackButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
226
    mBackButton.setText(R.string.back);
227

    
228
    mBackButton.setOnClickListener( new View.OnClickListener()
229
      {
230
      @Override
231
      public void onClick(View v)
232
        {
233
        RubikPreRender pre = act.getPreRender();
234
        pre.resetAllTextureMaps();
235
        RubikState.goBack(act);
236
        }
237
      });
238
    }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

    
242
  private void markButton(RubikActivity act)
243
    {
244
    for(int b=0; b<mNumFaces; b++)
245
      {
246
      Drawable d = mColorButton[b].getBackground();
247

    
248
      if( b==mCurrentColor )
249
        {
250
        d.setColorFilter(ContextCompat.getColor(act,R.color.red), PorterDuff.Mode.MULTIPLY);
251
        }
252
      else
253
        {
254
        d.clearColorFilter();
255
        }
256
      }
257
    }
258

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

    
261
  public void savePreferences(SharedPreferences.Editor editor)
262
    {
263
    editor.putInt("stateSolver_color", mCurrentColor);
264
    }
265

    
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267

    
268
  public void restorePreferences(SharedPreferences preferences)
269
    {
270
    mCurrentColor = preferences.getInt("stateSolver_color", 0);
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
  public int getCurrentColor()
276
    {
277
    return mCurrentColor;
278
    }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  public void setSolved(final String moves)
283
    {
284
    mSolving = false;
285
    final RubikActivity act = mWeakAct.get();
286

    
287
    if( act!=null )
288
      {
289
      act.runOnUiThread(new Runnable()
290
        {
291
        @Override
292
        public void run()
293
          {
294
          RubikState.switchState(act,RubikState.SOLU);
295
          RubikStateSolution solution = (RubikStateSolution) RubikState.SOLU.getStateClass();
296
          solution.setupMoves(act, moves);
297
          }
298
        });
299
      }
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  public void displayErrorDialog( String message)
305
    {
306
    mSolving = false;
307
    RubikActivity act = mWeakAct.get();
308

    
309
    if( act!=null )
310
      {
311
      RubikDialogSolverError dialog = new RubikDialogSolverError();
312
      Bundle bundle = new Bundle();
313
      bundle.putString("error", message );
314
      dialog.setArguments(bundle);
315
      dialog.show( act.getSupportFragmentManager(), null);
316
      }
317
    }
318
  }
(9-9/10)