/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.jc0NSHwjnqf/rev.544
*
* authors:
* Farshid Naderi
* Sina Seifee
* Sina
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
int cellCount = 6; //min 3, max 20
color[] colors = {color(50), //default color
color(255,0,0,30), //player one color
color(0,0,255,30)}; //player tow color
char[] turnXO = {' ','X','O'}; //player names
int[] score = new int[3];
int turn, cSize, frame;
Cell[][] grid;
void setup() {
if (cellCount>=20)cellCount = 20;
if (cellCount<= 3)cellCount = 3;
size(400,430);
smooth();
frameRate(30);
background(10);
score[1] = 0;
score[2] = 0;
turn = 0;
cSize = width;
grid = new Cell[cellCount][cellCount];
rectMode (CORNER);
stroke(255);
strokeWeight(2);
for (int r = 0; r < cellCount; r+=1) {
for (int c = 0; c < cellCount; c+=1) {
grid[c][r] = new Cell(c, r);
}}
}
void draw() {
fill(10);
rect (0,cSize,cSize,(cSize/10));
if(turn <= cellCount*cellCount){
for (int r = 0; r < cellCount; r+=1) {
for (int c = 0; c < cellCount; c+=1) {
grid[c][r].display();
winCheck(c, r);
}}}
if(turn >= cellCount*cellCount) showWinner();
if(frameCount>frame)
if(turn%2 == 1 && turn <= cellCount*cellCount)moveAI();
textSize(cSize*.04);
textAlign(LEFT, TOP);
text("score "+str(turnXO[1])+" ("+score[1] +") "+str(turnXO[2])+" ("+score[2]+")",5,cSize+(cSize/100));
}
void mousePressed() {
if(turn%2 == 0){
if(turn < cellCount*cellCount) {
for (int r = 0; r < cellCount; r++) {
for (int c = 0; c < cellCount; c++) {
if(grid[c][r].sel==true) {
grid[c][r].val=turn%2+1;
turn++;
//cursor(WAIT);
frame = frameCount + int(random(3,20));
}}}}else setup();}
}
void showWinner(){
turn++;
String winText;
int win =0;
if(score[1]+score[2] > 0){
win = (score[1]>score[2])?1:2;
winText = str(turnXO[win]) + " is winner Score: ";
if(score[1]==score[2])
winText = ":) who's winner? Score: ";
}else{
winText = "Sorry...! no one won Score: ";
}
fill(blendColor(colors[win],color(50,50,50), MULTIPLY),20);
rect(0,0,cSize,cSize);
fill(255);
textAlign(CENTER, CENTER);
textSize(cSize*.05);
text(winText+score[1] +"/"+score[2],cSize/2,cSize/2);
textSize(cSize*.04);
text("Click for reset",cSize/2,cSize/2+(cSize*.06));
}
void winCheck(int cID, int rID){
int ci, ri, cn, rn;
int won = 0, mx = cellCount-1;
int[] c = {-1, 0, +1, +1};
int[] r = {-1, -1, -1, 0};
int[] id = new int[0];
if( grid[cID][rID].val>0 ){
for (int i = 0; i < 4 ; i++){
ci = cID+c[i]; cn = cID+(c[i]*-1);
ri = rID+r[i]; rn = rID+(r[i]*-1);
if ( ci < 0 || cn < 0 || ci > mx || cn > mx ) continue;
if ( ri < 0 || rn < 0 || ri > mx || rn > mx ) continue;
if (grid[ci][ri].val == grid[cID][rID].val && grid[cn][rn].val == grid[cID][rID].val){
if (grid[cID][rID].scr || grid[ci][ri].scr || grid[cn][rn].scr) {
line(grid[ci][ri].centerX, grid[ci][ri].centerY, grid[cn][rn].centerX, grid[cn][rn].centerY);
id = append(id, cID+cellCount*rID);
id = append(id, ci+cellCount*ri);
id = append(id, cn+cellCount*rn);
won = grid[cID][rID].val;
score[won]++;
}}}
for(int i = 0; i < id.length; i++){
ci = id[i]%cellCount;
ri = floor(id[i]/cellCount);
grid[ci][ri].scr = false;
}}
}
/////////////////////////////////////////
//// start Artificial intelligence //////
//
void moveAI() {
cursor(WAIT);
int[] priority = new int[cellCount*cellCount];
for (int r = 0; r < cellCount; r+=1) {
for (int c = 0; c < cellCount; c+=1) {
if (grid[c][r].val == 0)
grid[c][r].AI = priorityAI(c, r);
else
grid[c][r].AI = 0;
priority[c+cellCount*r] = grid[c][r].AI;
}
}
int maxP = max(priority);
int[] listID = new int[0];
for (int r = 0; r < cellCount; r+=1) {
for (int c = 0; c < cellCount; c+=1) {
if (grid[c][r].AI == maxP)
listID = append(listID, c+cellCount*r);
}
}
int id = listID[floor(random(listID.length-1))];
int c = id%cellCount;
int r = floor(id/cellCount);
grid[c][r].val = 2;
turn++;
cursor(ARROW);
}
int priorityAI(int cID, int rID) {
int p = 1;
int[] c1 = { -1, 0, +1, +1, +1, 0, -1, -1 };
int[] r1 = { -1, -1, -1, 0, +1, +1, +1, 0 };
int[] c2 = { -2, 0, +2, +2, +2, 0, -2, -2 };
int[] r2 = { -2, -2, -2, 0, +2, +2, +2, 0 };
int ci1, ri1, cin, rin, ci2, ri2;
for (int i = 0; i < 8 ; i++) {
ci1 = cID+c1[i]; cin = cID+(c1[i]*-1);
ri1 = rID+r1[i]; rin = rID+(r1[i]*-1);
ci2 = cID+c2[i]; ri2 = rID+r2[i];
if ( ci1 < 0 || ci1 > cellCount-1)continue;
if ( ri1 < 0 || ri1 > cellCount-1)continue;
p++;
if ( cin > 0 && cin < cellCount && rin > 0 && rin < cellCount )
if ( grid[ci1][ri1].val == 2 && grid[cin][rin].val == 2 )
p+=40;
if ( cin > 0 && cin < cellCount && rin > 0 && rin < cellCount )
if ( grid[ci1][ri1].val == 1 && grid[cin][rin].val == 1 )
p+=80;
if ( ci2 < 0 || ci2 > cellCount-1)continue;
if ( ri2 < 0 || ri2 > cellCount-1)continue;
p++;
if ( grid[ci1][ri1].val == 2 && grid[ci2][ri2].val == 2 ) p+= 80;
if ( grid[ci1][ri1].val == 1 && grid[ci2][ri2].val == 1 ) p+= 160;
}
return p;
}
//
//////////////////////////////end AI.////
/////////////////////////////////////////
/////////////////////////////////////////
//// start class Cell ///////////////////
//
class Cell {
boolean sel, scr;
float startX, startY;
float len, rand;
float centerX, centerY;
int AI, val;
int cID, rID;
char stringXO;
color col;
Cell(int columnID, int rowID) {
col = color(50);
AI = 0;
cID = columnID;
rID = rowID;
val = 0;
sel = false;
scr = true;
len = (cSize /cellCount);
rand= random(500);
startX = (cSize /cellCount*cID);
startY = (cSize/cellCount*rID);
centerX = startX+(len/2);
centerY = startY+(len/2);
stringXO= ' ';
}
void display(){
sel = false;
col = colors[val];
stringXO = turnXO[val];
if( mouseX > startX && mouseX < startX+len)
if( mouseY > startY && mouseY < startY+len)
if(val==0){
col = blendColor(colors[turn%2+1],color(50,50,50), MULTIPLY);
sel = true;
stringXO = turnXO[turn%2+1];
}
fill(col);
stroke(255);
rect(startX, startY, len, len);
fill(255);
textSize ((cSize*.5)/(cellCount));
textAlign(CENTER, CENTER);
float noiseX = map( noise(.03*frameCount+rand ), 0, 1, len*-.2, len*.2);
float noiseY = map( noise(.02*frameCount+rand*rand), 0, 1, len*-.2, len*.3);
text(stringXO, centerX+noiseX, centerY-noiseY);
//textSize ((cSize*.25)/(cellCount));
//text(AI,centerX,centerY-(len/3*0));
//text(cID+" "+rID,centerX,centerY+(len/3.5));
}
}
//
//////////////////////end class Cell.////
/////////////////////////////////////////