// Cloned by Fionn Gallahar Hall on 1 Dec 2022 from World "Connect4 2 Player " by Daniel O'Sullivan
// Please leave this clone trail here.
//const CLOCKTICK = 100; // speed of run - move things every n milliseconds
//const MAXSTEPS = 1000; // length of a run before final score
//---- global constants: -------------------------------------------------------
const gridsize = 3; // number of squares along side of world
const squaresize = 100; // size of square in pixels
const MAXPOS = gridsize * squaresize; // length of one side in pixels
const SKYCOLOR = 0xffffcc; // a number, not a string
const BLANKCOLOR = SKYCOLOR ; // make objects this color until texture arrives (from asynchronous file read)
const startRadiusConst = MAXPOS * 0.8 ; // distance from centre to start the camera at
const maxRadiusConst = MAXPOS * 3 ; // maximum distance from camera we will render things
const ACTION_1 = 0;
const ACTION_2 = 1;
const ACTION_3 = 2;
const ACTION_4 = 3;
const ACTION_5 = 4;
const ACTION_6 = 5;
const ACTION_7 = 6;
const ACTION_8 = 7;
//---- start of World class -------------------------------------------------------
function World()
{
// most of World can be private
// regular "var" syntax means private variables:
var GRID = new Array(gridsize); // can query GRID about whether squares are occupied, will in fact be initialised as a 2D array
var WALLS = new Array ( 4 * gridsize ); // need to keep handle to each wall block object so can find it later to paint it
var VALUES = new Array (64);
var self = this;
/*function initGrid()
{
for (var i = 0; i < gridsize ; i++)
{
GRID[i] = new Array(gridsize); // each element is an array
for (var j = 0; j < gridsize ; j++)
{
GRID[i][j] = false;
}
}
}*/
function translate ( x )
{
return ( x - ( MAXPOS/2 ) );
}
function loadTextures()
{
var loader1 = new THREE.TextureLoader();
loader1.load ( '/uploads/osulld42/connectsquare.png',
function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
paintWalls ( new THREE.MeshBasicMaterial( { map: thetexture } ) );
} );
}
function initThreeWalls() // graphical run only, set up blank boxes, painted later
{
var t = 0;
for (var i = 0; i < gridsize ; i++)
{
for (var j = 0; j < gridsize ; j++)
{
var shape = new THREE.CubeGeometry( squaresize, squaresize, squaresize );
var thecube = new THREE.Mesh( shape );
thecube.material.color.setHex( BLANKCOLOR );
thecube.position.x = translate ( i * squaresize ); // translate my simple (i,j) block-numbering coordinates to three.js (x,y,z) coordinates
thecube.position.z = translate ( j * squaresize );
thecube.position.y = 0;
threeworld.scene.add(thecube);
WALLS[t] = thecube; // save it for later
t++;
}
}
}
function paintWalls ( material ) // paint blank boxes
{
for ( var i = 0; i < WALLS.length; i++ )
{
if ( WALLS[i] )
WALLS[i].material = material;
}
}
function initValArray()
{
for(var i = 0; i < VALUES.length; i++)
{
VALUES[i] = -1;
}
}
var one = 7;
var two = 15;
var three = 23;
var four = 31;
var five = 39;
var six = 47;
var seven = 55;
var eight = 63;
var redTurn = true;
var winCheck = false;
function moveLogicalAgent( a ) // this is called by the infrastructure that gets action a from the Mind
{
if ( a === ACTION_1 && redTurn )
{
WALLS[one].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/redconnect.png" )}));
VALUES[one] = 0;
one--;
redTurn = false;
$("#user_span6").html( " <font color=yellow> <B> Yellow Turn </B> </font> ");
}
else if ( a === ACTION_1 && !redTurn )
{
WALLS[one].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/yellowconnect.png" )}));
VALUES[one] = 1;
one--;
redTurn = true;
$("#user_span6").html( " <font color=red> <B> Red Turn </B> </font> ");
}
else if ( a === ACTION_2 && redTurn && two != 7)
{
WALLS[two].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/redconnect.png" )}));
VALUES[two] = 0;
two--;
redTurn = false;
$("#user_span6").html( " <font color=yellow> <B> Yellow Turn </B> </font> ");
}
else if ( a === ACTION_2 && !redTurn && two != 7)
{
WALLS[two].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/yellowconnect.png" )}));
VALUES[two] = 1;
two--;
redTurn = true;
$("#user_span6").html( " <font color=red> <B> Red Turn </B> </font> ");
}
else if ( a === ACTION_3 && redTurn && three != 15)
{
WALLS[three].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/redconnect.png" )}));
VALUES[three] = 0;
three--;
redTurn = false;
$("#user_span6").html( " <font color=yellow> <B> Yellow Turn </B> </font> ");
}
else if ( a === ACTION_3 && !redTurn && three != 15)
{
WALLS[three].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/yellowconnect.png" )}));
VALUES[three] = 1;
three--;
redTurn = true;
$("#user_span6").html( " <font color=red> <B> Red Turn </B> </font> ");
}
else if ( a === ACTION_4 && redTurn && four != 23)
{
WALLS[four].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/redconnect.png" )}));
VALUES[four] = 0;
four--;
redTurn = false;
$("#user_span6").html( " <font color=yellow> <B> Yellow Turn </B> </font> ");
}
else if ( a === ACTION_4 && !redTurn && four != 23)
{
WALLS[four].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/yellowconnect.png" )}));
VALUES[four] = 1;
four--;
redTurn = true;
$("#user_span6").html( " <font color=red> <B> Red Turn </B> </font> ");
}
else if ( a === ACTION_5 && redTurn && five != 31)
{
WALLS[five].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/redconnect.png" )}));
VALUES[five] = 0;
five--;
redTurn = false;
$("#user_span6").html( " <font color=yellow> <B> Yellow Turn </B> </font> ");
}
else if ( a === ACTION_5 && !redTurn && five != 31)
{
WALLS[five].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/yellowconnect.png" )}));
VALUES[five] = 1;
five--;
redTurn = true;
$("#user_span6").html( " <font color=red> <B> Red Turn </B> </font> ");
}
else if ( a === ACTION_6 && redTurn && six != 39)
{
WALLS[six].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/redconnect.png" )}));
VALUES[six] = 0;
six--;
redTurn = false;
$("#user_span6").html( " <font color=yellow> <B> Yellow Turn </B> </font> ");
}
else if ( a === ACTION_6 && !redTurn && six != 39)
{
WALLS[six].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/yellowconnect.png" )}));
VALUES[six] = 1;
six--;
redTurn = true;
$("#user_span6").html( " <font color=red> <B> Red Turn </B> </font> ");
}
else if ( a === ACTION_7 && redTurn && seven != 47)
{
WALLS[seven].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/redconnect.png" )}));
VALUES[seven] = 0;
seven--;
redTurn = false;
$("#user_span6").html( " <font color=yellow> <B> Yellow Turn </B> </font> ");
}
else if ( a === ACTION_7 && !redTurn && seven != 47)
{
WALLS[seven].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/yellowconnect.png" )}));
VALUES[seven] = 1;
seven--;
redTurn = true;
$("#user_span6").html( " <font color=red> <B> Red Turn </B> </font> ");
}
else if ( a === ACTION_8 && redTurn && eight != 55)
{
WALLS[eight].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/redconnect.png" )}));
VALUES[eight] = 0;
eight--;
redTurn = false;
$("#user_span6").html( " <font color=yellow> <B> Yellow Turn </B> </font> ");
}
else if ( a === ACTION_8 && !redTurn && eight != 55)
{
WALLS[eight].material = ( new THREE.MeshBasicMaterial ( { map: THREE.ImageUtils.loadTexture( "/uploads/osulld42/yellowconnect.png" )}));
VALUES[eight] = 1;
eight--;
redTurn = true;
$("#user_span6").html( " <font color=red> <B> Red Turn </B> </font> ");
}
else
{
;
}
if(checkWinner())
{
winCheck = true;
$("#user_span6").html( " <font color=green> <B> Winner! </B> </font> " );
}
}
function keyHandler(e)
// user control
// Note that this.takeAction(a) is constantly running at same time, redrawing the screen.
{
if(winCheck) this.endCondition = true;
else if (e.keyCode == 49) moveLogicalAgent ( ACTION_1);
else if (e.keyCode == 50) moveLogicalAgent ( ACTION_2);
else if (e.keyCode == 51) moveLogicalAgent ( ACTION_3);
else if (e.keyCode == 52) moveLogicalAgent ( ACTION_4);
else if (e.keyCode == 53) moveLogicalAgent ( ACTION_5);
else if (e.keyCode == 54) moveLogicalAgent ( ACTION_6);
else if (e.keyCode == 55) moveLogicalAgent ( ACTION_7);
else if (e.keyCode == 56) moveLogicalAgent ( ACTION_8);
}
function checkWinner()
{
var check = false;
for(var i = 63; i > 55; i--)
{
var length = (i-56);
for(var j = i; j >= length; j=j-8)
{
if(VALUES[j] === -1)
;
else if((VALUES[j] === VALUES[j-8]) && (VALUES[j] === VALUES[j-16]) && (VALUES[j] === VALUES[j-24]))
{
check = true;
break;
}
}
if(check)
break;
}
for(var i = 7; i < 64; i=i+8)
{
var length = (i-7);
for(var j = i; j >= length; j--)
{
if(VALUES[j] === -1)
;
else if((VALUES[j] === VALUES[j-1]) && (VALUES[j] === VALUES[j-2]) && (VALUES[j] === VALUES[j-3]))
{
check = true;
break;
}
}
if(check)
break;
}
for(var i = 7; i > 2; i--)
{
var length = (i+32);
for(var j = i; j <= length; j=j+8)
{
if(VALUES[j] === -1)
;
else if((VALUES[j] === VALUES[j+7]) && (VALUES[j] === VALUES[j+14]) && (VALUES[j] === VALUES[j+21]))
{
check = true;
break;
}
}
if(check)
break;
}
for(var i = 63; i > 58; i--)
{
var length = (i-32);
for(var j = i; j >= length; j=j-8)
{
if(VALUES[j] === -1)
;
else if((VALUES[j] === VALUES[j-9]) && (VALUES[j] === VALUES[j-18]) && (VALUES[j] === VALUES[j-27]))
{
check = true;
break;
}
}
if(check)
break;
}
return check;
}
//--- public functions / interface / API ----------------------------------------------------------
// must have this public variable:
this.endCondition; // If set to true, run will end.
this.newRun = function()
{
// (subtle bug) must reset variables like these inside newRun (in case do multiple runs)
this.endCondition = false;
$("#user_span3").html( " <font color=black> <B> Use keys 1-8 on the top of the keyboard to put checkers into grid. Leftmost column is 1, next is 2 and so on. Once you press a button, move your mouse to update the screen! <br></B> </font> " );
$("#user_span6").html( " <font color=red> <B> Red Turn </B> </font> ");
// define logical data structure for the World, even if no graphical representation:
//initGrid();
initValArray();
//initLogicalWalls();
// if Three.js graphical representation:
if ( true )
{
threeworld.init3d ( startRadiusConst, maxRadiusConst, SKYCOLOR );
// Set up blank objects first:
initThreeWalls();
// Then paint them with textures - asynchronous load of textures from files.
// The texture file loads return at some unknown future time in some unknown order.
// Because of the unknown order, it is probably best to make objects first and later paint them, rather than have the objects made when the file reads return.
// It is safe to paint objects in random order, but might not be safe to create objects in random order.
loadTextures(); // will return sometime later, but can go ahead and render now
}
document.onkeydown = keyHandler;
};
this.endRun = function()
{
};
}