I have a list of absolute points of screen like bellow :
355.2599 : 408.4894
353.31705 : 409.43512
341.44516 : 418.35184
329.3344 : 427.5607
314.9433 : 435.21622
304.6277 : 440.36212
292.61746 : 444.36887
And i have some other points like below :
160.66528 : 513.35834
319.33472 : 230.71161
304.3659 : 479.40076
How can i know second points is in first points?
for example when points different was less than 10 dp it should be return found;
private boolean checkValidate(List<Point> first, List<Point> second)
{
int accuracy = Helper.dpToPixel(this, 10);
int pointSize = first.size();
int pointFlag = 0;
List<Boolean> poinsValidation = new ArrayList<>();
for(Point line : second)
{
if(pointSize != 0 && pointFlag < pointSize)
{
if(Math.abs(first.get(pointFlag).x - line.x ) <= accuracy && Math.abs(first.get(pointFlag).y - line.y ) <= accuracy)
{
poinsValidation.add(true);
pointFlag++;
}
}
}
if(poinsValidation.size() == first.size())
{
return true;
}
return false;
}
I would suggest nested looping through both arrays. Although nested looping is not preferred, at this stage I cannot think of another way to do it.
private boolean checkValidate(List<Point> first, List<Point> second)
{
int accuracy = Helper.dpToPixel(this, 10);
int pointSize = first.size();
int pointSize2 = second.size();
int pointFlag = 0;
List<Boolean> poinsValidation = new ArrayList<>();
for(Point line : second)
{
for(Point points: first){
if(pointSize != 0 && pointSize2 != 0 && pointFlag < pointSize)
{
if(Math.abs(points.x - line.x ) <= accuracy && Math.abs(points.y - line.y ) <= accuracy)
{
poinsValidation.add(true);
pointFlag++;
}
}
}
}
if(poinsValidation.size() == first.size())
{
return true;
}
return false;
}
Let me know if this helps.
Related
I'm going to use Luxand api for detect persons.
Scenario:
1- At the first on register activity persons sit in front of the camera and take pictures and templates save on sqlite database. also personal information will be save;
2- After that On detect activity one of them sit in front of the camera and take Auto detection and find same temp and show person information.(similarity is 96%)
my problem:Unfortunately too times detection is wrong and two different people’s templates will be recognized as the same person.
My Code:
1- Register activity for register form
for (int i = 0; i < MAX_FACES; ++i) {
if (rects[i] != null && rects[i].x1 <= x && x <= rects[i].x2 && rects[i].y1 <= y && y <= rects[i].y2 + 30) {
mTouchedID = IDs[i];
mTouchedIndex = i;
temp = (byte[]) ImageFrameFaceIDTemps.get(mTouchedID);
if (mPreview != null) {
onTouchMode = true;
try {
requesting name on tapping the face
if (faceSelected != null) {
faceSelected.Selected(temp, data);
}
} finally {
onTouchMode = false;
}
}
break;
}
2- Detection activity for match form
public int RetrievePersonDetection(byte[] template, float[] maxSimilarity_UnderAccepted, float[] maxSimilarityArray) {
if (IDTemps == null || IDTemps.size() == 0) {
return 0;
}
int person = 0;
FSDK_FaceTemplate currentFaceTemp = new FSDK_FaceTemplate();
currentFaceTemp.template = template;
float[] similarityArray = new float[1];
float maxSimilarity = 0;
float MatchingThreshold[] = new float[1];
FSDK.GetMatchingThresholdAtFRR(LocalSetting.MIN_ACCEPTED_SIMILAITY, MatchingThreshold);
for (int i = 0; i < IDTemps.size(); i++) {
long key = IDTemps.keyAt(i);
FSDK_FaceTemplate faceTemp = (FSDK_FaceTemplate) IDTemps.get(key);
int result = FSDK.MatchFaces(currentFaceTemp, faceTemp, similarityArray);
if (result == 0) {
if (maxSimilarity < similarityArray[0] && similarityArray[0] >= MatchingThreshold[0]) {
maxSimilarity = similarityArray[0];
person = (int) key;
maxSimilarityArray[0] = similarityArray[0];
FSDK_FaceTemplate currentFaceTemp2 = new FSDK_FaceTemplate();
}
else if (maxSimilarity_UnderAccepted[0] < similarityArray[0]) {
maxSimilarity_UnderAccepted[0] = similarityArray[0];
}
}
}
return person;
}
I don't no what's my problem? why return wrong person and 2 person similarity is 96%
I want to Justify text inside Android TextView. With copy and share function and can accept spannable string. Can someone help me. It's so important for me. Thank you in advance
I have a solution for the text-justify in Android.
I have created a Custom Textview class, with this you can solve the justification issue in Android.
<com.trailcreator.util.JustifyCustomTextView
android:id="#+id/yourTextViewID"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Here is the class
public class JustifyCustomTextView extends android.support.v7.widget.AppCompatTextView {
//Object that helps us to measure the words and characters like spaces.
private Paint mPaint;
//Thin space (Hair Space actually) character that will fill the spaces
private String mThinSpace = "\u200A";
//String that will storage the text with the inserted spaces
private String mJustifiedText = "";
//Float that represents the actual width of a sentence
private float mSentenceWidth = 0;
//Integer that counts the spaces needed to fill the line being processed
private int mWhiteSpacesNeeded = 0;
//Integer that counts the actual amount of words in the sentence
private int mWordsInThisSentence = 0;
//ArrayList of Strings that will contain the words of the sentence being processed
private ArrayList<String> mTemporalLine = new ArrayList<String>();
//StringBuilder that will hold the temporal chunk of the string to calculate word index.
private StringBuilder mStringBuilderCSequence = new StringBuilder();
//List of SpanHolder class that will hold the spans within the giving string.
private List<SpanHolder> mSpanHolderList = new ArrayList<>();
//StringBuilder that will store temp data for joining sentence.
private StringBuilder sentence = new StringBuilder();
private int mViewWidth;
private float mThinSpaceWidth;
private float mWhiteSpaceWidth;
//Default Constructors!
public JustifyCustomTextView(Context context) {
super(context);
}
public JustifyCustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public JustifyCustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mJustifiedText.replace(" ", "")
.replace("", mThinSpace)
.equals(this.getText().toString().replace(" ", "").replace("", mThinSpace))) {
return;
}
ViewGroup.LayoutParams params = this.getLayoutParams();
CharSequence charSequence = this.getText();
mSpanHolderList.clear();
String[] words = this.getText().toString().split(" ");
//Get spans within the string and adds the instance references into the
//SpanHolderList to be applied once the justify process has been performed.
SpannableString s = SpannableString.valueOf(charSequence);
if ((charSequence instanceof SpannedString)) {
for (int i = 0; i < this.getText().length() - 1; i++) {
CharacterStyle[] spans =
((SpannedString) charSequence).getSpans(i, i + 1, CharacterStyle.class);
if (spans != null && spans.length > 0) {
for (CharacterStyle span : spans) {
int spaces =
charSequence.toString().substring(0, i).split(" ").length + charSequence.toString()
.substring(0, i)
.split(mThinSpace).length;
SpanHolder spanHolder =
SpanHolder.getNewInstance(spans, s.getSpanStart(span), s.getSpanEnd(span), spaces);
mStringBuilderCSequence.setLength(0);
for (int j = 0; j <= words.length - 1; j++) {
mStringBuilderCSequence.append(words[j]);
mStringBuilderCSequence.append(" ");
if (mStringBuilderCSequence.length() > i) {
if (words[j].trim().replace(mThinSpace, "").length() == 1) {
spanHolder.setWordHolderIndex(j);
} else {
spanHolder.setWordHolderIndex(j);
spanHolder.setTextChunkPadded(true);
}
break;
}
}
mSpanHolderList.add(spanHolder);
}
}
}
}
mPaint = this.getPaint();
mViewWidth = this.getMeasuredWidth() - (getPaddingLeft() + getPaddingRight());
//This class won't justify the text if the TextView has wrap_content as width
//And won't repeat the process of justify text if it's already done.
//AND! won't justify the text if the view width is 0
if (params.width != ViewGroup.LayoutParams.WRAP_CONTENT
&& mViewWidth > 0
&& words.length > 0
&& mJustifiedText.isEmpty()) {
mThinSpaceWidth = mPaint.measureText(mThinSpace);
mWhiteSpaceWidth = mPaint.measureText(" ");
for (int i = 0; i <= words.length - 1; i++) {
boolean containsNewLine = (words[i].contains("\n") || words[i].contains("\r"));
if (containsNewLine) {
String[] splitted = words[i].split("(?<=\\n)");
for (String splitWord : splitted) {
processWord(splitWord, splitWord.contains("\n"));
}
} else {
processWord(words[i], false);
}
}
mJustifiedText += joinWords(mTemporalLine);
}
//Apply the extra spaces to the items of the SpanList that were added due
//the justifying process.
SpannableString spannableString = SpannableString.valueOf(mJustifiedText);
for (SpanHolder sH : mSpanHolderList) {
int spaceCount = 0, wordCount = 0;
boolean isCountingWord = false;
int j = 0;
while (wordCount < (sH.getWordHolderIndex() + 1)) {
if (mJustifiedText.charAt(j) == ' ' || mJustifiedText.charAt(j) == ' ') {
spaceCount++;
if (isCountingWord) {
wordCount++;
}
isCountingWord = false;
} else {
isCountingWord = true;
}
j++;
}
sH.setStart(
sH.getStart() + spaceCount - sH.getCurrentSpaces() + (sH.isTextChunkPadded() ? 1 : 0));
sH.setEnd(
sH.getEnd() + spaceCount - sH.getCurrentSpaces() + (sH.isTextChunkPadded() ? 1 : 0));
}
//Applies spans on Justified String.
for (SpanHolder sH : mSpanHolderList) {
for (CharacterStyle cS : sH.getSpans())
spannableString.setSpan(cS, sH.getStart(), sH.getEnd(), 0);
}
if (!mJustifiedText.isEmpty()) this.setText(spannableString);
}
private void processWord(String word, boolean containsNewLine) {
if ((mSentenceWidth + mPaint.measureText(word)) < mViewWidth) {
mTemporalLine.add(word);
mWordsInThisSentence++;
mTemporalLine.add(containsNewLine ? "" : " ");
mSentenceWidth += mPaint.measureText(word) + mWhiteSpaceWidth;
if (containsNewLine) {
mJustifiedText += joinWords(mTemporalLine);
resetLineValues();
}
} else {
while (mSentenceWidth < mViewWidth) {
mSentenceWidth += mThinSpaceWidth;
if (mSentenceWidth < mViewWidth) mWhiteSpacesNeeded++;
}
if (mWordsInThisSentence > 1) {
insertWhiteSpaces(mWhiteSpacesNeeded, mWordsInThisSentence, mTemporalLine);
}
mJustifiedText += joinWords(mTemporalLine);
resetLineValues();
if (containsNewLine) {
mJustifiedText += word;
mWordsInThisSentence = 0;
return;
}
mTemporalLine.add(word);
mWordsInThisSentence = 1;
mTemporalLine.add(" ");
mSentenceWidth += mPaint.measureText(word) + mWhiteSpaceWidth;
}
}
//Method that resets the values of the actual line being processed
private void resetLineValues() {
mTemporalLine.clear();
mSentenceWidth = 0;
mWhiteSpacesNeeded = 0;
mWordsInThisSentence = 0;
}
//Function that joins the words of the ArrayList
private String joinWords(ArrayList<String> words) {
sentence.setLength(0);
for (String word : words) {
sentence.append(word);
}
return sentence.toString();
}
//Method that inserts spaces into the words to make them fix perfectly in the width of the view. I know I'm a genius naming stuff :)
private void insertWhiteSpaces(int whiteSpacesNeeded, int wordsInThisSentence,
ArrayList<String> sentence) {
if (whiteSpacesNeeded == 0) return;
if (whiteSpacesNeeded == wordsInThisSentence) {
for (int i = 1; i < sentence.size(); i += 2) {
sentence.set(i, sentence.get(i) + mThinSpace);
}
} else if (whiteSpacesNeeded < wordsInThisSentence) {
for (int i = 0; i < whiteSpacesNeeded; i++) {
int randomPosition = getRandomEvenNumber(sentence.size() - 1);
sentence.set(randomPosition, sentence.get(randomPosition) + mThinSpace);
}
} else if (whiteSpacesNeeded > wordsInThisSentence) {
//I was using recursion to achieve this... but when you tried to watch the preview,
//Android Studio couldn't show any preview because a StackOverflow happened.
//So... it ended like this, with a wild while xD.
while (whiteSpacesNeeded > wordsInThisSentence) {
for (int i = 1; i < sentence.size() - 1; i += 2) {
sentence.set(i, sentence.get(i) + mThinSpace);
}
whiteSpacesNeeded -= (wordsInThisSentence - 1);
}
if (whiteSpacesNeeded == 0) return;
if (whiteSpacesNeeded == wordsInThisSentence) {
for (int i = 1; i < sentence.size(); i += 2) {
sentence.set(i, sentence.get(i) + mThinSpace);
}
} else if (whiteSpacesNeeded < wordsInThisSentence) {
for (int i = 0; i < whiteSpacesNeeded; i++) {
int randomPosition = getRandomEvenNumber(sentence.size() - 1);
sentence.set(randomPosition, sentence.get(randomPosition) + mThinSpace);
}
}
}
}
//Gets a random number, it's part of the algorithm... don't blame me.
private int getRandomEvenNumber(int max) {
Random rand = new Random();
// nextInt is normally exclusive of the top value,
return rand.nextInt((max)) & ~1;
}
}
public class SpanHolder {
private CharacterStyle[] spans;
private int start;
private int end;
private boolean textChunkPadded =false;
private int wordHolderIndex;
private int currentSpaces;
public SpanHolder(CharacterStyle[] spans, int start, int end, int spaces){
this.setSpans(spans);
this.setStart(start);
this.setEnd(end);
this.setCurrentSpaces(spaces);
}
public static SpanHolder getNewInstance(CharacterStyle[] spans, int start, int end, int spaces){
return new SpanHolder(spans,start,end,spaces);
}
public boolean isTextChunkPadded() {
return textChunkPadded;
}
public void setTextChunkPadded(boolean textChunkPadded) {
this.textChunkPadded = textChunkPadded;
}
public int getWordHolderIndex() {
return wordHolderIndex;
}
public void setWordHolderIndex(int wordHolderIndex) {
this.wordHolderIndex = wordHolderIndex;
}
public CharacterStyle[] getSpans() {
return spans;
}
public void setSpans(CharacterStyle[] spans) {
this.spans = spans;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public int getCurrentSpaces() {
return currentSpaces;
}
public void setCurrentSpaces(int currentSpaces) {
this.currentSpaces = currentSpaces;
}
}
GOOD LUCK! (Y)
How to compare app version in android
I got latest version code and current version code , but the problem is
current version is 1.0
and latest version is 1.0.0
so how to compare that float value in android
I have written a small Android library for comparing version numbers: https://github.com/G00fY2/version-compare
What it basically does is this:
public int compareVersions(String versionA, String versionB) {
String[] versionTokensA = versionA.split("\\.");
String[] versionTokensB = versionB.split("\\.");
List<Integer> versionNumbersA = new ArrayList<>();
List<Integer> versionNumbersB = new ArrayList<>();
for (String versionToken : versionTokensA) {
versionNumbersA.add(Integer.parseInt(versionToken));
}
for (String versionToken : versionTokensB) {
versionNumbersB.add(Integer.parseInt(versionToken));
}
final int versionASize = versionNumbersA.size();
final int versionBSize = versionNumbersB.size();
int maxSize = Math.max(versionASize, versionBSize);
for (int i = 0; i < maxSize; i++) {
if ((i < versionASize ? versionNumbersA.get(i) : 0) > (i < versionBSize ? versionNumbersB.get(i) : 0)) {
return 1;
} else if ((i < versionASize ? versionNumbersA.get(i) : 0) < (i < versionBSize ? versionNumbersB.get(i) : 0)) {
return -1;
}
}
return 0;
}
This snippet doesn't offer any error checks or handling. Beside that my library also supports suffixes like "1.2-rc" > "1.2-beta".
I am a bit late to the party but I have a great solution for all of you!
1. Use this class:
public class VersionComparator implements Comparator {
public boolean equals(Object o1, Object o2) {
return compare(o1, o2) == 0;
}
public int compare(Object o1, Object o2) {
String version1 = (String) o1;
String version2 = (String) o2;
VersionTokenizer tokenizer1 = new VersionTokenizer(version1);
VersionTokenizer tokenizer2 = new VersionTokenizer(version2);
int number1, number2;
String suffix1, suffix2;
while (tokenizer1.MoveNext()) {
if (!tokenizer2.MoveNext()) {
do {
number1 = tokenizer1.getNumber();
suffix1 = tokenizer1.getSuffix();
if (number1 != 0 || suffix1.length() != 0) {
// Version one is longer than number two, and non-zero
return 1;
}
}
while (tokenizer1.MoveNext());
// Version one is longer than version two, but zero
return 0;
}
number1 = tokenizer1.getNumber();
suffix1 = tokenizer1.getSuffix();
number2 = tokenizer2.getNumber();
suffix2 = tokenizer2.getSuffix();
if (number1 < number2) {
// Number one is less than number two
return -1;
}
if (number1 > number2) {
// Number one is greater than number two
return 1;
}
boolean empty1 = suffix1.length() == 0;
boolean empty2 = suffix2.length() == 0;
if (empty1 && empty2) continue; // No suffixes
if (empty1) return 1; // First suffix is empty (1.2 > 1.2b)
if (empty2) return -1; // Second suffix is empty (1.2a < 1.2)
// Lexical comparison of suffixes
int result = suffix1.compareTo(suffix2);
if (result != 0) return result;
}
if (tokenizer2.MoveNext()) {
do {
number2 = tokenizer2.getNumber();
suffix2 = tokenizer2.getSuffix();
if (number2 != 0 || suffix2.length() != 0) {
// Version one is longer than version two, and non-zero
return -1;
}
}
while (tokenizer2.MoveNext());
// Version two is longer than version one, but zero
return 0;
}
return 0;
}
// VersionTokenizer.java
public static class VersionTokenizer {
private final String _versionString;
private final int _length;
private int _position;
private int _number;
private String _suffix;
private boolean _hasValue;
VersionTokenizer(String versionString) {
if (versionString == null)
throw new IllegalArgumentException("versionString is null");
_versionString = versionString;
_length = versionString.length();
}
public int getNumber() {
return _number;
}
String getSuffix() {
return _suffix;
}
public boolean hasValue() {
return _hasValue;
}
boolean MoveNext() {
_number = 0;
_suffix = "";
_hasValue = false;
// No more characters
if (_position >= _length)
return false;
_hasValue = true;
while (_position < _length) {
char c = _versionString.charAt(_position);
if (c < '0' || c > '9') break;
_number = _number * 10 + (c - '0');
_position++;
}
int suffixStart = _position;
while (_position < _length) {
char c = _versionString.charAt(_position);
if (c == '.') break;
_position++;
}
_suffix = _versionString.substring(suffixStart, _position);
if (_position < _length) _position++;
return true;
}
}
}
2. create this function
private fun isNewVersionAvailable(currentVersion: String, latestVersion: String): Boolean {
val versionComparator = VersionComparator()
val result: Int = versionComparator.compare(currentVersion, latestVersion)
var op = "=="
if (result < 0) op = "<"
if (result > 0) op = ">"
System.out.printf("%s %s %s\n", currentVersion, op, latestVersion)
return if (op == ">" || op == "==") {
false
} else op == "<"
}
3. and just call it by
e.g. isNewVersionAvailable("1.2.8","1.2.9") where 1.2.8 is your current version here and 1.2.9 is the latest version, which returns true!
Why overcomplicate this so much?
Just scale the major, minor, patch version and you have it covered:
fun getAppVersionFromString(version: String): Int { // "2.3.5"
val versions = version.split(".") // [2, 3, 5]
val major = versions[0].toIntOrDefault(0) * 10000 // 20000
val minor = versions[1].toIntOrDefault(0) * 1000 // 3000
val patch = versions[2].toIntOrDefault(0) * 100 // 500
return major + minor + patch // 2350
}
That way when you compare e.g 9.10.10 with 10.0.0 the second one is greater.
Use the following method to compare the versions number:
Convert float to String first.
public static int versionCompare(String str1, String str2) {
String[] vals1 = str1.split("\\.");
String[] vals2 = str2.split("\\.");
int i = 0;
// set index to first non-equal ordinal or length of shortest version string
while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) {
i++;
}
// compare first non-equal ordinal number
if (i < vals1.length && i < vals2.length) {
int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i]));
return Integer.signum(diff);
}
// the strings are equal or one string is a substring of the other
// e.g. "1.2.3" = "1.2.3" or "1.2.3" < "1.2.3.4"
return Integer.signum(vals1.length - vals2.length);
}
Refer the following SO question : Efficient way to compare version strings in Java
I am trying to do a jigsaw puzzle app in android. In this, I have split a Bitmap into many small chunks. These chunks are then displayed in a GridViewNow I need to shuffle them. Then, I need to know each image chunk's actualPosition(where the piece was supposed to be, its actual location in the image) and its currentPosition(where the piece is currently located). actualPosition and currentPosition are 2 integer arrays. So is there a way that I can get each image chunk's currentPosition and actualPosition after the shuffling so that after every move that the user make I can check wether every image chunk's actualPosition equals its currentPosition. If so the user wins the game. Can anyone please help me out.
Below is the number puzzle game in pure Java that works. Can be run from command line.
It re-prints the whole matrix after every move (not pretty). It demos the basic game.
I hope most of the code is self explanatory. This shows the basic 2-dim mapping of the game, position tracking, validating based on numbers. Have fun.
package madhav.turangi.basic.game;
import java.util.Random;
import java.util.Scanner;
public class NumberPuzzle {
int size;
int[][] arr;
int spaceRow;
int spaceCol;
int turnsTook;
public NumberPuzzle(int size) {
this.size = size;
arr = new int[size][size];
}
void init()
{
for(int r=0; r<size; r++)
{
for(int c=0; c<arr[r].length; c++)
{
arr[r][c] = r*size + c + 1; // row-column of cell to its value equation
}
}
spaceRow = spaceCol = size - 1; // bottom-right cell index
}
int readUserInput()
{
int value = -1;
boolean valid = false;
do {
System.out.printf("To move space [0 - Up, 1 - Down, 2 - Left, 3 - Right] : ? ");
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
try
{
value = Integer.parseInt(line);
valid = (value>=0 && value<=3);
}
catch(NumberFormatException ne)
{
}
if(! valid) System.out.println("== Invalid ==");
} while (! valid);
return value;
}
void swap(int aRow, int aCol, int withRow, int withCol)
{
int temp = arr[aRow][aCol];
arr[aRow][aCol] = arr[withRow][withCol];
arr[withRow][withCol] = temp;
}
boolean moveUp()
{
if(spaceRow != 0)
{
int newSpaceRow = spaceRow - 1;
swap(spaceRow, spaceCol, newSpaceRow, spaceCol);
spaceRow--;
return true;
}
else
{
return false;
}
}
boolean moveDown()
{
if(spaceRow != size-1)
{
int newSpaceRow = spaceRow + 1;
swap(spaceRow, spaceCol, newSpaceRow, spaceCol);
spaceRow++;
return true;
}
else
{
return false;
}
}
boolean moveRight()
{
if(spaceCol != size-1)
{
int newSpaceCol = spaceCol + 1;
swap(spaceRow, spaceCol, spaceRow, newSpaceCol);
spaceCol++;
return true;
}
else
{
return false;
}
}
boolean moveLeft()
{
if(spaceCol != 0)
{
int newSpaceCol = spaceCol - 1;
swap(spaceRow, spaceCol, spaceRow, newSpaceCol);
spaceCol--;
return true;
}
else
{
return false;
}
}
void shuffle()
{
Random rnd = new Random(System.currentTimeMillis());
boolean moved = false;
int attemptCount = 1;
int maxMoves = 20;
for(int moveCount=0; moveCount<maxMoves; moveCount++, attemptCount++)
{
int randomMoveDir = rnd.nextInt(4);
moved = move(randomMoveDir);
if(! moved) moveCount--; //ensure maxMoves number of moves
}
System.out.printf("Shuffle attempts %d\n",attemptCount);
}
boolean move(int dir)
{
boolean moved = false;
switch(dir)
{
case 0 : // up
moved = moveUp();
break;
case 1 : // down
moved = moveDown();
break;
case 2 : // left
moved = moveLeft();
break;
case 3 : // right
moved = moveRight();
break;
}
return moved;
}
void prnArray()
{
System.out.println("-- -- -- -- --");
for(int[] row : arr)
{
for(int cellValue : row)
{
String v = (cellValue == 16 ? "" : String.valueOf(cellValue));
System.out.printf("%4s", v);
}
System.out.println();
}
System.out.println("-- -- -- -- --");
}
boolean validate()
{
for(int r=0; r<size; r++)
{
for(int c=0; c<arr[r].length; c++)
{
if(arr[r][c] != (r*size + c + 1))
{
return false;
}
}
}
return true;
}
boolean oneTurn()
{
int dir = readUserInput();
boolean moved = move(dir);
boolean won = false;
if(moved)
{
turnsTook++;
prnArray();
won = validate();
}
else
{
System.out.println("= Invalid =");
}
return won;
}
void play()
{
init();
System.out.println("Before shuffle");
prnArray();
shuffle();
prnArray();
boolean won = false;
while(! won)
{
won = oneTurn();
}
System.out.printf("Won in %d\n", turnsTook);
}
public static void main(String[] args)
{
NumberPuzzle puzzle = new NumberPuzzle(4);
puzzle.play();
}
}
In android I'm trying to save grids that the user already have pressed.
Code snipping I’m using is:
// private
private HashSet<int[]> PlayerSelectedHashField = new HashSet<int[]>();
private boolean collisionDetected = false;
In a function I’m using
collisionDetected = PlayerSelectedHashField.contains(TmpPos); // -> Fail - not working
{doing something}
PlayerSelectedHashField.add(TmpPos); // int[] TmpPos - TmpPos is x y
The .add function is working as expected, but .contains always return false.
Why does it not working - and what can I do instead?
public boolean contains(Object o) {
return map.containsKey(o);
}
containsKey:
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}
getNode:
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
It will not work since equals of arrays will do a == compare, and it will return true only if they point to the same instance.
Your problem could be fixed without work with Arrays.equals (the way to compare two arrays elements and not reference) (could be problematic (at least, for me.) i prefer an easy way)
Since you save X and Y coordinates, just make a class Point
public class Point {
public final int X;
public final int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
#Override
public boolean equals(Object obj)
{
if (obj == this) {
return true;
}
if (obj instanceof Point) {
Point pObj = (Point) obj;
return pObj.X == X && pObj.Y == Y;
}
return false;
}
#Override
public int hashCode()
{
int result = X;
result = 31 * result + Y;
return result;
}
}
then use Point class to save X, Y points.
Instead of create your custom point class, you can use the Android Point.
Example
Set<Point> points = new HashSet<Point>();
points.add(new Point(1, 3));
points.add(new Point(1, 4));
System.out.println(points.contains(new Point(1, 3)));
System.out.println(points.contains(new Point(1, 4)));
System.out.println(points.contains(new Point(1, 5)));
From the HashSet javadocs:
public boolean contains(Object o)
Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e)).
So, generally, if you don't know what happens when you call equals on a particular object type, then contains also may not behave as you expect. It is never a bad idea to make a class for a particular object if that object type has conceptual meaning in your program. If you do that, you can override the equals method to make sure it is behaving exactly as you want.