Revision 1d1f9ccf
Added by Leszek Koltunski 1 day ago
src/main/java/org/distorted/dialogs/RubikDialogStarsStatus.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2022 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.dialogs; |
|
11 |
|
|
12 |
import android.app.Dialog; |
|
13 |
import android.view.View; |
|
14 |
import android.view.Window; |
|
15 |
import android.view.WindowManager; |
|
16 |
import android.widget.LinearLayout; |
|
17 |
import android.widget.TextView; |
|
18 |
|
|
19 |
import androidx.fragment.app.FragmentActivity; |
|
20 |
|
|
21 |
import org.distorted.external.RubikScores; |
|
22 |
import org.distorted.main.R; |
|
23 |
|
|
24 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
25 |
|
|
26 |
public class RubikDialogStarsStatus extends RubikDialogAbstract |
|
27 |
{ |
|
28 |
@Override |
|
29 |
public void onResume() |
|
30 |
{ |
|
31 |
super.onResume(); |
|
32 |
|
|
33 |
Window window = getDialog().getWindow(); |
|
34 |
|
|
35 |
if( window!=null ) |
|
36 |
{ |
|
37 |
WindowManager.LayoutParams params = window.getAttributes(); |
|
38 |
params.width = (int)Math.min( mHeight*0.65f,mWidth*0.95f ); |
|
39 |
params.height = WindowManager.LayoutParams.WRAP_CONTENT; |
|
40 |
window.setAttributes(params); |
|
41 |
} |
|
42 |
} |
|
43 |
|
|
44 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
45 |
|
|
46 |
public int getResource() { return R.layout.dialog_stars_status; } |
|
47 |
public int getTitleResource() { return -1; } |
|
48 |
public boolean hasArgument() { return false; } |
|
49 |
public int getPositive() { return R.string.ok; } |
|
50 |
public int getNegative() { return -1; } |
|
51 |
|
|
52 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
53 |
|
|
54 |
public void positiveAction() |
|
55 |
{ |
|
56 |
|
|
57 |
} |
|
58 |
|
|
59 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
60 |
|
|
61 |
public void negativeAction() |
|
62 |
{ |
|
63 |
|
|
64 |
} |
|
65 |
|
|
66 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
67 |
|
|
68 |
public void prepareBody(Dialog dialog, View view, FragmentActivity act, float size) |
|
69 |
{ |
|
70 |
int height = (int)(mHeight*0.110f); |
|
71 |
int margin = (int)(mHeight*0.007f); |
|
72 |
|
|
73 |
LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT); |
|
74 |
params1.setMargins(margin, margin, margin, margin); |
|
75 |
LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,height); |
|
76 |
params2.setMargins(margin, margin, margin, margin); |
|
77 |
|
|
78 |
LinearLayout lm = view.findViewById(R.id.stars_main); |
|
79 |
lm.setPadding(margin,margin,margin,margin); |
|
80 |
|
|
81 |
LinearLayout ls = view.findViewById(R.id.stars_strings); |
|
82 |
ls.setLayoutParams(params1); |
|
83 |
LinearLayout l1 = view.findViewById(R.id.stars_layout_1); |
|
84 |
l1.setLayoutParams(params2); |
|
85 |
LinearLayout l2 = view.findViewById(R.id.stars_layout_2); |
|
86 |
l2.setLayoutParams(params2); |
|
87 |
LinearLayout l3 = view.findViewById(R.id.stars_layout_3); |
|
88 |
l3.setLayoutParams(params2); |
|
89 |
|
|
90 |
int number = RubikScores.getInstance().getNumStars(); |
|
91 |
TextView v = view.findViewById(R.id.stars_string1); |
|
92 |
v.setText(getString(R.string.buy_string1,number)); |
|
93 |
} |
|
94 |
} |
src/main/java/org/distorted/objects/RubikObject.java | ||
---|---|---|
27 | 27 |
import org.distorted.objectlib.metadata.ListObjects; |
28 | 28 |
import org.distorted.objectlib.metadata.Metadata; |
29 | 29 |
import org.distorted.objectlib.patterns.RubikPatternList; |
30 |
import org.distorted.solvers.ImplementedSolversList;
|
|
30 |
import org.distorted.solvers.SolvingList;
|
|
31 | 31 |
|
32 | 32 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
33 | 33 |
|
... | ... | |
81 | 81 |
int patternOrdinal = RubikPatternList.getOrdinal(mObjectIndex); |
82 | 82 |
mPatterns = RubikPatternList.getPatterns(patternOrdinal); |
83 | 83 |
|
84 |
mSolverOrdinal = ImplementedSolversList.getSolverOrdinal(mObjectIndex);
|
|
84 |
mSolverOrdinal = SolvingList.getSolverOrdinal(mObjectIndex);
|
|
85 | 85 |
mExtrasOrdinal = -1; |
86 | 86 |
|
87 | 87 |
mObjectVersion = meta.objectVersion(); |
src/main/java/org/distorted/overlays/DataGeneric.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2022 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.overlays; |
|
11 |
|
|
12 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
13 |
|
|
14 |
public abstract class DataGeneric |
|
15 |
{ |
|
16 |
|
|
17 |
|
|
18 |
} |
src/main/java/org/distorted/overlays/DataStars.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2022 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.overlays; |
|
11 |
|
|
12 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
13 |
|
|
14 |
import android.content.res.Resources; |
|
15 |
|
|
16 |
public class DataStars extends DataGeneric |
|
17 |
{ |
|
18 |
private final int mTotStars, mNewStars; |
|
19 |
private final Resources mRes; |
|
20 |
|
|
21 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
22 |
|
|
23 |
public DataStars(int totStars, int newStars, Resources res) |
|
24 |
{ |
|
25 |
mTotStars = totStars; |
|
26 |
mNewStars = newStars; |
|
27 |
mRes = res; |
|
28 |
} |
|
29 |
|
|
30 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
31 |
|
|
32 |
int getTotal() |
|
33 |
{ |
|
34 |
return mTotStars; |
|
35 |
} |
|
36 |
|
|
37 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
38 |
|
|
39 |
int getNew() |
|
40 |
{ |
|
41 |
return mNewStars; |
|
42 |
} |
|
43 |
|
|
44 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
45 |
|
|
46 |
Resources getResources() |
|
47 |
{ |
|
48 |
return mRes; |
|
49 |
} |
|
50 |
} |
src/main/java/org/distorted/overlays/ListenerOverlay.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2022 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.overlays; |
|
11 |
|
|
12 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
13 |
|
|
14 |
public interface ListenerOverlay |
|
15 |
{ |
|
16 |
void overlayFinished(long id); |
|
17 |
} |
src/main/java/org/distorted/overlays/OverlayGeneric.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2022 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.overlays; |
|
11 |
|
|
12 |
import org.distorted.library.main.DistortedScreen; |
|
13 |
|
|
14 |
import java.lang.reflect.Method; |
|
15 |
|
|
16 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
17 |
|
|
18 |
public abstract class OverlayGeneric |
|
19 |
{ |
|
20 |
private enum Overlays |
|
21 |
{ |
|
22 |
STARS ( OverlayStars.class ) |
|
23 |
; |
|
24 |
|
|
25 |
private final Class<? extends OverlayGeneric> mClass; |
|
26 |
|
|
27 |
Overlays(Class<? extends OverlayGeneric> clazz) |
|
28 |
{ |
|
29 |
mClass = clazz; |
|
30 |
} |
|
31 |
} |
|
32 |
|
|
33 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
34 |
|
|
35 |
public static void enableEffects() |
|
36 |
{ |
|
37 |
Method method; |
|
38 |
|
|
39 |
for(Overlays overlay: Overlays.values() ) |
|
40 |
{ |
|
41 |
try |
|
42 |
{ |
|
43 |
method = overlay.mClass.getDeclaredMethod("enableEffects"); |
|
44 |
} |
|
45 |
catch(NoSuchMethodException ex) |
|
46 |
{ |
|
47 |
android.util.Log.e("OverlayGeneric", overlay.mClass.getSimpleName()+": exception getting method: "+ex.getMessage()); |
|
48 |
method = null; |
|
49 |
} |
|
50 |
|
|
51 |
try |
|
52 |
{ |
|
53 |
if( method!=null ) method.invoke(null); |
|
54 |
} |
|
55 |
catch(Exception ex) |
|
56 |
{ |
|
57 |
android.util.Log.e("OverlayGeneric", overlay.mClass.getSimpleName()+": exception invoking method: "+ex.getMessage()); |
|
58 |
} |
|
59 |
} |
|
60 |
} |
|
61 |
|
|
62 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
63 |
|
|
64 |
public abstract long startOverlay(DistortedScreen screen, ListenerOverlay listener, DataGeneric data); |
|
65 |
} |
src/main/java/org/distorted/overlays/OverlayStars.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2022 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.overlays; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
import android.graphics.Bitmap; |
|
14 |
import android.graphics.BitmapFactory; |
|
15 |
import android.graphics.Canvas; |
|
16 |
import android.graphics.Paint; |
|
17 |
|
|
18 |
import org.distorted.library.effect.EffectQuality; |
|
19 |
import org.distorted.library.effect.FragmentEffectAlpha; |
|
20 |
import org.distorted.library.effect.MatrixEffectMove; |
|
21 |
import org.distorted.library.effect.MatrixEffectScale; |
|
22 |
import org.distorted.library.effect.PostprocessEffectGlow; |
|
23 |
import org.distorted.library.effect.VertexEffectMove; |
|
24 |
import org.distorted.library.effect.VertexEffectScale; |
|
25 |
import org.distorted.library.main.DistortedEffects; |
|
26 |
import org.distorted.library.main.DistortedNode; |
|
27 |
import org.distorted.library.main.DistortedScreen; |
|
28 |
import org.distorted.library.main.DistortedTexture; |
|
29 |
import org.distorted.library.main.InternalOutputSurface; |
|
30 |
import org.distorted.library.mesh.MeshJoined; |
|
31 |
import org.distorted.library.mesh.MeshQuad; |
|
32 |
import org.distorted.library.message.EffectListener; |
|
33 |
import org.distorted.library.type.Dynamic; |
|
34 |
import org.distorted.library.type.Dynamic1D; |
|
35 |
import org.distorted.library.type.Dynamic2D; |
|
36 |
import org.distorted.library.type.Dynamic3D; |
|
37 |
import org.distorted.library.type.Dynamic4D; |
|
38 |
import org.distorted.library.type.Static1D; |
|
39 |
import org.distorted.library.type.Static2D; |
|
40 |
import org.distorted.library.type.Static3D; |
|
41 |
import org.distorted.library.type.Static4D; |
|
42 |
import org.distorted.main.R; |
|
43 |
|
|
44 |
import java.util.Random; |
|
45 |
|
|
46 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
47 |
|
|
48 |
public class OverlayStars extends OverlayGeneric implements EffectListener |
|
49 |
{ |
|
50 |
private static final int DUR_APP = 1500; |
|
51 |
private static final int DUR_MOV = 3000; |
|
52 |
private static final int DUR_GLO = 600; |
|
53 |
|
|
54 |
private static final int MAX_FALLING = 50; |
|
55 |
|
|
56 |
private ListenerOverlay mListener; |
|
57 |
private DistortedNode mNodeFalling, mNodeCentral; |
|
58 |
private DistortedScreen mScreen; |
|
59 |
private DistortedTexture mTexture; |
|
60 |
private Bitmap mCountBitmap, mStarBitmap; |
|
61 |
private Canvas mCountCanvas; |
|
62 |
private Paint mPaint; |
|
63 |
private int mBmpW, mBmpH; |
|
64 |
private float mWidth, mHeight; |
|
65 |
private Random mRandom; |
|
66 |
private long mMoveID, mGlow1ID, mGlow2ID, mAlphaID; |
|
67 |
private int mTotalStars, mNewStars; |
|
68 |
private FragmentEffectAlpha mAlpha; |
|
69 |
private Dynamic1D mAlphaStrength; |
|
70 |
private boolean mIncrease; |
|
71 |
private float mTextHeight; |
|
72 |
|
|
73 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
74 |
|
|
75 |
private Dynamic3D createRandomMove(boolean increase) |
|
76 |
{ |
|
77 |
Dynamic3D move = new Dynamic3D(); |
|
78 |
move.setMode(Dynamic.MODE_PATH); |
|
79 |
move.setDuration(DUR_MOV); |
|
80 |
move.setCount( increase ? 0.40f : 0.50f ); |
|
81 |
|
|
82 |
float widthS = (mRandom.nextFloat()-0.5f)*mWidth*1.10f; |
|
83 |
float widthM = widthS + (mRandom.nextFloat()-0.5f)*mWidth*0.2f; |
|
84 |
float heighS = mRandom.nextFloat()*mHeight*0.2f; |
|
85 |
float heighM = (mRandom.nextFloat()-0.5f)*mHeight*0.2f; |
|
86 |
|
|
87 |
Static3D pointS = new Static3D(widthS,mHeight*0.60f+heighS,0); |
|
88 |
Static3D pointM = new Static3D(widthM,mHeight*0.25f+heighM,0); |
|
89 |
Static3D pointE = new Static3D(0,0,0); |
|
90 |
Static3D pointF = new Static3D(0,0,-10000); |
|
91 |
|
|
92 |
if( increase ) |
|
93 |
{ |
|
94 |
move.add(pointS); |
|
95 |
move.add(pointM); |
|
96 |
move.add(pointE); |
|
97 |
move.add(pointF); |
|
98 |
} |
|
99 |
else |
|
100 |
{ |
|
101 |
move.add(pointF); |
|
102 |
move.add(pointE); |
|
103 |
move.add(pointM); |
|
104 |
move.add(pointS); |
|
105 |
} |
|
106 |
|
|
107 |
return move; |
|
108 |
} |
|
109 |
|
|
110 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
111 |
|
|
112 |
private void createAlphaEffect(boolean appear) |
|
113 |
{ |
|
114 |
if( mAlpha==null ) |
|
115 |
{ |
|
116 |
mAlphaStrength = new Dynamic1D(); |
|
117 |
mAlphaStrength.setMode(Dynamic.MODE_PATH); |
|
118 |
mAlphaStrength.setDuration( mNewStars==0 ? 3*DUR_APP : DUR_APP); |
|
119 |
mAlphaStrength.setCount(0.5f); |
|
120 |
equipAlpha(mAlphaStrength,appear); |
|
121 |
mAlpha = new FragmentEffectAlpha(mAlphaStrength); |
|
122 |
|
|
123 |
if( mNewStars==0 ) |
|
124 |
{ |
|
125 |
mMoveID = mAlpha.getID(); |
|
126 |
mAlpha.notifyWhenFinished(this); |
|
127 |
} |
|
128 |
} |
|
129 |
else |
|
130 |
{ |
|
131 |
mAlphaStrength.resetToBeginning(); |
|
132 |
equipAlpha(mAlphaStrength,appear); |
|
133 |
} |
|
134 |
} |
|
135 |
|
|
136 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
137 |
|
|
138 |
private void equipAlpha(Dynamic1D alpha, boolean appear) |
|
139 |
{ |
|
140 |
Static1D point0 = new Static1D(0.0f); |
|
141 |
Static1D point1 = new Static1D(1.0f); |
|
142 |
|
|
143 |
alpha.removeAll(); |
|
144 |
|
|
145 |
if( appear ) |
|
146 |
{ |
|
147 |
alpha.add(point0); |
|
148 |
if( mNewStars==0 ) alpha.add(point1); |
|
149 |
alpha.add(point1); |
|
150 |
} |
|
151 |
else |
|
152 |
{ |
|
153 |
alpha.add(point1); |
|
154 |
if( mNewStars==0 ) alpha.add(point1); |
|
155 |
alpha.add(point0); |
|
156 |
} |
|
157 |
} |
|
158 |
|
|
159 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
160 |
|
|
161 |
private float computeQuotientAndTextHeight(int total) |
|
162 |
{ |
|
163 |
if( total>=10000 ) |
|
164 |
{ |
|
165 |
mTextHeight = 0.610f; |
|
166 |
return 0.16f; |
|
167 |
} |
|
168 |
if( total>= 1000 ) |
|
169 |
{ |
|
170 |
mTextHeight = 0.625f; |
|
171 |
return 0.20f; |
|
172 |
} |
|
173 |
if( total>= 100 ) |
|
174 |
{ |
|
175 |
mTextHeight = 0.640f; |
|
176 |
return 0.26f; |
|
177 |
} |
|
178 |
|
|
179 |
mTextHeight = 0.655f; |
|
180 |
return 0.28f; |
|
181 |
} |
|
182 |
|
|
183 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
184 |
|
|
185 |
private void createBitmap(Resources res, int total) |
|
186 |
{ |
|
187 |
mStarBitmap = BitmapFactory.decodeResource(res, R.drawable.star); |
|
188 |
mBmpW = mStarBitmap.getWidth(); |
|
189 |
mBmpH = mStarBitmap.getHeight(); |
|
190 |
mCountBitmap = Bitmap.createBitmap(mBmpW,mBmpH,Bitmap.Config.ARGB_8888); |
|
191 |
mCountCanvas = new Canvas(mCountBitmap); |
|
192 |
|
|
193 |
float quotient = computeQuotientAndTextHeight(total); |
|
194 |
|
|
195 |
mPaint = new Paint(); |
|
196 |
mPaint.setColor(0xff000000); |
|
197 |
mPaint.setTextSize(mBmpH*quotient); |
|
198 |
mPaint.setAntiAlias(true); |
|
199 |
mPaint.setTextAlign(Paint.Align.CENTER); |
|
200 |
} |
|
201 |
|
|
202 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
203 |
|
|
204 |
private DistortedNode createNodeFalling(boolean increase) |
|
205 |
{ |
|
206 |
DistortedTexture texture = new DistortedTexture(); |
|
207 |
texture.setTexture(mStarBitmap); |
|
208 |
int numFalling = Math.min(mNewStars,MAX_FALLING); |
|
209 |
|
|
210 |
MeshQuad[] mesh = new MeshQuad[numFalling]; |
|
211 |
|
|
212 |
for(int i=0; i<numFalling; i++) |
|
213 |
{ |
|
214 |
mesh[i] = new MeshQuad(); |
|
215 |
mesh[i].setEffectAssociation(0,1,i+1); |
|
216 |
} |
|
217 |
|
|
218 |
MeshJoined wholeMesh = new MeshJoined(mesh); |
|
219 |
|
|
220 |
DistortedEffects effects = new DistortedEffects(); |
|
221 |
VertexEffectScale scaleE = new VertexEffectScale(mHeight*0.10f); |
|
222 |
scaleE.setMeshAssociation(1,-1); |
|
223 |
effects.apply(scaleE); |
|
224 |
|
|
225 |
for(int i=0; i<numFalling; i++) |
|
226 |
{ |
|
227 |
Dynamic3D moveP = createRandomMove(increase); |
|
228 |
VertexEffectMove moveE= new VertexEffectMove(moveP); |
|
229 |
moveE.setMeshAssociation(0,i+1); |
|
230 |
effects.apply(moveE); |
|
231 |
|
|
232 |
if( i==0 ) |
|
233 |
{ |
|
234 |
mMoveID = moveE.getID(); |
|
235 |
moveE.notifyWhenFinished(this); |
|
236 |
} |
|
237 |
} |
|
238 |
|
|
239 |
return new DistortedNode(texture,effects,wholeMesh); |
|
240 |
} |
|
241 |
|
|
242 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
243 |
|
|
244 |
private DistortedNode createNodeCentral(int numStars) |
|
245 |
{ |
|
246 |
mTexture = new DistortedTexture(); |
|
247 |
renderStars(numStars); |
|
248 |
|
|
249 |
MeshQuad mesh = new MeshQuad(); |
|
250 |
|
|
251 |
DistortedEffects effects = new DistortedEffects(); |
|
252 |
float scaleM = mHeight*0.22f; |
|
253 |
Static3D moveM= new Static3D(0,0,1); |
|
254 |
MatrixEffectMove move = new MatrixEffectMove(moveM); |
|
255 |
MatrixEffectScale scale= new MatrixEffectScale(scaleM); |
|
256 |
effects.apply(move); |
|
257 |
effects.apply(scale); |
|
258 |
createAlphaEffect(true); |
|
259 |
effects.apply(mAlpha); |
|
260 |
|
|
261 |
return new DistortedNode(mTexture,effects,mesh); |
|
262 |
} |
|
263 |
|
|
264 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
265 |
|
|
266 |
private void renderStars(int numStars) |
|
267 |
{ |
|
268 |
String txt = ""+numStars; |
|
269 |
mCountBitmap.eraseColor(0x00000000); |
|
270 |
mCountCanvas.drawBitmap(mStarBitmap,0,0,null); |
|
271 |
mCountCanvas.drawText(txt,mBmpW*0.5f,mBmpH*mTextHeight,mPaint); |
|
272 |
mTexture.setTexture(mCountBitmap); |
|
273 |
} |
|
274 |
|
|
275 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
276 |
|
|
277 |
public long startOverlay(DistortedScreen screen, ListenerOverlay listener, DataGeneric data) |
|
278 |
{ |
|
279 |
mRandom = new Random(); |
|
280 |
mScreen = screen; |
|
281 |
mListener= listener; |
|
282 |
DataStars stars = (DataStars)data; |
|
283 |
mTotalStars = stars.getTotal(); |
|
284 |
mNewStars = stars.getNew(); |
|
285 |
Resources res = stars.getResources(); |
|
286 |
mWidth = mScreen.getWidth(); |
|
287 |
mHeight= mScreen.getHeight(); |
|
288 |
mIncrease = mNewStars>0; |
|
289 |
if( !mIncrease ) mNewStars = -mNewStars; |
|
290 |
|
|
291 |
createBitmap(res, mTotalStars); |
|
292 |
|
|
293 |
if( mNewStars!=0 ) |
|
294 |
{ |
|
295 |
mNodeFalling = createNodeFalling(mIncrease); |
|
296 |
mNodeFalling.enableDepthStencil(InternalOutputSurface.NO_DEPTH_NO_STENCIL); |
|
297 |
mScreen.attach(mNodeFalling); |
|
298 |
} |
|
299 |
|
|
300 |
mNodeCentral = createNodeCentral(mTotalStars); |
|
301 |
mNodeCentral.glDepthMask(false); |
|
302 |
mScreen.attach(mNodeCentral); |
|
303 |
|
|
304 |
return 0; |
|
305 |
} |
|
306 |
|
|
307 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
308 |
|
|
309 |
private PostprocessEffectGlow constructGlow(boolean firstPhase) |
|
310 |
{ |
|
311 |
Dynamic2D haloRadius = new Dynamic2D( mNewStars==0 ? 2*DUR_GLO : DUR_GLO,0.5f); |
|
312 |
Static2D point20 = new Static2D( 0, 0); |
|
313 |
Static2D point21 = new Static2D(15,50); |
|
314 |
Dynamic4D color = new Dynamic4D(DUR_GLO, 0.5f); |
|
315 |
Static4D point40 = new Static4D(1,1,1,0.0f); |
|
316 |
Static4D point41 = new Static4D(1,1,1,0.8f); |
|
317 |
|
|
318 |
if( firstPhase ) |
|
319 |
{ |
|
320 |
haloRadius.add(point20); |
|
321 |
haloRadius.add(point21); |
|
322 |
color.add(point40); |
|
323 |
color.add(point41); |
|
324 |
} |
|
325 |
else |
|
326 |
{ |
|
327 |
haloRadius.add(point21); |
|
328 |
haloRadius.add(point20); |
|
329 |
color.add(point41); |
|
330 |
color.add(point40); |
|
331 |
} |
|
332 |
|
|
333 |
PostprocessEffectGlow glow = new PostprocessEffectGlow(haloRadius,color); |
|
334 |
glow.setQuality(EffectQuality.MEDIUM); |
|
335 |
glow.notifyWhenFinished(this); |
|
336 |
|
|
337 |
return glow; |
|
338 |
} |
|
339 |
|
|
340 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
341 |
|
|
342 |
public void effectFinished(long id) |
|
343 |
{ |
|
344 |
if( id==mMoveID ) |
|
345 |
{ |
|
346 |
PostprocessEffectGlow glow = constructGlow(true); |
|
347 |
mGlow1ID = glow.getID(); |
|
348 |
DistortedEffects effects = mNodeCentral.getEffects(); |
|
349 |
effects.apply(glow); |
|
350 |
} |
|
351 |
if( id==mGlow1ID ) |
|
352 |
{ |
|
353 |
renderStars(mTotalStars+(mIncrease ? mNewStars : -mNewStars)); |
|
354 |
PostprocessEffectGlow glow = constructGlow(false); |
|
355 |
mGlow2ID = glow.getID(); |
|
356 |
DistortedEffects effects = mNodeCentral.getEffects(); |
|
357 |
effects.abortById(mGlow1ID); |
|
358 |
effects.apply(glow); |
|
359 |
} |
|
360 |
if( id==mGlow2ID ) |
|
361 |
{ |
|
362 |
DistortedEffects effects = mNodeCentral.getEffects(); |
|
363 |
effects.abortById(mGlow2ID); |
|
364 |
createAlphaEffect(false); |
|
365 |
mAlphaID = mAlpha.getID(); |
|
366 |
mAlpha.notifyWhenFinished(this); |
|
367 |
effects.apply(mAlpha); |
|
368 |
} |
|
369 |
if( id==mAlphaID ) |
|
370 |
{ |
|
371 |
mScreen.detach(mNodeCentral); |
|
372 |
mNodeCentral.markForDeletion(); |
|
373 |
mNodeCentral=null; |
|
374 |
|
|
375 |
if( mNodeFalling!=null ) |
|
376 |
{ |
|
377 |
mScreen.detach(mNodeFalling); |
|
378 |
mNodeFalling.markForDeletion(); |
|
379 |
mNodeFalling=null; |
|
380 |
} |
|
381 |
|
|
382 |
if( mListener!=null ) mListener.overlayFinished(id); |
|
383 |
} |
|
384 |
} |
|
385 |
|
|
386 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
387 |
|
|
388 |
@SuppressWarnings("unused") |
|
389 |
public static void enableEffects() |
|
390 |
{ |
|
391 |
FragmentEffectAlpha.enable(); |
|
392 |
VertexEffectMove.enable(); |
|
393 |
VertexEffectScale.enable(); |
|
394 |
PostprocessEffectGlow.enable(); |
|
395 |
} |
|
396 |
} |
src/main/java/org/distorted/solvers/ImplementedSolversList.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2020 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.solvers; |
|
11 |
|
|
12 |
import org.distorted.main.R; |
|
13 |
import org.distorted.objectlib.metadata.MetadataCUBE_2; |
|
14 |
import org.distorted.objectlib.metadata.MetadataCUBE_3; |
|
15 |
import org.distorted.objectlib.metadata.MetadataCU_232; |
|
16 |
import org.distorted.objectlib.metadata.MetadataCU_323; |
|
17 |
import org.distorted.objectlib.metadata.MetadataDIAM_2; |
|
18 |
import org.distorted.objectlib.metadata.MetadataDIN4_3; |
|
19 |
import org.distorted.objectlib.metadata.MetadataDINO_3; |
|
20 |
import org.distorted.objectlib.metadata.MetadataIVY_2; |
|
21 |
import org.distorted.objectlib.metadata.MetadataJING_2; |
|
22 |
import org.distorted.objectlib.metadata.MetadataPDIA_3; |
|
23 |
import org.distorted.objectlib.metadata.MetadataPDUO_2; |
|
24 |
import org.distorted.objectlib.metadata.MetadataPYRA_3; |
|
25 |
import org.distorted.objectlib.metadata.MetadataSKEW_2; |
|
26 |
|
|
27 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
28 |
|
|
29 |
public enum ImplementedSolversList |
|
30 |
{ |
|
31 |
CUBE2 (MetadataCUBE_2.INDEX, R.string.solver_cube2_title, R.string.solver_cube2_description, true), |
|
32 |
CUBE3_KOCIEMBA (MetadataCUBE_3.INDEX, R.string.solver_cube3_title, R.string.solver_cube3_description, true), |
|
33 |
CU_232 (MetadataCU_232.INDEX, R.string.solver_cu232_title, R.string.solver_cu232_description, true), |
|
34 |
CU_323 (MetadataCU_323.INDEX, R.string.solver_cu323_title, R.string.solver_cu323_description, true), |
|
35 |
PYRAMINX (MetadataPYRA_3.INDEX, R.string.solver_pyra3_title, R.string.solver_pyra3_description, true), |
|
36 |
SKEWB (MetadataSKEW_2.INDEX, R.string.solver_skew2_title, R.string.solver_skew2_description, true), |
|
37 |
PYRAMINX_DUO (MetadataPDUO_2.INDEX, R.string.solver_pduo2_title, R.string.solver_pduo2_description, true), |
|
38 |
IVY (MetadataIVY_2.INDEX , R.string.solver_ivy_title, R.string.solver_ivy_description, true), |
|
39 |
DIAMOND (MetadataDIAM_2.INDEX, R.string.solver_diam2_title, R.string.solver_diam2_description, true), |
|
40 |
JING2 (MetadataJING_2.INDEX, R.string.solver_jing2_title, R.string.solver_jing2_description, true), |
|
41 |
DINO6 (MetadataDINO_3.INDEX, R.string.solver_dino6_title, R.string.solver_dino6_description, true), |
|
42 |
DINO4 (MetadataDIN4_3.INDEX, R.string.solver_dino4_title, R.string.solver_dino4_description, true), |
|
43 |
PDIA (MetadataPDIA_3.INDEX, R.string.solver_pdia_title, R.string.solver_pdia_description, true), |
|
44 |
; |
|
45 |
|
|
46 |
public static final int NUM_OBJECTS = values().length; |
|
47 |
|
|
48 |
private final int mObject; |
|
49 |
private final int mTitle; |
|
50 |
private final int mDescription; |
|
51 |
private final boolean mImplemented; |
|
52 |
|
|
53 |
private static final ImplementedSolversList[] objects; |
|
54 |
|
|
55 |
static |
|
56 |
{ |
|
57 |
objects = new ImplementedSolversList[NUM_OBJECTS]; |
|
58 |
int i=0; |
|
59 |
|
|
60 |
for(ImplementedSolversList object: ImplementedSolversList.values()) |
|
61 |
{ |
|
62 |
objects[i++] = object; |
|
63 |
} |
|
64 |
} |
|
65 |
|
|
66 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
67 |
|
|
68 |
public static ImplementedSolversList getSolver(int solverOrdinal) |
|
69 |
{ |
|
70 |
return objects[solverOrdinal]; |
|
71 |
} |
|
72 |
|
|
73 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
74 |
|
|
75 |
public static int getSolverOrdinal(int objectOrdinal) |
|
76 |
{ |
|
77 |
for(int o=0; o<NUM_OBJECTS; o++) |
|
78 |
if( objects[o].mObject==objectOrdinal ) return o; |
|
79 |
|
|
80 |
return -1; |
|
81 |
} |
|
82 |
|
|
83 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
84 |
|
|
85 |
ImplementedSolversList(int object, int title, int descripton, boolean implemented) |
|
86 |
{ |
|
87 |
mObject = object; |
|
88 |
mTitle = title; |
|
89 |
mDescription = descripton; |
|
90 |
mImplemented = implemented; |
|
91 |
} |
|
92 |
|
|
93 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
94 |
|
|
95 |
public int getObject() |
|
96 |
{ |
|
97 |
return mObject; |
|
98 |
} |
|
99 |
|
|
100 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
101 |
|
|
102 |
public int getTitle() |
|
103 |
{ |
|
104 |
return mTitle; |
|
105 |
} |
|
106 |
|
|
107 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
108 |
|
|
109 |
public int getDescription() |
|
110 |
{ |
|
111 |
return mDescription; |
|
112 |
} |
|
113 |
|
|
114 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
115 |
|
|
116 |
public boolean isImplemented() |
|
117 |
{ |
|
118 |
return mImplemented; |
|
119 |
} |
|
120 |
} |
src/main/java/org/distorted/solvers/SolverCube2.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2023 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.main.R; |
|
15 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
16 |
import org.distorted.objectlib.metadata.ListObjects; |
|
17 |
import org.distorted.objectlib.main.TwistyObject; |
|
18 |
import org.distorted.objectlib.tablebases.ImplementedTablebasesList; |
|
19 |
import org.distorted.objectlib.tablebases.TablebaseHelpers; |
|
20 |
import org.distorted.objectlib.tablebases.TablebasesAbstract; |
|
21 |
import org.distorted.objectlib.tablebases.TBCube2; |
|
22 |
|
|
23 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
24 |
|
|
25 |
public class SolverCube2 extends SolverTablebase |
|
26 |
{ |
|
27 |
private static final int ERROR_CORNER_135_MISSING = -1; |
|
28 |
private static final int ERROR_CORNER_134_MISSING = -2; |
|
29 |
private static final int ERROR_CORNER_125_MISSING = -3; |
|
30 |
private static final int ERROR_CORNER_124_MISSING = -4; |
|
31 |
private static final int ERROR_CORNER_035_MISSING = -5; |
|
32 |
private static final int ERROR_CORNER_034_MISSING = -6; |
|
33 |
private static final int ERROR_CORNER_025_MISSING = -7; |
|
34 |
private static final int ERROR_CORNER_024_MISSING = -8; |
|
35 |
private static final int ERROR_CORNERS_CANNOT = -9; |
|
36 |
private static final int ERROR_CORNER_TWISTED = -10; |
|
37 |
|
|
38 |
TablebasesAbstract mSolver; |
|
39 |
private final int[] mFaceColors; |
|
40 |
|
|
41 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
42 |
|
|
43 |
private void fillCornerTwists(int[] output, int[][] corners, int[] perm) |
|
44 |
{ |
|
45 |
for(int i=0; i<8; i++) |
|
46 |
{ |
|
47 |
int[] c = corners[perm[i]]; |
|
48 |
|
|
49 |
if( c[0]==mFaceColors[0] || c[0]==mFaceColors[1] ) output[i] = 0; |
|
50 |
else if( c[1]==mFaceColors[0] || c[1]==mFaceColors[1] ) output[i] = 1; |
|
51 |
else output[i] = 2; |
|
52 |
} |
|
53 |
} |
|
54 |
|
|
55 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
56 |
|
|
57 |
private int cornerIndex(int[][] corners, int i1, int i2, int i3) |
|
58 |
{ |
|
59 |
int c1 = mFaceColors[i1]; |
|
60 |
int c2 = mFaceColors[i2]; |
|
61 |
int c3 = mFaceColors[i3]; |
|
62 |
|
|
63 |
for(int i=0; i<8; i++) |
|
64 |
{ |
|
65 |
int[] cor = corners[i]; |
|
66 |
|
|
67 |
if( (cor[0]==c1 && cor[1]==c2 && cor[2]==c3) || |
|
68 |
(cor[0]==c2 && cor[1]==c3 && cor[2]==c1) || |
|
69 |
(cor[0]==c3 && cor[1]==c1 && cor[2]==c2) ) return i; |
|
70 |
} |
|
71 |
|
|
72 |
return -1; |
|
73 |
} |
|
74 |
|
|
75 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
76 |
|
|
77 |
private int retCornerPermutation(int[] output, int[][] corners) |
|
78 |
{ |
|
79 |
for(int i=0; i<8; i++) output[i] = -1; |
|
80 |
|
|
81 |
output[0] = cornerIndex(corners, 1,2,5); |
|
82 |
output[1] = cornerIndex(corners, 1,4,2); |
|
83 |
output[2] = cornerIndex(corners, 1,5,3); |
|
84 |
output[3] = cornerIndex(corners, 1,3,4); |
|
85 |
output[4] = cornerIndex(corners, 0,5,2); |
|
86 |
output[5] = cornerIndex(corners, 0,2,4); |
|
87 |
output[6] = cornerIndex(corners, 0,3,5); |
|
88 |
output[7] = cornerIndex(corners, 0,4,3); |
|
89 |
|
|
90 |
if( output[0]==-1 ) return ERROR_CORNER_125_MISSING; |
|
91 |
if( output[1]==-1 ) return ERROR_CORNER_124_MISSING; |
|
92 |
if( output[2]==-1 ) return ERROR_CORNER_135_MISSING; |
|
93 |
if( output[3]==-1 ) return ERROR_CORNER_134_MISSING; |
|
94 |
if( output[4]==-1 ) return ERROR_CORNER_025_MISSING; |
|
95 |
if( output[5]==-1 ) return ERROR_CORNER_024_MISSING; |
|
96 |
if( output[6]==-1 ) return ERROR_CORNER_035_MISSING; |
|
97 |
if( output[7]==-1 ) return ERROR_CORNER_034_MISSING; |
|
98 |
|
|
99 |
return 0; |
|
100 |
} |
|
101 |
|
|
102 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
103 |
|
|
104 |
private int findColor(int[][] corners, int c1, int c2) |
|
105 |
{ |
|
106 |
for(int i=0; i<8; i++) |
|
107 |
{ |
|
108 |
int[] cor = corners[i]; |
|
109 |
|
|
110 |
if( cor[0]==c1 && cor[1]==c2 ) return cor[2]; |
|
111 |
if( cor[1]==c1 && cor[2]==c2 ) return cor[0]; |
|
112 |
if( cor[2]==c1 && cor[0]==c2 ) return cor[1]; |
|
113 |
} |
|
114 |
|
|
115 |
return -1; |
|
116 |
} |
|
117 |
|
|
118 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
119 |
|
|
120 |
private int computeFaceColors(int[][] corners) |
|
121 |
{ |
|
122 |
mFaceColors[1] = corners[1][0]; |
|
123 |
mFaceColors[2] = corners[1][2]; |
|
124 |
mFaceColors[4] = corners[1][1]; |
|
125 |
|
|
126 |
mFaceColors[0] = findColor(corners,mFaceColors[2],mFaceColors[4]); |
|
127 |
mFaceColors[3] = findColor(corners,mFaceColors[4],mFaceColors[1]); |
|
128 |
mFaceColors[5] = findColor(corners,mFaceColors[1],mFaceColors[2]); |
|
129 |
|
|
130 |
for(int i=0; i<6; i++) |
|
131 |
{ |
|
132 |
int color = mFaceColors[i]; |
|
133 |
if( color<0 ) return ERROR_CORNERS_CANNOT; |
|
134 |
|
|
135 |
for(int j=i+1; j<6; j++) |
|
136 |
if( mFaceColors[j]==color ) return ERROR_CORNERS_CANNOT; |
|
137 |
} |
|
138 |
|
|
139 |
return 0; |
|
140 |
} |
|
141 |
|
|
142 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
143 |
|
|
144 |
public SolverCube2(OperatingSystemInterface os, Resources res, TwistyObject object) |
|
145 |
{ |
|
146 |
super(os,res,object); |
|
147 |
mFaceColors = new int[6]; |
|
148 |
} |
|
149 |
|
|
150 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
151 |
|
|
152 |
private void getCorners(TwistyObject object, int[][] corners) |
|
153 |
{ |
|
154 |
corners[0][0] = object.getCubitFaceStickerIndex(0,1); |
|
155 |
corners[0][1] = object.getCubitFaceStickerIndex(0,3); |
|
156 |
corners[0][2] = object.getCubitFaceStickerIndex(0,5); |
|
157 |
|
|
158 |
corners[1][0] = object.getCubitFaceStickerIndex(1,3); |
|
159 |
corners[1][1] = object.getCubitFaceStickerIndex(1,5); |
|
160 |
corners[1][2] = object.getCubitFaceStickerIndex(1,1); |
|
161 |
|
|
162 |
corners[2][0] = object.getCubitFaceStickerIndex(2,5); |
|
163 |
corners[2][1] = object.getCubitFaceStickerIndex(2,1); |
|
164 |
corners[2][2] = object.getCubitFaceStickerIndex(2,3); |
|
165 |
|
|
166 |
corners[3][0] = object.getCubitFaceStickerIndex(3,1); |
|
167 |
corners[3][1] = object.getCubitFaceStickerIndex(3,3); |
|
168 |
corners[3][2] = object.getCubitFaceStickerIndex(3,5); |
|
169 |
|
|
170 |
corners[4][0] = object.getCubitFaceStickerIndex(4,1); |
|
171 |
corners[4][1] = object.getCubitFaceStickerIndex(4,3); |
|
172 |
corners[4][2] = object.getCubitFaceStickerIndex(4,5); |
|
173 |
|
|
174 |
corners[5][0] = object.getCubitFaceStickerIndex(5,1); |
|
175 |
corners[5][1] = object.getCubitFaceStickerIndex(5,3); |
|
176 |
corners[5][2] = object.getCubitFaceStickerIndex(5,5); |
|
177 |
|
|
178 |
corners[6][0] = object.getCubitFaceStickerIndex(6,1); |
|
179 |
corners[6][1] = object.getCubitFaceStickerIndex(6,3); |
|
180 |
corners[6][2] = object.getCubitFaceStickerIndex(6,5); |
|
181 |
|
|
182 |
corners[7][0] = object.getCubitFaceStickerIndex(7,1); |
|
183 |
corners[7][1] = object.getCubitFaceStickerIndex(7,3); |
|
184 |
corners[7][2] = object.getCubitFaceStickerIndex(7,5); |
|
185 |
} |
|
186 |
|
|
187 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
188 |
|
|
189 |
public int tablebaseIndex(TwistyObject object) |
|
190 |
{ |
|
191 |
int[][] corners= new int[8][3]; |
|
192 |
getCorners(object,corners); |
|
193 |
|
|
194 |
int result0 = computeFaceColors(corners); |
|
195 |
if( result0<0 ) return result0; |
|
196 |
|
|
197 |
int[] perm = new int[8]; |
|
198 |
int result1 = retCornerPermutation(perm,corners); |
|
199 |
if( result1<0 ) return result1; |
|
200 |
|
|
201 |
int[] perm7 = TBCube2.shrinkPerm(perm); |
|
202 |
int permNum = TablebaseHelpers.computePermutationNum(perm7); |
|
203 |
int[] twist = new int[8]; |
|
204 |
fillCornerTwists(twist,corners,perm); |
|
205 |
|
|
206 |
int totalTwist = 0; |
|
207 |
for(int i=0; i<8; i++) totalTwist += twist[i]; |
|
208 |
if( ((totalTwist)%3) != 0 ) return ERROR_CORNER_TWISTED; |
|
209 |
|
|
210 |
int twistNum = twist[0] + 3*(twist[2] + 3*(twist[3] + 3*(twist[4] + 3*(twist[5] + 3*twist[6])))); |
|
211 |
|
|
212 |
return twistNum + 729*permNum; |
|
213 |
} |
|
214 |
|
|
215 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
216 |
|
|
217 |
private int getColorIndex4(int face) |
|
218 |
{ |
|
219 |
switch(mFaceColors[face]) |
|
220 |
{ |
|
221 |
case 0: return R.string.color_yellow4; |
|
222 |
case 1: return R.string.color_white4; |
|
223 |
case 2: return R.string.color_blue4; |
|
224 |
case 3: return R.string.color_green4; |
|
225 |
case 4: return R.string.color_red4; |
|
226 |
case 5: return R.string.color_orange4; |
|
227 |
} |
|
228 |
|
|
229 |
return -1; |
|
230 |
} |
|
231 |
|
|
232 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
233 |
|
|
234 |
private int getColorIndex3(int face) |
|
235 |
{ |
|
236 |
switch(mFaceColors[face]) |
|
237 |
{ |
|
238 |
case 0: return R.string.color_yellow3; |
|
239 |
case 1: return R.string.color_white3; |
|
240 |
case 2: return R.string.color_blue3; |
|
241 |
case 3: return R.string.color_green3; |
|
242 |
case 4: return R.string.color_red3; |
|
243 |
case 5: return R.string.color_orange3; |
|
244 |
} |
|
245 |
|
|
246 |
return -1; |
|
247 |
} |
|
248 |
|
|
249 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
250 |
|
|
251 |
private String cornerError(Resources res, int face0, int face1, int face2) |
|
252 |
{ |
|
253 |
int j0 = getColorIndex3(face0); |
|
254 |
int j1 = getColorIndex3(face1); |
|
255 |
int j2 = getColorIndex4(face2); |
|
256 |
|
|
257 |
String c0 = res.getString(j0); |
|
258 |
String c1 = res.getString(j1); |
|
259 |
String c2 = res.getString(j2); |
|
260 |
|
|
261 |
return res.getString(R.string.solver_generic_missing_corner,c0,c1,c2); |
|
262 |
} |
|
263 |
|
|
264 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
265 |
|
|
266 |
public String error(int index, Resources res) |
|
267 |
{ |
|
268 |
switch(index) |
|
269 |
{ |
|
270 |
case ERROR_CORNER_135_MISSING: return cornerError(res,1,3,5); |
|
271 |
case ERROR_CORNER_134_MISSING: return cornerError(res,1,3,4); |
|
272 |
case ERROR_CORNER_125_MISSING: return cornerError(res,1,2,5); |
|
273 |
case ERROR_CORNER_124_MISSING: return cornerError(res,1,2,4); |
|
274 |
case ERROR_CORNER_035_MISSING: return cornerError(res,0,3,5); |
|
275 |
case ERROR_CORNER_034_MISSING: return cornerError(res,0,3,4); |
|
276 |
case ERROR_CORNER_025_MISSING: return cornerError(res,0,2,5); |
|
277 |
case ERROR_CORNER_024_MISSING: return cornerError(res,0,2,4); |
|
278 |
case ERROR_CORNERS_CANNOT : return res.getString(R.string.solver_generic_corners_cannot); |
|
279 |
case ERROR_CORNER_TWISTED : return res.getString(R.string.solver_generic_corner_twist); |
|
280 |
} |
|
281 |
|
|
282 |
return null; |
|
283 |
} |
|
284 |
|
|
285 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
286 |
|
|
287 |
public int[][] solution(int index, OperatingSystemInterface os) |
|
288 |
{ |
|
289 |
if( mSolver==null ) |
|
290 |
{ |
|
291 |
mSolver = ImplementedTablebasesList.createPacked(os, ListObjects.CUBE_2.name() ); |
|
292 |
} |
|
293 |
|
|
294 |
return mSolver!=null ? mSolver.solution(index,null,os) : null; |
|
295 |
} |
|
296 |
} |
|
297 |
|
src/main/java/org/distorted/solvers/SolverCube3.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2023 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.main.R; |
|
15 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
16 |
import org.distorted.solverui.ScreenSolver; |
|
17 |
import org.distorted.objectlib.main.TwistyObject; |
|
18 |
import org.distorted.objectlib.kociemba.SolverSearch; |
|
19 |
|
|
20 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
21 |
|
|
22 |
public class SolverCube3 |
|
23 |
{ |
|
24 |
private final Resources mRes; |
|
25 |
private final OperatingSystemInterface mOS; |
|
26 |
private final TwistyObject mObject; |
|
27 |
private int mColorID; |
|
28 |
|
|
29 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
30 |
|
|
31 |
private int mapCubitToFace(int cubit, int face) |
|
32 |
{ |
|
33 |
if( cubit<8 ) |
|
34 |
{ |
|
35 |
switch(face) |
|
36 |
{ |
|
37 |
case 0: return 1; |
|
38 |
case 1: if( cubit==2 ) return 5; |
|
39 |
if( cubit==1 ) return 3; |
|
40 |
return 1; |
|
41 |
case 2: return cubit==7 ? 5 : 3; |
|
42 |
case 3: if( cubit==1 ) return 1; |
|
43 |
return cubit==4 ? 5 : 3; |
|
44 |
case 4: return cubit==7 ? 3 : 5; |
|
45 |
case 5: if( cubit==2 ) return 1; |
|
46 |
if( cubit==4 ) return 3; |
|
47 |
return 5; |
|
48 |
} |
|
49 |
} |
|
50 |
|
|
51 |
if( cubit>19 ) return 4; |
|
52 |
|
|
53 |
switch(face) |
|
54 |
{ |
|
55 |
case 0: return cubit==15 || cubit==18 ? 3 : 5; |
|
56 |
case 1: return cubit==13 || cubit==16 ? 3 : 5; |
|
57 |
case 2: return cubit==10 ? 5 : 3; |
|
58 |
case 3: return cubit== 8 ? 3 : 5; |
|
59 |
case 4: return cubit== 9 ? 3 : 5; |
|
60 |
case 5: return cubit== 8 ? 5 : 3; |
|
61 |
} |
|
62 |
|
|
63 |
return -1; |
|
64 |
} |
|
65 |
|
|
66 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
67 |
|
|
68 |
private int checkPosition(String position) |
|
69 |
{ |
|
70 |
int[] numColors = new int[6]; |
|
71 |
int len = position.length(); |
|
72 |
|
|
73 |
for(int i=0; i<len; i++) |
|
74 |
{ |
|
75 |
char ch = position.charAt(i); |
|
76 |
|
|
77 |
switch(ch) |
|
78 |
{ |
|
79 |
case 'R': numColors[0]++; break; |
|
80 |
case 'L': numColors[1]++; break; |
|
81 |
case 'U': numColors[2]++; break; |
|
82 |
case 'D': numColors[3]++; break; |
|
83 |
case 'F': numColors[4]++; break; |
|
84 |
case 'B': numColors[5]++; break; |
|
85 |
} |
|
86 |
} |
|
87 |
|
|
88 |
if( numColors[0]<9 ) { mColorID = R.string.color_yellow1; return numColors[0]; } |
|
89 |
if( numColors[1]<9 ) { mColorID = R.string.color_white1 ; return numColors[1]; } |
|
90 |
if( numColors[2]<9 ) { mColorID = R.string.color_blue1 ; return numColors[2]; } |
|
91 |
if( numColors[3]<9 ) { mColorID = R.string.color_green1 ; return numColors[3]; } |
|
92 |
if( numColors[4]<9 ) { mColorID = R.string.color_red1 ; return numColors[4]; } |
|
93 |
if( numColors[5]<9 ) { mColorID = R.string.color_orange1; return numColors[5]; } |
|
94 |
|
|
95 |
return -1; |
|
96 |
} |
|
97 |
|
|
98 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
99 |
// order: Up --> Right --> Front --> Down --> Left --> Back |
|
100 |
// (because the first implemented Solver - the two-phase Cube3 one - expects such order) |
|
101 |
// |
|
102 |
// Solved 3x3x3 Cube maps to "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB" |
|
103 |
|
|
104 |
private String preparePosition() |
|
105 |
{ |
|
106 |
StringBuilder objectString = new StringBuilder(); |
|
107 |
|
|
108 |
final int R = 0; |
|
109 |
final int L = 1; |
|
110 |
final int U = 2; |
|
111 |
final int D = 3; |
|
112 |
final int F = 4; |
|
113 |
final int B = 5; |
|
114 |
|
|
115 |
// 'I' - interior, theoretically can happen |
|
116 |
final char[] FACE_NAMES = { 'R', 'L', 'U', 'D', 'F', 'B', 'I'}; |
|
117 |
|
|
118 |
final int[] U_INDEX = { 2,10, 6,17,22,19, 3,11, 7}; |
|
119 |
final int[] R_INDEX = { 7,19, 6,15,20,14, 5,18, 4}; |
|
120 |
final int[] F_INDEX = { 3,11, 7,13,24,15, 1, 9, 5}; |
|
121 |
final int[] D_INDEX = { 1, 9, 5,16,23,18, 0, 8, 4}; |
|
122 |
final int[] L_INDEX = { 2,17, 3,12,21,13, 0,16, 1}; |
|
123 |
final int[] B_INDEX = { 6,10, 2,14,25,12, 4, 8, 0}; |
|
124 |
|
|
125 |
for(int i=0; i<9; i++) |
|
126 |
{ |
|
127 |
int face = mapCubitToFace(U_INDEX[i],U); |
|
128 |
int color = mObject.getCubitFaceStickerIndex(U_INDEX[i], face); |
|
129 |
objectString.append(FACE_NAMES[color]); |
|
130 |
} |
|
131 |
for(int i=0; i<9; i++) |
|
132 |
{ |
|
133 |
int face = mapCubitToFace(R_INDEX[i],R); |
|
134 |
int color = mObject.getCubitFaceStickerIndex(R_INDEX[i], face); |
|
135 |
objectString.append(FACE_NAMES[color]); |
|
136 |
} |
|
137 |
for(int i=0; i<9; i++) |
|
138 |
{ |
|
139 |
int face = mapCubitToFace(F_INDEX[i],F); |
|
140 |
int color = mObject.getCubitFaceStickerIndex(F_INDEX[i], face); |
|
141 |
objectString.append(FACE_NAMES[color]); |
|
142 |
} |
|
143 |
for(int i=0; i<9; i++) |
|
144 |
{ |
|
145 |
int face = mapCubitToFace(D_INDEX[i],D); |
|
146 |
int color = mObject.getCubitFaceStickerIndex(D_INDEX[i], face); |
|
147 |
objectString.append(FACE_NAMES[color]); |
|
148 |
} |
|
149 |
for(int i=0; i<9; i++) |
|
150 |
{ |
|
151 |
int face = mapCubitToFace(L_INDEX[i],L); |
|
152 |
int color = mObject.getCubitFaceStickerIndex(L_INDEX[i], face); |
|
153 |
objectString.append(FACE_NAMES[color]); |
|
154 |
} |
|
155 |
for(int i=0; i<9; i++) |
|
156 |
{ |
|
157 |
int face = mapCubitToFace(B_INDEX[i],B); |
|
158 |
int color = mObject.getCubitFaceStickerIndex(B_INDEX[i], face); |
|
159 |
objectString.append(FACE_NAMES[color]); |
|
160 |
} |
|
161 |
|
|
162 |
return objectString.toString(); |
|
163 |
} |
|
164 |
|
|
165 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
166 |
// PUBLIC API |
|
167 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
168 |
|
|
169 |
public SolverCube3(OperatingSystemInterface os, Resources res, TwistyObject object) |
|
170 |
{ |
|
171 |
mRes = res; |
|
172 |
mOS = os; |
|
173 |
mObject= object; |
|
174 |
} |
|
175 |
|
|
176 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
177 |
|
|
178 |
public void solve(ScreenSolver solver) |
|
179 |
{ |
|
180 |
String result; |
|
181 |
|
|
182 |
SolverSearch.prepare(mOS); |
|
183 |
String objectPosition = preparePosition(); |
|
184 |
int check = checkPosition(objectPosition); |
|
185 |
|
|
186 |
if( check<0 ) |
|
187 |
{ |
|
188 |
result = SolverSearch.solution(objectPosition, 24, 20); |
|
189 |
|
|
190 |
if (result.contains("Error")) |
|
191 |
{ |
|
192 |
switch (result.charAt(result.length() - 1)) |
|
193 |
{ |
|
194 |
case '1': result = mRes.getString(R.string.solver_cube3_error1); break; |
|
195 |
case '2': result = mRes.getString(R.string.solver_cube3_error2); break; |
|
196 |
case '3': result = mRes.getString(R.string.solver_generic_edge_twist); break; |
|
197 |
case '4': result = mRes.getString(R.string.solver_cube3_error4); break; |
|
198 |
case '5': result = mRes.getString(R.string.solver_generic_corner_twist); break; |
|
199 |
case '6': result = mRes.getString(R.string.solver_cube3_error6); break; |
|
200 |
case '7': result = mRes.getString(R.string.solver_cube3_error7); break; |
|
201 |
case '8': result = mRes.getString(R.string.solver_cube3_error8); break; |
|
202 |
case '9': result = mRes.getString(R.string.solver_cube3_error9); break; |
|
203 |
} |
|
204 |
|
|
205 |
solver.displayImpossibleDialog(result); |
|
206 |
} |
|
207 |
else |
|
208 |
{ |
|
209 |
solver.setSolved(result); |
|
210 |
} |
|
211 |
} |
|
212 |
else |
|
213 |
{ |
|
214 |
String color = mRes.getString(mColorID); |
|
215 |
result = mRes.getString(R.string.solver_cube3_error1,check,color); |
|
216 |
solver.displayImpossibleDialog(result); |
|
217 |
} |
|
218 |
} |
|
219 |
} |
|
220 |
|
src/main/java/org/distorted/solvers/SolverCuboid232.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2023 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.main.R; |
|
15 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
16 |
import org.distorted.objectlib.metadata.ListObjects; |
|
17 |
import org.distorted.objectlib.main.TwistyObject; |
|
18 |
import org.distorted.objectlib.tablebases.ImplementedTablebasesList; |
|
19 |
import org.distorted.objectlib.tablebases.TablebaseHelpers; |
|
20 |
import org.distorted.objectlib.tablebases.TablebasesAbstract; |
|
21 |
|
|
22 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
23 |
|
|
24 |
public class SolverCuboid232 extends SolverTablebase |
|
25 |
{ |
|
26 |
private static final int ERROR_CORNER_135_MISSING = -1; |
|
27 |
private static final int ERROR_CORNER_134_MISSING = -2; |
|
28 |
private static final int ERROR_CORNER_125_MISSING = -3; |
|
29 |
private static final int ERROR_CORNER_124_MISSING = -4; |
|
30 |
private static final int ERROR_CORNER_035_MISSING = -5; |
|
31 |
private static final int ERROR_CORNER_034_MISSING = -6; |
|
32 |
private static final int ERROR_CORNER_025_MISSING = -7; |
|
33 |
private static final int ERROR_CORNER_024_MISSING = -8; |
|
34 |
|
|
35 |
private static final int ERROR_EDGE_15_MISSING = -9; |
|
36 |
private static final int ERROR_EDGE_14_MISSING = -10; |
|
37 |
private static final int ERROR_EDGE_05_MISSING = -11; |
|
38 |
private static final int ERROR_EDGE_04_MISSING = -12; |
|
39 |
|
|
40 |
private static final int ERROR_CORNERS_CANNOT = -13; |
|
41 |
private static final int ERROR_EDGE_TWISTED = -14; |
|
42 |
private static final int ERROR_CORNER_TWISTED = -15; |
|
43 |
|
|
44 |
TablebasesAbstract mSolver; |
|
45 |
private final int[] mFaceColors; |
|
46 |
|
|
47 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
48 |
|
|
49 |
private int edgeIs(int[] edge, int i0, int i1) |
|
50 |
{ |
|
51 |
int c0 = mFaceColors[i0]; |
|
52 |
int c1 = mFaceColors[i1]; |
|
53 |
|
|
54 |
if( edge[0]==c0 && edge[1]==c1 ) return 0; |
|
55 |
if( edge[0]==c1 && edge[1]==c0 ) return 1; |
|
56 |
return 2; |
|
57 |
} |
|
58 |
|
|
59 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
60 |
|
|
61 |
private int retEdgePermutation(int[] output, int[][] edges) |
|
62 |
{ |
|
63 |
for(int i=0; i<4; i++) output[i] = -1; |
|
64 |
|
|
65 |
for(int i=0; i<4; i++) |
|
66 |
{ |
|
67 |
int edge0 = edgeIs(edges[i],1,5); |
|
68 |
if( edge0==0 ) output[0]=i; |
|
69 |
else if( edge0==1 ) return ERROR_EDGE_TWISTED; |
|
70 |
|
|
71 |
int edge1 = edgeIs(edges[i],1,4); |
|
72 |
if( edge1==0 ) output[1]=i; |
|
73 |
else if( edge1==1 ) return ERROR_EDGE_TWISTED; |
|
74 |
|
|
75 |
int edge2 = edgeIs(edges[i],0,5); |
|
76 |
if( edge2==0 ) output[2]=i; |
|
77 |
else if( edge2==1 ) return ERROR_EDGE_TWISTED; |
|
78 |
|
|
79 |
int edge3 = edgeIs(edges[i],0,4); |
|
80 |
if( edge3==0 ) output[3]=i; |
|
81 |
else if( edge3==1 ) return ERROR_EDGE_TWISTED; |
|
82 |
} |
|
83 |
|
|
84 |
if( output[0]==-1 ) return ERROR_EDGE_15_MISSING; |
|
85 |
if( output[1]==-1 ) return ERROR_EDGE_14_MISSING; |
|
86 |
if( output[2]==-1 ) return ERROR_EDGE_05_MISSING; |
|
87 |
if( output[3]==-1 ) return ERROR_EDGE_04_MISSING; |
|
88 |
|
|
89 |
return 0; |
|
90 |
} |
|
91 |
|
|
92 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
93 |
|
|
94 |
private int cornerIs(int[] corner, int i0, int i1, int i2) |
|
95 |
{ |
|
96 |
int c0 = mFaceColors[i0]; |
|
97 |
int c1 = mFaceColors[i1]; |
|
98 |
int c2 = mFaceColors[i2]; |
|
99 |
|
|
100 |
if( corner[0]==c0 && corner[1]==c1 && corner[2]==c2 ) return 0; |
|
101 |
|
|
102 |
if( corner[0]==c0 && corner[1]==c2 && corner[2]==c1 || |
|
103 |
corner[0]==c1 && corner[1]==c0 && corner[2]==c2 || |
|
104 |
corner[0]==c1 && corner[1]==c2 && corner[2]==c0 || |
|
105 |
corner[0]==c2 && corner[1]==c0 && corner[2]==c1 || |
|
106 |
corner[0]==c2 && corner[1]==c1 && corner[2]==c0 ) return 1; |
|
107 |
|
|
108 |
return 2; |
|
109 |
} |
|
110 |
|
|
111 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
112 |
|
|
113 |
private int retCornerPermutation(int[] output, int[][] corners) |
|
114 |
{ |
|
115 |
for(int i=0; i<8; i++) output[i] = -1; |
|
116 |
|
|
117 |
for(int i=0; i<8; i++) |
|
118 |
{ |
|
119 |
int corner7 = cornerIs(corners[i],2,4,0); |
|
120 |
if( corner7==0 ) output[7]=i; |
|
121 |
else if( corner7==1 ) return ERROR_CORNER_TWISTED; |
|
122 |
|
|
123 |
int corner6 = cornerIs(corners[i],2,0,5); |
|
124 |
if( corner6==0 ) output[6]=i; |
|
125 |
else if( corner6==1 ) return ERROR_CORNER_TWISTED; |
|
126 |
|
|
127 |
int corner5 = cornerIs(corners[i],3,0,4); |
|
128 |
if( corner5==0 ) output[5]=i; |
|
129 |
else if( corner5==1 ) return ERROR_CORNER_TWISTED; |
|
130 |
|
|
131 |
int corner4 = cornerIs(corners[i],3,5,0); |
|
132 |
if( corner4==0 ) output[4]=i; |
Also available in: Unified diff
Progeress towards automatically integrating the Algorithmic solvers into the list of solvers in the App.