if neigbour color found,
* set same color
* move on with step 0.
ELSE
* if all neighbours are empty
* choose random color (which must be a NEW color (not used yet))
* (if there's no new color, skip and goto 0)
But then he fills all with one color
He needs to stop and start new
Chrisir i am having a little trouble understanding your code it fells a level above me. Can you explain it to me so that way i can understand it better.
here's the code ▼
// RESET
for (int TE = 0; TE < AmountOfTiles; TE++) {
TileColors[TE] = 1; // not OCEAN
}
// attempts
for (int i = 1; i < 13; i++) {
// new group of Type startingNewGroupType : loop over types of hexagon :
// starting with 1 = NO ocean
for (int startingNewGroupType = 1; startingNewGroupType < 4; startingNewGroupType++) {
int startingNewGroupWhere = int (random(AmountOfTiles));
TileColors[startingNewGroupWhere] = startingNewGroupType;
// going down and up
int from = -int(random(4, 12));
int to = int(random(4, 12));
for (int i2 = from; i2 < to; i2++) {
int newFieldIndex= startingNewGroupWhere + i2;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
// for each new field going left and right
from = -int(random(4, 12));
to = int(random(4, 12));
for (int i3 = from; i3 < to; i3++) {
if (newFieldIndex + i3*29 >= 0 && newFieldIndex + i3*29 < AmountOfTiles)
TileColors[newFieldIndex + i3*29] = startingNewGroupType;
}
}
}
//
}//for
//
//add ocean
int startingNewGroupType = 0;
float xPrev=-10000;
float yPrev=-10000;
// attempts
for (int i4 = 1; i4 < 12; i4++) {
int startingNewGroupWhere = indexOfExistingOcean(); // find old ocean tile
if ( startingNewGroupWhere==-1)
startingNewGroupWhere= int (random(AmountOfTiles));
TileColors[startingNewGroupWhere] = startingNewGroupType;
if (random(100) > 90) {
// random walker / river
int newFieldIndex = startingNewGroupWhere -1;
int direction = int(random(4));
// attempts
for (int i = 1; i < 293; i++) {
if (random(100)>60)
direction = int(random(4));
switch (direction) {
case 0: //north
newFieldIndex = startingNewGroupWhere -1;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
break;
case 1: //east
newFieldIndex= startingNewGroupWhere + 29;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
break;
case 2: //south
newFieldIndex= startingNewGroupWhere + 1;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
break;
case 3: //west
newFieldIndex= startingNewGroupWhere - 29;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
break;
}
startingNewGroupWhere=newFieldIndex;
}
}
//---
else
{
// Lake
// going down and up
int from = -int(random(4, 12));
int to = int(random(4, 12));
for (int i2 = from; i2 < to; i2++) {
int newFieldIndex= startingNewGroupWhere + i2;
if (newFieldIndex >= 0 &&
newFieldIndex < AmountOfTiles &&
dist(xPrev, yPrev, XColmns[newFieldIndex], YColmns[newFieldIndex]) < 66 ) {
TileColors[newFieldIndex] = startingNewGroupType;
// for each new field going left and right
from = -int(random(4, 12));
to = int(random(4, 12));
for (int i3 = from; i3 < to; i3++) {
if (newFieldIndex + i3*29 >= 0 && newFieldIndex + i3*29 < AmountOfTiles)
TileColors[newFieldIndex + i3*29] = startingNewGroupType;
}
}
}//for
xPrev=XColmns[startingNewGroupWhere];
yPrev=YColmns[startingNewGroupWhere];
}//else
//
}//for
//
} // setup end
// ------------------------------------------------------------------------
int indexOfExistingOcean() {
//
ArrayList<Integer> indices = new ArrayList();
for (int TE = 0; TE < AmountOfTiles; TE++) {
if (TileColors[TE] == 0) { // OCEAN
//
indices.add (TE);
//
}//if
}//for
if (indices.size()==0) {
return -1;
}
int randomNumber = int(random(indices.size()));
return indices.get(randomNumber);
Chrisir having trouble working out how to make it where when the mouse is pressed on a hexagon a ellipse called character would move into that hexagons x and y.
Then use if(dist(mouseX,mouseY, centerX,centerY) <44) .... or some value for 44 being the radius
Then store the data that this ellipse carries a character. Or just store the index of the hexagon and show the character using the data of the hexagon in the array with the character index
Eg in function mousePressed you for loop i over the array and check if (dist( as above if true set indexCharacter to i
Then use if(dist(mouseX,mouseY, centerX,centerY) <44) .... or some value for 44 being the radius
Then store the data that this ellipse carries a character. Or just store the index of the hexagon and show the character using the data of the hexagon in the array with the character index
Eg in function mousePressed you for loop i over the array and check if (dist( as above if true set indexCharacter to i
I'm having some trouble with the y value in hexagon for some reason it doesn't want to change when i press in the hexagons but the x works fine Any suggestions.
Chrisir i think that the code you gave me was for a area of a circle if it was pressed in the area but is it possible to do it for the area of a hexagon for. here's the code
float [] XColmns;
float [] YColmns;
float [] ColorR;
float [] ColorG;
float [] ColorB;
int [] TileColors;
int [] TileColorChance;
int AmountOfTiles = 1131;
int Seed = round(random(1000000000));
float CharPosX, CharPosY;
////////////////////////////////////////////////////////////////////////////
void setup() {
size(975, 830);
println("Seed: "+Seed);
randomSeed(Seed);
XColmns = new float[AmountOfTiles];
YColmns = new float[AmountOfTiles];
ColorR = new float[AmountOfTiles];
ColorG = new float[AmountOfTiles];
ColorB = new float[AmountOfTiles];
TileColors = new int[AmountOfTiles];
TileColorChance = new int[AmountOfTiles];
for (int c = 0; c < 39; c++) {
if ((int)c%2==0) {
for (int N = 0; N < 29; N++) {
XColmns[N+c*29] = 31+c*24;
YColmns[N+c*29] = 30 + N * 27;
}
} else {
for (int N = 0; N < 29; N++) {
XColmns[N+c*29] = 31+c*24;
YColmns[N+c*29] = 43 + N * 27;
}
}
}
// RESET
for (int TE = 0; TE < AmountOfTiles; TE++) {
TileColors[TE] = 1; // not OCEAN
}
// attempts
for (int i = 1; i < 13; i++) {
// new group of Type startingNewGroupType : loop over types of hexagon :
// starting with 1 = NO ocean
for (int startingNewGroupType = 1; startingNewGroupType < 4; startingNewGroupType++) {
int startingNewGroupWhere = int (random(AmountOfTiles));
TileColors[startingNewGroupWhere] = startingNewGroupType;
// going down and up
int from = -int(random(4, 12));
int to = int(random(4, 12));
for (int i2 = from; i2 < to; i2++) {
int newFieldIndex= startingNewGroupWhere + i2;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
// for each new field going left and right
from = -int(random(4, 12));
to = int(random(4, 12));
for (int i3 = from; i3 < to; i3++) {
if (newFieldIndex + i3*29 >= 0 && newFieldIndex + i3*29 < AmountOfTiles)
TileColors[newFieldIndex + i3*29] = startingNewGroupType;
}
}
}
//
}//for
//
//add ocean
int startingNewGroupType = 0;
float xPrev=-10000;
float yPrev=-10000;
// attempts
for (int i4 = 1; i4 < 12; i4++) {
int startingNewGroupWhere = indexOfExistingOcean(); // find old ocean tile
if ( startingNewGroupWhere==-1)
startingNewGroupWhere= int (random(AmountOfTiles));
TileColors[startingNewGroupWhere] = startingNewGroupType;
if (random(100) > 90) {
// random walker / river
int newFieldIndex = startingNewGroupWhere -1;
int direction = int(random(4));
// attempts
for (int i = 1; i < 293; i++) {
if (random(100)>60)
direction = int(random(4));
switch (direction) {
case 0: //north
newFieldIndex = startingNewGroupWhere -1;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
break;
case 1: //east
newFieldIndex= startingNewGroupWhere + 29;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
break;
case 2: //south
newFieldIndex= startingNewGroupWhere + 1;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
break;
case 3: //west
newFieldIndex= startingNewGroupWhere - 29;
if (newFieldIndex >= 0 && newFieldIndex < AmountOfTiles)
TileColors[newFieldIndex] = startingNewGroupType;
break;
}
startingNewGroupWhere=newFieldIndex;
}
}
//---
else
{
// Lake
// going down and up
int from = -int(random(4, 12));
int to = int(random(4, 12));
for (int i2 = from; i2 < to; i2++) {
int newFieldIndex= startingNewGroupWhere + i2;
if (newFieldIndex >= 0 &&
newFieldIndex < AmountOfTiles &&
dist(xPrev, yPrev, XColmns[newFieldIndex], YColmns[newFieldIndex]) < 66 ) {
TileColors[newFieldIndex] = startingNewGroupType;
// for each new field going left and right
from = -int(random(4, 12));
to = int(random(4, 12));
for (int i3 = from; i3 < to; i3++) {
if (newFieldIndex + i3*29 >= 0 && newFieldIndex + i3*29 < AmountOfTiles)
TileColors[newFieldIndex + i3*29] = startingNewGroupType;
}
}
}//for
xPrev=XColmns[startingNewGroupWhere];
yPrev=YColmns[startingNewGroupWhere];
}//else
//
}//for
////////////////////////////////////////////////////////////////////////////
// new code here
CharPosX = XColmns[round(random(0, AmountOfTiles))];
CharPosY = YColmns[round(random(0, AmountOfTiles))];
////////////////////////////////////////////////////////////////////////////
//new code ends here
} // setup end
// ------------------------------------------------------------------------
int indexOfExistingOcean() {
//
ArrayList<Integer> indices = new ArrayList();
for (int TE = 0; TE < AmountOfTiles; TE++) {
if (TileColors[TE] == 0) { // OCEAN
//
indices.add (TE);
//
}//if
}//for
if (indices.size()==0) {
return -1;
}
int randomNumber = int(random(indices.size()));
return indices.get(randomNumber);
//
}//func
////////////////////////////////////////////////////////////////////////////
void draw() {
background(226, 185, 108);
//table
fill(89, 60, 5);
// ellipse(-260, -330, 1500, 1500);
//black board
fill(0);
stroke(108, 67, 4);
strokeWeight(1);
//rect(0, 0, width, height);
for (int i = 0; i < AmountOfTiles; i++) {
Hexagon(XColmns[i], YColmns[i], 14, TileColors[i]);
}
fill(255, 0, 25);
ellipse(CharPosX, CharPosY, 10, 10);
} // end of draw
////////////////////////////////////////////////////////////////////////////
void Hexagon (float x, float y, float S, float ColorSelecter) {
noFill();
//Ocean
if (ColorSelecter == 0) fill(16, 0, 165);
//Grassland
else if (ColorSelecter == 1) fill(81, 175, 14);
//Jungle
else if (ColorSelecter == 2) fill(27, 157, 2);
//Pond
else if (ColorSelecter == 3) fill(1, 116, 147);
// Error
else println ("Error ColorSelecter "+ColorSelecter);
////////////////////////////////////////////////////////////////////////////
//new code here
if (mousePressed && dist(mouseX, mouseY, x+S/2, y+S/2) < S) CharPosX = x; CharPosY = y;
////////////////////////////////////////////////////////////////////////////
//new code ends here
noStroke();
beginShape();
for (int i=0; i<6; i++) {
float angle = i * 2 * PI / 6;
vertex(x + S*cos(angle), y + S*sin(angle));
}
endShape(CLOSE);
}//function
Yes i -1 the size in the dist(); and it was that i had no brackets which the second line of code that is run in that if statement was buggy. To fix it i just added brackets at the start and the end of the statement. Thanks for your suggestions it help a lot.
to distribute the initial colors you could like start each color in different random spots in the map. Then in a second step fill the wholes (empty fields) by connecting it.
Yah it works. no i was just trying to learn some different concepts since i'm sort of new to this stuff ;) . Yep that was the spot. Chrisir how would you make like a AI person that moved around but only in the center of different hexagons. For example it can move forward a tile back a tile or left to right one tile etc..
The problem I see is that one condition you have is that you want all hexagons of one color to be connected. So one color is always ONE area / patch and not several patches. Not to easy with noise().
Okay thanks, but is it easy to generate the base colors say ocean and grassland in noise then generate on top of the grassland random patches of trees in other code not noise.
Sorry for late response life gets busy as you know. Wow that looks great though and i appreciate the comments it helps to understand the code. I agree on ocean code in setup the new code is better.
I think you need to define more clearly what you don't like about the current way the colors are distributed
Well i was just seeing if we could get smoother terrain generation because i was looking at examples of noise generation and then i saw this one here's the link to it studio.sketchpad.cc/sp/pad/view/ro.ALuTIcV$K3D/rev.28.
Does the hexagons of ONE color really be connected? So they are ONE patch and not divided into 3 patches or so?
Not to sure what you mean here but by one color do you mean having multiple colors inside a hexagon?
Now i understand yes it is allowed to have multiple patches in different places.
Its kind of a game that i am trying to make. But i ran into some problems with the hexagon generation code.
Sorry i should have been more clearer at the start with this. I was just trying to code as much as possible so that way i would could get more experience with coding because i am fairly new here. That's why i was asking if you could explain the code to me because it seems you are very experienced in this sort of thing and i want to learn and grow to get better at coding.
But we have to take into account that we don't want the walker to go back and forth, like forward one and back one. That'd look stupid. So we need 3 pairs of numbers which are the back and forth and exclude them:
return here means we leave the function and don't move the AI Walker:
// to go back and forth is not allowed
// (so these are 3 illegal pairs: 01, 43, 25)
if (prevDirection == 0 && testDirection == 1)
return;
if (prevDirection == 1 && testDirection == 0)
return;
if (prevDirection == 3 && testDirection == 4)
return;
if (prevDirection == 4 && testDirection == 3)
return;
if (prevDirection == 2 && testDirection == 5)
return;
if (prevDirection == 5 && testDirection == 2)
return;
The numbers like 0/1 and 3/4 and 2/5 are the illegal pairs and refer to the list vectorsForNeigbours (so they mean -1/1 and 29/-28 and -29/30)
for a discussion of the illegal neighbor pairs see here (numbers refer to the full red hexagon and its six neighbors, marked by red crosses X) :
Here is the entire AI Walker function :
void move_AI() {
// for AI_Walker_Position
int testDirection;
if (random(100)<90) {
return; // leave here
}
int prevDirection = direction;
testDirection = int(random(6));
// -----
// to go back and forth is not allowed
// (so these are 3 illegal pairs: 01, 43, 25)
if (prevDirection == 0 && testDirection == 1)
return;
if (prevDirection == 1 && testDirection == 0)
return;
if (prevDirection == 3 && testDirection == 4)
return;
if (prevDirection == 4 && testDirection == 3)
return;
if (prevDirection == 2 && testDirection == 5)
return;
if (prevDirection == 5 && testDirection == 2)
return;
// -----
direction = testDirection;
AI_Walker_Position = AI_Walker_Position + vectorsForNeigbours[direction];
// check
if (AI_Walker_Position < 0)
AI_Walker_Position=AmountOfTiles;
if (AI_Walker_Position >= AmountOfTiles)
AI_Walker_Position=0;
}
//
here is a new version that uses a random walker for the initial patches and then fills the gaps
// https : // forum.processing.org/two/discussion/26942/hexagon-generation#latest
// this version:
// * improved AI Walker
// * patch not more or less round area but with a virtual Walker (like rivers) (still then gaps are filled)
// * good version
// color red as a constant
final color RED = color (255, 0, 0); // RED
// list for neighbour finder as array (constant)
final int[] vectorsForNeigbours = {
-1, 1, -29, 29, -28, 30
};
float [] XColmns;
float [] YColmns;
float [] ColorR;
float [] ColorG;
float [] ColorB;
int [] TileColors;
//int [] TileColorChance;
int AmountOfTiles = 1131;
int AI_Walker_Position = int (AmountOfTiles / 2);
//int Seed = round(random(1000000000));
float CharPosX, CharPosY;
int direction=0;
int centerFieldIndexGlobal;
int [] listOfNeighbours = new int [6];
////////////////////////////////////////////////////////////////////////////
void setup() {
size(975, 830);
//println("Seed: "+Seed);
//randomSeed(Seed);
XColmns = new float[AmountOfTiles];
YColmns = new float[AmountOfTiles];
ColorR = new float[AmountOfTiles];
ColorG = new float[AmountOfTiles];
ColorB = new float[AmountOfTiles];
TileColors = new int[AmountOfTiles];
// TileColorChance = new int[AmountOfTiles];
// make hexagon positions
for (int c = 0; c < 39; c++) {
if ((int)c%2==0) {
for (int N = 0; N < 29; N++) {
XColmns[N+c*29] = 31+c*24;
YColmns[N+c*29] = 30 + N * 27;
}
} else {
for (int N = 0; N < 29; N++) {
XColmns[N+c*29] = 31+c*24;
YColmns[N+c*29] = 43 + N * 27;
}
}
}
// -----------
// RESET colors
for (int TE = 0; TE < AmountOfTiles; TE++) {
TileColors[TE] = -1; // not defined
}
// -----------
// add patches
patches();
// -----------
// fill gaps between patches
fillGapsBetweenPatches();
// -----------
//
// -----------
// add ocean but then (maybe) you need to skip ocean above (starting for loop at 1)
// addOcean();
////////////////////////////////////////////////////////////////////////////
// new code here
int indexCharPos = int(random(0, AmountOfTiles));
CharPosX = XColmns[indexCharPos];
CharPosY = YColmns[indexCharPos];
////////////////////////////////////////////////////////////////////////////
//new code ends here
} // setup end
////////////////////////////////////////////////////////////////////////////
void draw() {
background(226, 185, 108);
//table
fill(89, 60, 5);
// ellipse(-260, -330, 1500, 1500);
//black board
fill(0);
stroke(108, 67, 4);
strokeWeight(1);
//rect(0, 0, width, height);
for (int i = 0; i < AmountOfTiles; i++) {
Hexagon(XColmns[i], YColmns[i],
14, TileColors[i], i);
if (i==AI_Walker_Position) {
fill(255, 0, 255);
ellipse(XColmns[i], YColmns[i], 10, 10);
}//if
}//for
move_AI();
showNeighbour(AmountOfTiles/4);
for (int i = 0; i < AmountOfTiles; i++) {
for (int i2=0; i2<6; i2++)
if (i==listOfNeighbours[i2])
cross(XColmns[i], YColmns[i]);
}
fill(255, 0, 25);
ellipse(CharPosX, CharPosY, 10, 10);
} // end of draw
////////////////////////////////////////////////////////////////////////////
// called from setup() (or its children)
void fillGapsBetweenPatches() {
// 130 attempts
for (int c2 = 0; c2 < 139; c2++) {
IntList array1 = new IntList();
for (int c3 = 0; c3 < AmountOfTiles; c3++) {
array1.append(c3);
}
array1.shuffle();
// fill gaps between patches
for (int c4 = 0; c4 < AmountOfTiles; c4++) {
int c = array1.get(c4);
if (TileColors[c] == -1) {
int type1 = getNeighbours(c);
if (type1 != -1)
TileColors[c] = type1;
}//if
}//for
}//for
}//func
int getNeighbours(int index1) {
// checks all 6 neighbors of index1 and returns the color of the first non-empty field.
int i2=0;
for (Integer i : vectorsForNeigbours) {
//print(i+" ");
int neighbourIndex = index1 + i;
// if valid hexagon index and tile not empty return the color
if (neighbourIndex >= 0 &&
neighbourIndex < AmountOfTiles &&
TileColors[neighbourIndex] != -1 &&
!tooFar(index1, neighbourIndex)) {
// return the found color of the neighbour
return TileColors[neighbourIndex]; // leave here
}//if
i2++;
}//for
//println(i2);
// fail
return -1;
}
boolean tooFar(int ind1, int ind2) {
// too far away
return dist(XColmns[ind1], YColmns[ind1],
XColmns[ind2], YColmns[ind2]) >= 66;
}
void patches() {
// making a ***patch*** of color
// by using a virtual random walker (like a river)
// new group of Type startingNewGroupType : loop over types of hexagon :
// (starting with 1 = NO ocean OR starting with 0 = WITH ocean)
for (int startingNewGroupType = 0; startingNewGroupType < 4; startingNewGroupType++) {
// attempts per color
for (int i2 = 0; i2 < 14; i2++) { // starting multiple patches - you can comment out this for loop
int startingNewGroupWhere = int(random(AmountOfTiles));
int newFieldIndex = startingNewGroupWhere;
int direction = int(random(6));
// walking steps
for (int i = 1; i < 244; i++) {
if (random(100)>80) {
direction = int(random(6));
}
direction = int(random(6));
newFieldIndex = startingNewGroupWhere + vectorsForNeigbours[direction];
if (newFieldIndex >= 0 &&
newFieldIndex < AmountOfTiles &&
(TileColors[newFieldIndex] == -1 || TileColors[newFieldIndex] == startingNewGroupType ) &&
!tooFar(startingNewGroupWhere, newFieldIndex) ) { // !tooFar(startingNewGroupWhere, newFieldIndex) && TileColors[newFieldIndex] == -1
// define color for that hexagon
TileColors[newFieldIndex] = startingNewGroupType;
startingNewGroupWhere=newFieldIndex;
}
}//for
}//for
}//for
//
} // func
void patchesOLD() {
// more round patches
float xPrev=-10000;
float yPrev=-10000;
// attempts
//for (int i = 1; i < 13; i++) {
// new group of Type startingNewGroupType : loop over types of hexagon :
// starting with 1 = NO ocean
for (int startingNewGroupType = 0; startingNewGroupType < 4; startingNewGroupType++) {
// making a ***patch*** of color
int startingNewGroupWhere = int (random(AmountOfTiles));
TileColors[startingNewGroupWhere] = startingNewGroupType;
// going down and up from there
int from = -int(random(4, 7));
int to = int(random(4, 7));
for (int i2 = from; i2 < to; i2++) {
int newFieldIndex= startingNewGroupWhere + i2;
if (newFieldIndex >= 0 &&
newFieldIndex < AmountOfTiles &&
dist(xPrev, yPrev, XColmns[newFieldIndex], YColmns[newFieldIndex]) < 66 ) {
TileColors[newFieldIndex] = startingNewGroupType;
// for each new field going left and right
from = -int(random(4, 7));
to = int(random(4, 7));
for (int i3 = from; i3 < to; i3++) {
if (newFieldIndex + i3*29 >= 0 &&
newFieldIndex + i3*29 < AmountOfTiles)
TileColors[newFieldIndex + i3*29] = startingNewGroupType;
}//for
}//if
xPrev=XColmns[startingNewGroupWhere];
yPrev=YColmns[startingNewGroupWhere];
}//for
}//for
//
// }//for attempts
}
////////////////////////////////////////////////////////////////////////////
// called from draw() (or its children)
void showNeighbour(int centerFieldIndex) {
centerFieldIndexGlobal=centerFieldIndex;
int i2=0;
for (Integer i : vectorsForNeigbours) {
listOfNeighbours[i2]=centerFieldIndex+i;
i2++;
}
}
void Hexagon (float x, float y,
float S,
float ColorSelecter,
int index1) {
noFill();
//Ocean
if (ColorSelecter == 0)
fill(16, 0, 165);
//Grassland
else if (ColorSelecter == 1)
fill(81, 195, 14);
//Jungle
else if (ColorSelecter == 2)
fill(27, 157, 2);
//Pond
else if (ColorSelecter == 3)
fill(1, 116, 147);
// Error
else
println ("Error ColorSelecter "
+ColorSelecter);
// used for showNeighbour()
if (index1==centerFieldIndexGlobal)
fill(RED); // fill(255);
////////////////////////////////////////////////////////////////////////////
//new code here
if (mousePressed) {
if ( dist(mouseX, mouseY, x+S/2, y+S/2) < S) {
if (mouseButton==LEFT) {
CharPosX = x;
CharPosY = y;
} else if (mouseButton==RIGHT) {
// println (index1);
fill(0);
text(index1, width-33, 11);
}
}
}
////////////////////////////////////////////////////////////////////////////
//new code ends here
noStroke();
beginShape();
for (int i=0; i<6; i++) {
float angle = i * 2 * PI / 6;
vertex(x + S*cos(angle), y + S*sin(angle));
}
endShape(CLOSE);
}//function
void cross(float x, float y) {
final int radius = 5;
stroke(RED); // RED
line(x-radius, y-radius,
x+radius, y+radius);
line(x+radius, y-radius,
x-radius, y+radius);
}//
// ---------------------------------------------------------
// AI
void move_AI() {
// for AI_Walker_Position
int testDirection;
if (random(100)<90) {
return; // leave here
}
int prevDirection = direction;
testDirection = int(random(6));
// -----
// to go back and forth is not allowed
// (so these are 3 illegal pairs: 01, 43, 25)
if (prevDirection == 0 && testDirection == 1)
return;
if (prevDirection == 1 && testDirection == 0)
return;
if (prevDirection == 3 && testDirection == 4)
return;
if (prevDirection == 4 && testDirection == 3)
return;
if (prevDirection == 2 && testDirection == 5)
return;
if (prevDirection == 5 && testDirection == 2)
return;
// -----
direction = testDirection;
AI_Walker_Position = AI_Walker_Position + vectorsForNeigbours[direction];
// check
if (AI_Walker_Position < 0)
AI_Walker_Position=AmountOfTiles;
if (AI_Walker_Position >= AmountOfTiles)
AI_Walker_Position=0;
}
//
Wow this is great stuff i did notice that the AI had a bug i was trying to fix it but couldn't figure it. But the AI works great just looking at all the code you posted and slowly looking threw and learning how the new code works. I agree on the XColmns and the YRows change it makes it more clear.
and/or a mix of Settler of Catan with some "conquer areas game".
A simple approach:
Possible Game e.g.
two human players play on your board (no AI)
both start with a hexagon that belongs to them (randomly assigned to player)
they have alternating turns. (Their moves.)
Now each round the hexagons produce resources (ocean=fish, forest=wood, grassland with sheep = wool...), e.g. per round 1 fish, 1 wood etc.
Now the player that owns a hexagon gets its resources, so they get richer
to conquer / occupy a new hexagon (territory grows ) you need to invest resources. Once you own a new hexagon you also get its resources next round, so you're getting richer faster
to make the things easier, 1 fish = 1 $, 1 wood/lumber = 2 $, next 3$, next 4$ (different prices)
To conquer e.g. a new field, you must pay 5 bugs to the bank. When you own 12 bugs you can conquer 2 hexagons; only adjacent hexagons can be conquered
You have to decide which hexagon to take (that produce more wealth, so ocean is less attractive than wood etc.; hexagons owned by other player can't be bought
after 5 minutes game is over and we count the hexagons both own: who owns more has won. Display Win Message, "Player 2 has won!" or so. Ask to play again.
can be played in theory with 4 human players also or later against AI
Things to do
resources are distributed to players every turn
Each player has the resources he owns / money (variables for each player: money)
turn / round management (whose turn is it etc.)
select hexagons you want to conquer with the mouse, money is monitored
Answers
another approach:
check fields
check neighbours change random color
if neigbour color found, * set same color * move on with step 0. ELSE * if all neighbours are empty * choose random color (which must be a NEW color (not used yet)) * (if there's no new color, skip and goto 0)
But then he fills all with one color He needs to stop and start new
min. 5 fields per color, max. color = ?
1, 29, 40, 46 249 to 252 296 to 299
Excuse, what do you mean by that?
the lines numbers that i added 1 = line 1
Chrisir i am having a little trouble understanding your code it fells a level above me. Can you explain it to me so that way i can understand it better.
here's the code ▼
Apologies, I don’t have the time....
okay, maybe later you can do it please.
No, I don't think so
Okay that's all right anyways.
Chrisir having trouble working out how to make it where when the mouse is pressed on a hexagon a ellipse called character would move into that hexagons x and y.
I see
Do you have the center of the hexagon?
Then use if(dist(mouseX,mouseY, centerX,centerY) <44) .... or some value for 44 being the radius
Then store the data that this ellipse carries a character. Or just store the index of the hexagon and show the character using the data of the hexagon in the array with the character index
Eg in function mousePressed you for loop i over the array and check if (dist( as above if true set indexCharacter to i
I see
Do you have the center of the hexagon?
Then use if(dist(mouseX,mouseY, centerX,centerY) <44) .... or some value for 44 being the radius
Then store the data that this ellipse carries a character. Or just store the index of the hexagon and show the character using the data of the hexagon in the array with the character index
Eg in function mousePressed you for loop i over the array and check if (dist( as above if true set indexCharacter to i
I'm having some trouble with the y value in hexagon for some reason it doesn't want to change when i press in the hexagons but the x works fine Any suggestions.
Chrisir i think that the code you gave me was for a area of a circle if it was pressed in the area but is it possible to do it for the area of a hexagon for. here's the code
Circle is very similar to an hexagon
Just make the ...<value smaller in the if dist line
Is your x,y the center or upper left corner of hexagon?
That could be a source of error
Yes i -1 the size in the dist(); and it was that i had no brackets which the second line of code that is run in that if statement was buggy. To fix it i just added brackets at the start and the end of the statement. Thanks for your suggestions it help a lot.
Does it work now?
you should hit ctrl-t more often in processing
what is your goal in this sketch? A game?
distribute the initial colors
to distribute the initial colors you could like start each color in different random spots in the map. Then in a second step fill the wholes (empty fields) by connecting it.
you had a missing closing bracket } here
Yah it works. no i was just trying to learn some different concepts since i'm sort of new to this stuff ;) . Yep that was the spot. Chrisir how would you make like a AI person that moved around but only in the center of different hexagons. For example it can move forward a tile back a tile or left to right one tile etc..
Wow that's great i thought that you had to do some like the code below just didn't now how to do it.
Well, it's absolutely the same principle we use in lines 106 to 146 above which shows that you never really read or understood them...?
O yeah i didn't see that Wow. what does case do in the code is it like the condition.
case?
see reference
yeah condition like
==
https://www.processing.org/reference/switch.html
Okay thanks. Wow Chrisir the case statement and the if statement condition are very similar now i know thanks a lot this is ground breaking stuff.
Chrisir how would you add the noise function for the hexagon generation. From what i understand it makes smoother generation.
are you talking of how to distribute the colors to our hexagons?
please understand that above we have a process with several steps:
reset
place colors except ocean/water
add water as rivers (going thin in one random direction) OR lakes (more into an area, into all directions)
That's why the water looks totally different than the other colors.
For noise()
for
noise()
see reference and here:https://forum.processing.org/two/discussion/27719/looping-perlin-noise
The problem I see is that one condition you have is that you want all hexagons of one color to be connected. So one color is always ONE area / patch and not several patches. Not to easy with noise().
Okay thanks, but is it easy to generate the base colors say ocean and grassland in noise then generate on top of the grassland random patches of trees in other code not noise.
sure.
Okay thanks i am going to try to do this now.
I think you need to define more clearly what you don't like about the current way the colors are distributed
Does the hexagons of ONE color really be connected? So they are ONE patch and not divided into 3 patches or so?
What does that change Chrisir.
very philosophical. It would help us if you would answer this.
new version for color distribution
Sorry for late response life gets busy as you know. Wow that looks great though and i appreciate the comments it helps to understand the code. I agree on ocean code in setup the new code is better.
This is the 2D array i have been working on last night.
No, it’s just another version / outcome, not better. It depends from what you want.
In this Version ocean is treated like forest just a normal patch.
In the previous version, water was superimposed over all the other patches and therefore making a more complex pattern with rivers and lakes.
Do you think you can answer my questions above?
I think you need to define more clearly what you don't like about the current way the colors are distributed
Well i was just seeing if we could get smoother terrain generation because i was looking at examples of noise generation and then i saw this one here's the link to it studio.sketchpad.cc/sp/pad/view/ro.ALuTIcV$K3D/rev.28.
Does the hexagons of ONE color really be connected? So they are ONE patch and not divided into 3 patches or so?
Not to sure what you mean here but by one color do you mean having multiple colors inside a hexagon?
but by one color do you mean having multiple colors inside a hexagon?
No, I mean if you have one patch of forest is it allowed to have another patch somewhere else, ***not connected to the first patch?
Also is this part of a game or project you’re planning? What kind?
Now i understand yes it is allowed to have multiple patches in different places.
Its kind of a game that i am trying to make. But i ran into some problems with the hexagon generation code.
Sorry i should have been more clearer at the start with this. I was just trying to code as much as possible so that way i would could get more experience with coding because i am fairly new here. That's why i was asking if you could explain the code to me because it seems you are very experienced in this sort of thing and i want to learn and grow to get better at coding.
Ah, ok. I thought it would be not allowed to separate one color (different patches of it).
That’s a huge difference, now we can just call patches several times
Yeah that's great.
MAYbe I will have a look
Does your version with 2D array work?
slightly new version:
please note that the AI Walker is better (was better in the version before already)
the distribution of colors is improved, there was a bug in the neighbor finding
one example hexagon shows its neighbors now with a small red cross (to test the neighbor finding)
Chrisir
this line at end of setup was wrong:
must be the same index for both arrays XColmns and YColmns
Remark
also the names XColmns and YColmns are not good. Should be XColumns and YRows because in a table to the right are the columns, downwards the rows.
Do you remember our good old code for the AI walker:
It was a bit lame since we have fixed numbers here and also only 4 neighbors where we have in fact 6.
The improvement is the usage of this list of where the neighbors are (what you have to add to get from one hexagon to all neighbors) :
Neat, uh?
So our AI walker boils down to
But we have to take into account that we don't want the walker to go back and forth, like forward one and back one. That'd look stupid. So we need 3 pairs of numbers which are the back and forth and exclude them:
return here means we leave the function and don't move the AI Walker:
The numbers like 0/1 and 3/4 and 2/5 are the illegal pairs and refer to the list vectorsForNeigbours (so they mean -1/1 and 29/-28 and -29/30)
for a discussion of the illegal neighbor pairs see here (numbers refer to the full red hexagon and its six neighbors, marked by red crosses X) :
Here is the entire AI Walker function :
here is a new version that uses a random walker for the initial patches and then fills the gaps
Wow this is great stuff i did notice that the AI had a bug i was trying to fix it but couldn't figure it. But the AI works great just looking at all the code you posted and slowly looking threw and learning how the new code works. I agree on the XColmns and the YRows change it makes it more clear.
;-)
Besides of color distribution:
think of a game.
e.g. settlers of Catan
https://en.wikipedia.org/wiki/Catan
and/or a mix of Settler of Catan with some "conquer areas game".
A simple approach:
Possible Game e.g.
two human players play on your board (no AI)
both start with a hexagon that belongs to them (randomly assigned to player)
they have alternating turns. (Their moves.)
Now each round the hexagons produce resources (ocean=fish, forest=wood, grassland with sheep = wool...), e.g. per round 1 fish, 1 wood etc.
Now the player that owns a hexagon gets its resources, so they get richer
to conquer / occupy a new hexagon (territory grows ) you need to invest resources. Once you own a new hexagon you also get its resources next round, so you're getting richer faster
to make the things easier, 1 fish = 1 $, 1 wood/lumber = 2 $, next 3$, next 4$ (different prices)
To conquer e.g. a new field, you must pay 5 bugs to the bank. When you own 12 bugs you can conquer 2 hexagons; only adjacent hexagons can be conquered
You have to decide which hexagon to take (that produce more wealth, so ocean is less attractive than wood etc.; hexagons owned by other player can't be bought
after 5 minutes game is over and we count the hexagons both own: who owns more has won. Display Win Message, "Player 2 has won!" or so. Ask to play again.
can be played in theory with 4 human players also or later against AI
Things to do
resources are distributed to players every turn
Each player has the resources he owns / money (variables for each player: money)
turn / round management (whose turn is it etc.)
select hexagons you want to conquer with the mouse, money is monitored
Chrisir