Project

General

Profile

Download (12.6 KB) Statistics
| Branch: | Revision:

phasedsolver / src / main / java / org / distorted / phasedsolver / SolverLowerPane.java @ d78e2f1d

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2024 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// 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
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.phasedsolver;
11

    
12
import android.widget.TextView;
13

    
14
import org.distorted.library.effect.PostprocessEffectGlow;
15
import org.distorted.library.main.DistortedEffects;
16
import org.distorted.library.mesh.MeshBase;
17
import org.distorted.library.message.EffectListener;
18
import org.distorted.library.type.Dynamic2D;
19
import org.distorted.library.type.Dynamic4D;
20
import org.distorted.library.type.Static2D;
21
import org.distorted.library.type.Static4D;
22
import org.distorted.objectlib.helpers.MovesFinished;
23
import org.distorted.objectlib.main.ObjectControl;
24
import org.distorted.objectlib.main.TwistyObject;
25

    
26
import java.lang.ref.WeakReference;
27

    
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29

    
30
public class SolverLowerPane implements MovesFinished, EffectListener
31
{
32
  private static final int MOVES_PLACE_0 = 100;
33
  private static final int MOVES_PLACE_1 = 101;
34
  private static final int MILLIS_PER_DEGREE = 6;
35
  private static final int FLASH_TIME = 1200;
36

    
37
  private final TextView mText, mPhase;
38
  private String[] mPhaseNames;
39
  private int mNumPhases;
40
  private int[][][] mMoves;
41
  private int[][] mCubitsNotInvolved;
42
  private int mNumMoves,mCurrMove,mCurrPhase;
43
  private boolean mCanMove;
44

    
45
  private final Dynamic2D mHaloAndRadiusDyn;
46
  private final Dynamic4D mColorDyn;
47
  private final PostprocessEffectGlow mGlow;
48
  private final WeakReference<SolverActivity> mAct;
49
  private boolean mEffectWorking;
50

    
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

    
53
  SolverLowerPane(SolverActivity act, String[] names)
54
    {
55
    mAct = new WeakReference<>(act);
56

    
57
    mText  = act.findViewById(R.id.solverText);
58
    mPhase = act.findViewById(R.id.solverPhaseName);
59

    
60
    mHaloAndRadiusDyn = new Dynamic2D(FLASH_TIME,1.0f);
61
    mHaloAndRadiusDyn.add(new Static2D( 0,0));
62
    mHaloAndRadiusDyn.add(new Static2D(10,5));
63

    
64
    mColorDyn = new Dynamic4D(FLASH_TIME,1.0f);
65

    
66
    final int[] colors  = new int[] {1,1,1}; // white
67

    
68
    Static4D P1 = new Static4D(colors[0],colors[1],colors[2], 0.0f);
69
    Static4D P2 = new Static4D(colors[0],colors[1],colors[2], 1.0f);
70
    mColorDyn.add(P1);
71
    mColorDyn.add(P2);
72

    
73
    mGlow = new PostprocessEffectGlow(mHaloAndRadiusDyn,mColorDyn);
74

    
75
    mPhaseNames = names;
76
    mNumPhases = names.length;
77
    mMoves = new int[mNumPhases][][];
78
    mCubitsNotInvolved = new int[mNumPhases][];
79
    mCanMove = true;
80
    setSolution(null,0,null);
81
    }
82

    
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

    
85
  void updateNames(String[] names)
86
    {
87
    mPhaseNames = names;
88
    mNumPhases = names.length;
89
    mMoves = new int[mNumPhases][][];
90
    mCubitsNotInvolved = new int[mNumPhases][];
91
    mCanMove = true;
92
    setSolution(null,0,null);
93
    }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
  void backPhase()
98
    {
99
    SolverActivity act = mAct.get();
100
    ObjectControl control = act.getControl();
101

    
102
    if( mCurrMove>0 )
103
      {
104
      int[][] moves = transformMoves(mMoves[mCurrPhase],0,mCurrMove, false);
105
      control.applyScrambles(moves);
106
      mCurrMove = 0;
107
      }
108
    else if( mCurrPhase>0 )
109
      {
110
      mCurrPhase--;
111
      mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
112
      mCurrMove = 0;
113
      int[][] moves = transformMoves(mMoves[mCurrPhase],0,mNumMoves, false);
114
      control.applyScrambles(moves);
115
      }
116
    else
117
      {
118
      mCurrPhase = mNumPhases-1;
119
      mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
120
      mCurrMove = mNumMoves;
121
      int[][] moves = transformMoves(mMoves, true);
122
      control.applyScrambles(moves);
123
      }
124

    
125
    setText(act);
126
    }
127

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

    
130
  void nextPhase()
131
    {
132
    SolverActivity act = mAct.get();
133
    ObjectControl control = act.getControl();
134

    
135
    if( mCurrPhase<mNumPhases-1 )
136
      {
137
      glowCubits(mCubitsNotInvolved[mCurrPhase]);
138
      int[][] moves = transformMoves(mMoves[mCurrPhase],mCurrMove,mNumMoves, true);
139
      control.applyScrambles(moves);
140
      mCurrPhase++;
141
      mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
142
      mCurrMove = 0;
143
      }
144
    else if( mCurrMove<mNumMoves )
145
      {
146
      glowCubits(mCubitsNotInvolved[mCurrPhase]);
147
      int[][] moves = transformMoves(mMoves[mCurrPhase],mCurrMove,mNumMoves, true);
148
      control.applyScrambles(moves);
149
      mCurrMove = mNumMoves;
150
      }
151
    else
152
      {
153
      mCurrPhase = 0;
154
      mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
155
      mCurrMove = 0;
156
      int[][] moves = transformMoves(mMoves, false);
157
      control.applyScrambles(moves);
158
      }
159

    
160
    setText(act);
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  private void setText(SolverActivity act)
166
    {
167
    int currMove = 0;
168
    int totalMove = 0;
169

    
170
    if( mMoves!=null )
171
      {
172
      currMove = mCurrMove;
173
      for(int p=0; p<mCurrPhase; p++) currMove  += (mMoves[p]==null ? 0: mMoves[p].length);
174
      for(int p=0; p<mNumPhases; p++) totalMove += (mMoves[p]==null ? 0: mMoves[p].length);
175
      }
176

    
177
    final int cMove = currMove;
178
    final int tMove = totalMove;
179

    
180
    act.runOnUiThread(new Runnable()
181
      {
182
      @Override
183
      public void run()
184
        {
185
        mPhase.setText(mPhaseNames[mCurrPhase]+" "+mCurrMove+"/"+mNumMoves);
186
        mText.setText(cMove+"/"+tMove);
187
        }
188
      });
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  private int[][] transformMoves(int[][] moves, int start, int end, boolean front)
194
    {
195
    int mult = front ? 1:-1;
196
    int len = end-start;
197
    int[][] ret = new int[len][];
198

    
199
    for(int m=0; m<len; m++)
200
      {
201
      int[] mv = moves[front ? start+m : end-1-m];
202
      int[] rt = new int[3];
203
      rt[0] = mv[0];
204
      rt[1] = (1<<mv[1]);
205
      rt[2] = mult*mv[2];
206
      ret[m] = rt;
207
      }
208

    
209
    return ret;
210
    }
211

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

    
214
  private int[][] transformMoves(int[][][] moves, boolean front)
215
    {
216
    int len = moves.length;
217
    int totalLen = 0;
218
    for (int[][] move : moves) totalLen += (move==null ? 0 : move.length);
219

    
220
    int[][] ret = new int[totalLen][];
221
    int mult = front ? 1:-1;
222
    int index = 0;
223

    
224
    for(int m=0; m<len; m++)
225
      {
226
      int[][] mv = moves[front ? m : len-1-m];
227
      int l = (mv==null ? 0 : mv.length);
228

    
229
      for(int p=0; p<l; p++)
230
        {
231
        int[] mve = mv[front ? p : l-1-p];
232
        int[] rt = new int[3];
233
        rt[0] = mve[0];
234
        rt[1] = (1<<mve[1]);
235
        rt[2] = mult*mve[2];
236
        ret[index++] = rt;
237
        }
238
      }
239

    
240
    return ret;
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  private void glowCubits(int[] cubits)
246
    {
247
    if( !mEffectWorking )
248
      {
249
      mEffectWorking = true;
250
      SolverActivity act=mAct.get();
251
      ObjectControl control = act.getControl();
252
      TwistyObject object=control.getObject();
253
      DistortedEffects effects=object.getObjectEffects();
254
      effects.apply(mGlow);
255

    
256
      MeshBase mesh=object.getObjectMesh();
257
      mesh.setComponentsNotAffectedByPostprocessing(cubits);
258

    
259
      mHaloAndRadiusDyn.resetToBeginning();
260
      mColorDyn.resetToBeginning();
261
      mGlow.notifyWhenFinished(this);
262
      }
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

    
267
  public void effectFinished(long id)
268
    {
269
    SolverActivity act=mAct.get();
270
    ObjectControl control = act.getControl();
271
    TwistyObject object=control.getObject();
272
    DistortedEffects effects=object.getObjectEffects();
273
    effects.abortById(id);
274

    
275
    mEffectWorking = false;
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  private int[] computeCubitsNotInvolved(int[][] subphases, int numCubits)
281
    {
282
    int numCubitsInvolved = 0;
283
    boolean[] involved = new boolean[numCubits];
284

    
285
    for(int[] sub : subphases)
286
      if( sub!=null )
287
        for(int s : sub)
288
          {
289
          numCubitsInvolved++;
290
          involved[s] = true;
291
          }
292

    
293
    int[] ret = new int[numCubits-numCubitsInvolved];
294
    int index = 0;
295

    
296
    for(int c=0; c<numCubits; c++)
297
      if( !involved[c] ) ret[index++] = c;
298

    
299
    return ret;
300
    }
301

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

    
304
  void setSolution(int[][] moves, int phase, int[][] subphases)
305
    {
306
    SolverActivity act=mAct.get();
307

    
308
    if( subphases!=null )
309
      {
310
      ObjectControl control=act.getControl();
311
      TwistyObject object=control.getObject();
312
      int numCubits=object.getNumCubits();
313
      mCubitsNotInvolved[phase]= computeCubitsNotInvolved(subphases, numCubits);
314
      }
315

    
316
    mMoves[phase] = moves;
317
    if( phase==0 ) mNumMoves = (moves==null ? 0 : moves.length);
318
    mCurrPhase = 0;
319
    mCurrMove = 0;
320

    
321
    setText(act);
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
  void clearMoves()
327
    {
328
    for(int p=0; p<mNumPhases; p++) mMoves[p] = null;
329
    mNumMoves = 0;
330
    mCurrPhase= 0;
331
    mCurrMove = 0;
332

    
333
    setText(mAct.get());
334
    }
335

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
  void backMove()
339
    {
340
    if( mMoves!=null && mCanMove )
341
      {
342
      SolverActivity act=mAct.get();
343

    
344
      if( mCurrMove>0 )
345
        {
346
        mCanMove = false;
347
        int[] move = mMoves[mCurrPhase][--mCurrMove];
348
        ObjectControl control = act.getControl();
349
        control.blockTouch(MOVES_PLACE_0);
350
        control.addRotation(this, move[0], (1<<move[1]), -move[2], MILLIS_PER_DEGREE);
351
        }
352
      else if( mCurrPhase>0 )
353
        {
354
        mCurrPhase--;
355
        mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
356
        mCurrMove = mNumMoves;
357
        glowCubits(mCubitsNotInvolved[mCurrPhase]);
358
        }
359
      else
360
        {
361
        mCurrPhase = mNumPhases-1;
362
        mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
363
        mCurrMove = mNumMoves;
364
        int[][] moves = transformMoves(mMoves, true);
365
        ObjectControl control = act.getControl();
366
        control.applyScrambles(moves);
367
        glowCubits(mCubitsNotInvolved[mCurrPhase]);
368
        }
369

    
370
      setText(act);
371
      }
372
    }
373

    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

    
376
  void nextMove()
377
    {
378
    if( mMoves!=null && mCanMove )
379
      {
380
      SolverActivity act=mAct.get();
381

    
382
      if( mCurrMove<mNumMoves )
383
        {
384
        mCanMove = false;
385
        int[] move = mMoves[mCurrPhase][mCurrMove++];
386
        ObjectControl control = act.getControl();
387
        control.blockTouch(MOVES_PLACE_1);
388
        control.addRotation(this, move[0], (1<<move[1]), move[2], MILLIS_PER_DEGREE);
389
        if( mCurrMove==mNumMoves && mCurrPhase==mNumPhases-1 ) glowCubits(mCubitsNotInvolved[mCurrPhase]);
390
        }
391
      else if( mCurrPhase<mNumPhases-1 )
392
        {
393
        mCurrPhase++;
394
        mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
395
        mCurrMove = 0;
396
        glowCubits(mCubitsNotInvolved[mCurrPhase-1]);
397
        }
398
      else
399
        {
400
        mCurrPhase = 0;
401
        mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
402
        mCurrMove = 0;
403
        int[][] moves = transformMoves(mMoves, false);
404
        ObjectControl control = act.getControl();
405
        control.applyScrambles(moves);
406
        }
407

    
408
      setText(act);
409
      }
410
    }
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

    
414
  public void onActionFinished(final long effectID)
415
    {
416
    mCanMove = true;
417

    
418
    SolverActivity act=mAct.get();
419
    ObjectControl control = act.getControl();
420
    control.unblockRotation();
421
    }
422
}
(2-2/5)