Make a more complex Celtic knot
In Add option, you choose a knot element and rotate it. In Turn option, you can rotate any element. You can alter the colours of the completed knots.
app/manifests/AndroidManifest.xml - to force orientation
app/res/drawable - pictures
There are 7 x 15 image files (15 per colour). The colours are "black", "blue", "green", "red", "white", "yellow" and "cyan" and the files are, e.g., "black0" (background) to "black14". They give the various parts of the knot. They are loaded into an arrays defined in in app/java/com.(the project name)/MainActivity and used in app/java/com.(the project name)/ImagePalette and app/java/com.(the project name)/ImageTile. There are also colour squares (for changing colour).
app/res/mipmap/ic_launcher.png/ - icon for launching app
app/res/values/strings.xml - strings
Construct a Celtic Knot
Choose element, tap below to position, tap again to turn
Tap on any element below to turn
Choose colour, then tap on completed knot
new
Add
Turn
Colour
New knot
app/res/layout/activity_main.xml - screen format
app/java/com.(the project name)/MainActivity - main code for app
package com.edkins.celticknots2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.RadioButton;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
public static int option = 0;
public static int col = 1;
public static int width = 10;
public static int knotType = 1;
public static int knotPos = 1;
public static int knotNum = 0;
// tiles - for setting up knot and colours
public static int [] tile = new int [width * width];
public static int [] colour = new int [width * width];
public static int [] knot = new int [width * width];
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RadioButton acc = (RadioButton) findViewById(R.id.option0);
acc.setChecked(true);
option = 0;
newKnot();
GridView typeV = (GridView) findViewById(R.id.typeView);
typeV.setAdapter(new ImageType(this));
typeV.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView> parent, View v, int position, long id) {
processTypeClick(position);
}
});
GridView tileV = (GridView) findViewById(R.id.tileView);
tileV.setAdapter(new ImageTile(this));
tileV.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView> parent, View v, int position, long id) {
processTileClick(position);
}
});
}
// Main process - tap to rotate pattern plus check if knot completed
public void processTileClick(int position) {
if (option==0) {
if (knotType == 0 && tile[position] == 0) {
Toast.makeText(getApplicationContext(), "Choose an element above first", Toast.LENGTH_SHORT).show();
}
else if (knotSame(position)) {turnKnot(position);}
else {
tile[position] = knotType;
colour[position] = 0;
knot[position] = 0;
}
}
else if (option==1) {turnKnot(position);}
else if (option==2) {
if (knot[position]==0) {
Toast.makeText(getApplicationContext(), "You can only colour a complete knot", Toast.LENGTH_SHORT).show();
}
else {
int thisKnot=knot[position];
for (int j=0; j<(width * width); j++) {
if (knot[j]==thisKnot) {colour[j]=col;}
}
}
}
checkTiles();
redo();
}
// turn knot
public void turnKnot(int position) {
if (tile[position] == 0 || tile[position] == 15) {
Toast.makeText(getApplicationContext(), "You can\'t turn this", Toast.LENGTH_SHORT).show();
}
else if (tile[position] == 4) {tile[position] = 1;}
else if (tile[position] == 8) {tile[position] = 5;}
else if (tile[position] == 10) {tile[position] = 9;}
else if (tile[position] == 14) {tile[position] = 11;}
else {tile[position]++;}
}
// check if same knot
public boolean knotSame(int position) {
if (tile[position] >= 1 && tile[position] <= 4) {
if (knotType >= 1 && knotType <= 4) {return true;}
}
else if (tile[position] >= 5 && tile[position] <= 8) {
if (knotType >= 5 && knotType <= 8) {return true;}
}
else if (tile[position] >= 9 && tile[position] <= 10) {
if (knotType >= 9 && knotType <= 10) {return true;}
}
else if (tile[position] >= 11 && tile[position] <= 14) {
if (knotType >= 11 && knotType <= 14) {return true;}
}
else if (tile[position] == 15 && knotType == 15) {return true;}
return false;
}
// check if knots OK
public void checkTiles() {
int ok=1;
int i; int j;
for (i=0; i<(width * width ); i++) {
if (tile[i] > 0) {
int type = tile[i];
int x = i % width;
int y = i / width;
if (nJoin[type] == 1) {
j = i - width;
if (y==0) {ok = 0; undoKnot(i);}
else if (colour[j] != colour[i]) {ok = 0; undoKnot(i);}
else if (sJoin[tile[j]] == 0) {ok = 0; undoKnot(i);}
}
if (eJoin[type] == 1) {
j = i + 1;
if (x>=(width-1)) {ok = 0; undoKnot(i);}
else if (colour[j] != colour[i]) {ok = 0; undoKnot(i);}
else if (wJoin[tile[j]] == 0) {ok = 0; undoKnot(i);}
}
if (sJoin[type] == 1) {
j = i + width;
if (y>=(width-1)) {ok = 0; undoKnot(i);}
else if (colour[j] != colour[i]) {ok = 0; undoKnot(i);}
else if (nJoin[tile[j]] == 0) {ok = 0; undoKnot(i);}
}
if (wJoin[type] == 1) {
j = i - 1;
if (x==0) {ok = 0; undoKnot(i);}
else if (colour[j] != colour[i]) {ok = 0; undoKnot(i);}
else if (eJoin[tile[j]] == 0) {ok = 0; undoKnot(i);}
}
}
}
knotNum++;
if (ok==1) {
for (i=0; i<(width * width ); i++) {
if (tile[i] > 0 && colour[i] == 0) {colour[i] = col; knot[i]=knotNum;}
}
}
}
public void undoKnot(int i) {
int wrongKnot=knot[i];
for (int j=0; j<(width * width ); j++) {
if (knot[j]==wrongKnot) {colour[j]=0; knot[j]=0;}
}
}
public void newKnot() {
for (int i=0; i<(width * width); i++) {
colour[i] = 0; tile[i] = 0; knot [i] = 0;
}
knotNum = 0;
}
// redo main grid
public void redo() {
GridView tileV = (GridView) findViewById(R.id.tileView);
tileV.setAdapter(new ImageTile(this));
}
public void processTypeClick(int position) {
if (option==0) {
knotPos = position;
if (position == 0) {knotType = 0;}
else if (position == 1) {knotType = 1;}
else if (position == 2) {knotType = 5;}
else if (position == 3) {knotType = 9;}
else if (position == 4) {knotType = 11;}
else if (position == 5) {knotType = 15;}
}
else if (option==1) {
Toast.makeText(getApplicationContext(), "Tap below, not here", Toast.LENGTH_SHORT).show();
}
else if (option==2) {col = position+1;}
redoType();
}
// options
public void clickOption0(View view) {option=0; redoType();}
public void clickOption1(View view) {option=1; redoType();}
public void clickOption2(View view) {option=2; redoType();}
public void clickOption3(View view) {
newKnot(); redo();
option=0;
RadioButton acc = (RadioButton) findViewById(R.id.option0);
acc.setChecked(true);
option = 0;
redoType();
}
// redo options
public void redoType() {
GridView typeV = (GridView) findViewById(R.id.typeView);
typeV.setAdapter(new ImageType(this));
}
// Different colours of knot
public static int [] black = {
R.drawable.black0, R.drawable.black1, R.drawable.black2, R.drawable.black3,
R.drawable.black4, R.drawable.black5, R.drawable.black6, R.drawable.black7,
R.drawable.black8, R.drawable.black9, R.drawable.black10, R.drawable.black11,
R.drawable.black12, R.drawable.black13, R.drawable.black14, R.drawable.black15
};
public static int [] red = {
R.drawable.black0, R.drawable.red1, R.drawable.red2, R.drawable.red3,
R.drawable.red4, R.drawable.red5, R.drawable.red6, R.drawable.red7,
R.drawable.red8, R.drawable.red9, R.drawable.red10, R.drawable.red11,
R.drawable.red12, R.drawable.red13, R.drawable.red14, R.drawable.red15
};
public static int [] blue = {
R.drawable.black0, R.drawable.blue1, R.drawable.blue2, R.drawable.blue3,
R.drawable.blue4, R.drawable.blue5, R.drawable.blue6, R.drawable.blue7,
R.drawable.blue8, R.drawable.blue9, R.drawable.blue10, R.drawable.blue11,
R.drawable.blue12, R.drawable.blue13, R.drawable.blue14, R.drawable.blue15
};
public static int [] yellow = {
R.drawable.black0, R.drawable.yellow1, R.drawable.yellow2, R.drawable.yellow3,
R.drawable.yellow4, R.drawable.yellow5, R.drawable.yellow6, R.drawable.yellow7,
R.drawable.yellow8, R.drawable.yellow9, R.drawable.yellow10, R.drawable.yellow11,
R.drawable.yellow12, R.drawable.yellow13, R.drawable.yellow14, R.drawable.yellow15
};
public static int [] green = {
R.drawable.black0, R.drawable.green1, R.drawable.green2, R.drawable.green3,
R.drawable.green4, R.drawable.green5, R.drawable.green6, R.drawable.green7,
R.drawable.green8, R.drawable.green9, R.drawable.green10, R.drawable.green11,
R.drawable.green12, R.drawable.green13, R.drawable.green14, R.drawable.green15
};
public static int [] cyan = {
R.drawable.black0, R.drawable.cyan1, R.drawable.cyan2, R.drawable.cyan3,
R.drawable.cyan4, R.drawable.cyan5, R.drawable.cyan6, R.drawable.cyan7,
R.drawable.cyan8, R.drawable.cyan9, R.drawable.cyan10, R.drawable.cyan11,
R.drawable.cyan12, R.drawable.cyan13, R.drawable.cyan14, R.drawable.cyan15
};
public static int [] white = {
R.drawable.black0, R.drawable.white1, R.drawable.white2, R.drawable.white3,
R.drawable.white4, R.drawable.white5, R.drawable.white6, R.drawable.white7,
R.drawable.white8, R.drawable.white9, R.drawable.white10, R.drawable.white11,
R.drawable.white12, R.drawable.white13, R.drawable.white14, R.drawable.white15
};
// choice of tiles
public static int[] choose = {
R.drawable.choose0, R.drawable.choose1, R.drawable.choose2,
R.drawable.choose3, R.drawable.choose4, R.drawable.choose5
};
// choice of tiles
public static int[] chosen = {
R.drawable.chosen0, R.drawable.black1, R.drawable.black5,
R.drawable.black9, R.drawable.black11, R.drawable.black15
};
// choice of colours selected
public static int [] colourSel = {
R.drawable.colx1, R.drawable.colx2, R.drawable.colx3,
R.drawable.colx4, R.drawable.colx5, R.drawable.colx6
};
// choice of colours not selected
public static int[] colourNot = {
R.drawable.col1, R.drawable.col2, R.drawable.col3,
R.drawable.col4, R.drawable.col5, R.drawable.col6
};
// where joins are
public static int [] nJoin = {0,0,0,1,0,0,0,1,1,0,1,0,1,1,1,1};
public static int [] eJoin = {0,0,0,0,1,1,0,0,1,1,0,1,0,1,1,1};
public static int [] sJoin = {0,1,0,0,0,1,1,0,0,0,1,1,1,0,1,1};
public static int [] wJoin = {0,0,1,0,0,0,1,1,0,1,0,1,1,1,0,1};
}
app/java/com.(the project name)/ImageType - code for option type gridview - a new file, see above
package com.edkins.celticknots2;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class ImageType extends BaseAdapter {
private AppCompatActivity mContext;
public ImageType(AppCompatActivity c) {mContext = c;}
public int getCount() {return 6;}
public Object getItem(int position) {return null;}
public long getItemId(int position) {return 0;}
// create new ImageView for palette
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
GridView typeV = (GridView) mContext.findViewById(R.id.typeView);
int w = typeV.getWidth() / 12;
imageView.setLayoutParams(new GridView.LayoutParams(w, w));
}
else {
imageView = (ImageView) convertView;
}
if (MainActivity.option==0) {
if (MainActivity.knotPos == position) {
imageView.setImageResource(MainActivity.chosen[position]);
}
else {imageView.setImageResource(MainActivity.choose[position]);}
}
else if (MainActivity.option==1) {
imageView.setImageResource(R.drawable.space);
}
else if (MainActivity.option==2) {
if ((position+1) == MainActivity.col) {
imageView.setImageResource(MainActivity.colourSel [position]);
}
else {imageView.setImageResource(MainActivity.colourNot [position]);}
}
return imageView;
}
}
app/java/com.(the project name)/ImageTile - code for tile gridview - a new file, see above
package com.edkins.celticknots2;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class ImageTile extends BaseAdapter {
private AppCompatActivity mContext;
public ImageTile(AppCompatActivity c) {mContext = c;}
public int getCount() {return 100;}
public Object getItem(int position) {return null;}
public long getItemId(int position) {return 0;}
// create new ImageView for tile
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
GridView tile = (GridView) mContext.findViewById(R.id.tileView);
int w = tile.getWidth() / MainActivity.width;
imageView.setLayoutParams(new GridView.LayoutParams(w, w));
} else {
imageView = (ImageView) convertView;
}
// initialise the view element (to whatever is in array tile[])
int sub = MainActivity.tile[position];
int col = MainActivity.colour[position];
if (col == 0) {imageView.setImageResource(MainActivity.black[sub]);}
else if (col == 1) {imageView.setImageResource(MainActivity.red[sub]);}
else if (col == 2) {imageView.setImageResource(MainActivity.blue[sub]);}
else if (col == 3) {imageView.setImageResource(MainActivity.yellow[sub]);}
else if (col == 4) {imageView.setImageResource(MainActivity.green[sub]);}
else if (col == 5) {imageView.setImageResource(MainActivity.cyan[sub]);}
else if (col == 6) {imageView.setImageResource(MainActivity.white[sub]);}
return imageView;
}
}
Index to my other websites
© Jo Edkins 2016