getting array coordinates (8 queens problem) - actionscript-3

I am trying to make a graphic program that solves the 8 queens problem and so far what i have is the chess board
var chessBoard:Array = new Array();
for(var i:int = 0; i < 4; i++)
{
chessBoard.push(new Array(1,0,1,0,1,0,1,0));
chessBoard.push(new Array(0,1,0,1,0,1,0,1));
}
var tileSize:int = 20;
function createChessBoard():void
{
for(var i:int = 0; i < chessBoard.length; i++)
{
for(var j:int = 0; j < chessBoard[i].length; j++)
{
var tile:Sprite = new Sprite();
var tileColor:int = chessBoard[i][j] * 0xffffff;
tile.graphics.beginFill(tileColor);
tile.graphics.drawRect(0, 0, tileSize, tileSize);
tile.graphics.endFill();
tile.x = j * tileSize;
tile.y = i * tileSize;
addChild(tile);
}
}
}
createChessBoard();
(thanks André for this code)
this creates a black and white checkered board for the problem but now i need to be able to place the queens. How am i able to see where the user clicks in order to put the queen in the box that is clicked on?
(sorry if my question isn't fully clear)

I added a very simple example to your question. See below:
var chessBoard:Array = new Array();
for(var i:int = 0; i < 4; i++)
{
chessBoard.push(new Array(1,0,1,0,1,0,1,0));
chessBoard.push(new Array(0,1,0,1,0,1,0,1));
}
var tileSize:int = 20;
function createChessBoard():void
{
for(var i:int = 0; i < chessBoard.length; i++)
{
for(var j:int = 0; j < chessBoard[i].length; j++)
{
var tile:Sprite = new Sprite();
var tileColor:int = chessBoard[i][j] * 0xffffff;
tile.graphics.beginFill(tileColor);
tile.graphics.drawRect(0, 0, tileSize, tileSize);
tile.graphics.endFill();
//I added the name property and a MouseEvent.CLICK event listener
tile.name = "tile__" + i + "_" j + "_sp";
tile.addEventListener(MouseEvent.CLICK, onTileClick);
tile.x = j * tileSize;
tile.y = i * tileSize;
addChild(tile);
}
}
}
function onTileClick(event:MouseEvent):void
{
//This tells you which tile the user clicked on
trace(event.target.name);
};
createChessBoard();
Good luck,
Rob

Related

How to Save positions for 3 objects in Array to make random position between each other by AS3?

How to Save positions for 3 objects in Array to make random position between each other by AS3?
import flash.geom.Point;
var arry:Point = new Point();
arry[0] = arry[78,200];
arry[1] = arry[217,200];
arry[2] = arry[356,200];
//object called b1
b1.x = arry[0][0];
b1.y = arry[0][1];
//object called b2
b2.x = arry[1][0];
b2.y = arry[1][1];
//object called b3
b3.x = arry[2][0];
b3.y = arry[2][1];
//make objects swap positions between each other
var rand:Number = (Math.random()*arry.length);
//output to see random position [[78,200],[217,200],[356,200]]
trace(arry);
to get random with tween like this... https://www.youtube.com/watch?v=8m_m64plQ6E
At compile time you should get this Error I suppose : "ReferenceError: Error #1069"
Here is a way to store the positions (like in the link you provided from youtube) :
import flash.geom.Point;
var squareWidth:uint = 40;
var squareHeight:uint = 40;
var marginX:uint = 100;
var marginY:uint = 75;
var spacer:uint = 10;
var positions:Vector.<Point > = new Vector.<Point > (9);
function setPositions(v:Vector.<Point>):void {
var count:uint = 0;
var posx:uint;
var posy:uint;
for (var i = 0; i < 3; i ++)
{
for (var j = 0; j < 3; j ++)
{
posx = (j * squareWidth) + (spacer * j) + marginX;
posy = (i * squareHeight) + (spacer * i) + marginY;
v[count] = new Point(posx,posy);
count++;
}
}
}
setPositions(positions);
trace(positions);
// output :
// (x=100, y=75),(x=150, y=75),(x=200, y=75),(x=100, y=125),(x=150, y=125),(x=200, y=125),(x=100, y=175),(x=150, y=175),(x=200, y=175)
So here you have nine Points to place the clips like in the video.
You just have to add a function to swap the nine boxes stored in another Vector.
In your case.
For 3 positions do the following if I understand your question.
import flash.geom.Point;
var positions:Vector.<Point> = new Vector.<Point>(3);
var p1:Point = new Point(78,200);
var p2:Point = new Point(217,200);
var p3:Point = new Point(356,200);
positions[0] = p1;
positions[1] = p2;
positions[2] = p3;
trace(positions);
// output : (x=78, y=200),(x=217, y=200),(x=356, y=200)
So, you're still unclear!
Your issue is to find a random position?
This may help you if this is the problem you're facing :
import flash.geom.Point;
var positions:Vector.<Point > = new Vector.<Point > (3);
var numbers:Vector.<uint> = new Vector.<uint>();
var numbersAllowed:uint = 3;
var rndNmbrs:Vector.<uint> = new Vector.<uint>(3);;
var p1:Point = new Point(78,200);
var p2:Point = new Point(217,200);
var p3:Point = new Point(356,200);
positions[0] = p1;
positions[1] = p2;
positions[2] = p3;
trace(positions);
function populateRndNmbrs(n:uint):void {
for (var i:uint = 0; i < n; i++)
{
numbers[i] = i;
}
}
populateRndNmbrs(numbersAllowed);
function populateRandomNumbers(n:uint):void
{
var rnd:uint;
for (var i:uint = 0; i < n; i++)
{
rnd = numbers[Math.floor(Math.random() * numbers.length)];
for (var j:uint = 0; j < numbers.length; j++)
{
if (rnd == numbers[j])
{
numbers.splice(j,1);
}
}
rndNmbrs[i] = rnd;
}
}
populateRandomNumbers(numbersAllowed);
trace("rndNmbrs = " + rndNmbrs);
for (var i:uint = 0; i < numbersAllowed; i++)
{
trace("b"+ (i+1) + ".x = " + positions[rndNmbrs[i]].x);
trace("b"+ (i+1) + ".y = " + positions[rndNmbrs[i]].y);
// In place of trace, you should place the boxes at those random positions.;
}
//output:
//(x=78, y=200),(x=217, y=200),(x=356, y=200)
//rndNmbrs = 2,0,1
//b1.x = 356
//b1.y = 200
//b2.x = 78
//b2.y = 200
//b3.x = 217
//b3.y = 200
Is that what you want? Or do you want to know how to create a motion effect?
I'm not sure about what you really need...
This will help you to place all the boxes in a random position.
You may do this like here bellow, and add a function to check if the random positions are not the same.
With only 3 MovieClips, you will often have the same random positions as long they're stored in the "positions Vector"
var squares:Vector.<MovieClip> = new Vector.<MovieClip>(3);
function populateMCs(target:DisplayObjectContainer,n:uint):void{
for (var i:uint = 0; i < n; i++){
squares[i] = target["b"+(i+1)];
}
}
function swapMCs():void{
for (var i:uint=0; i<squares.length; i++){
squares[i].x = positions[rndNmbrs[i]].x;
squares[i].y = positions[rndNmbrs[i]].y;
}
}
populateMCs(this,numbersAllowed);
swapMCs();
I give you a last example to get a motion effect in AS3.
I'm not a translator AS2 -> AS3 and a video is not the best way to show your code :(
This will make your boxes move smoothly, but not the way you want.
Now, you have to learn AS3 and try to make the job by yourself.
Then, if you have another issue, just ask clearly what you want.
var friction:Number = 0.15;
setDestination(squares[0],squares[0].x,350,friction);
setDestination(squares[1],squares[1].x,350,friction);
setDestination(squares[2],squares[2].x,350,friction);
squares[0].addEventListener(Event.ENTER_FRAME,moveClip);
squares[1].addEventListener(Event.ENTER_FRAME,moveClip);
squares[2].addEventListener(Event.ENTER_FRAME,moveClip);
function setDestination(mc:MovieClip,x:uint,y:uint,friction:Number):void{
mc.destinx = x;
mc.destiny = y;
mc.f = friction;
}
function moveClip(e:Event):void{
var mc:MovieClip = e.target as MovieClip;
trace(mc.name)
mc.speedx = (mc.destinx - mc.x);
mc.speedy = (mc.destiny - mc.y);
mc.x += mc.speedx*mc.f;
mc.y += mc.speedy*mc.f;
if((Math.floor(mc.speedx)<1) && (Math.floor(mc.speedy)<1)){
mc.removeEventListener(Event.ENTER_FRAME,moveClip);
trace("STOP MOVE FOR " + mc.name);
}
}

adding X amount of addChild per maxvalue in loop

The assignment is the spawn several light and dark feathers according to score points from a quiz. The light feathers symbolize the correct points (light_feather), and the dark feather are the incorrect points (dark_feather) (Each are being tracked). All the feathers are supposed to line up on one line, meaning first light feathers, followed by the dark feathers. I got the quiz dynamics figured out, and the function I have posted here is only for when they press end quiz.
var light_feather:LightFeather = new LightFeather();
var dark_feather:DarkFeather = new DarkFeather();
var good_answers:uint = 0;
var bad_answers:uint = 0;
function avsluttFunc (evt:MouseEvent)
{
var sum_LightFeatherX:Number = 0;
for (var i = 0; i < good_answers; i++) {
addChild(light_feather);
light_feather.x += 12 + (i*16);
light_feather.y = 0;
trace("Lys X-verdi: " + light_feather.x);
sum_LightFeatherX += Number(light_feather.x);
return sum_LightFeatherX;
}
trace(sum_LightFeatherX);
dark_feather.x += sum_LightFeatherX;
for (var j = 1; j <= bad_answers; j++) {
addChild(dark_feather);
dark_feather.x += 12 + (j*16);
dark_feather.y = 0;
trace("Mørk X-verdi: " + dark_feather.x);
}
/*
//Resetter poengsummen
good_answers = 0;
bad_answers = 0;
*/
}
You can do what you are looking for using only one for loop, take a look :
var good_answers:uint = 2;
var bad_answers:uint = 4;
function avsluttFunc(evt:MouseEvent)
{
for (var i:int = 0; i < good_answers + bad_answers; i++) {
var feather:DisplayObject = i < good_answers ? new LightFeather() : new DarkFeather();
feather.x += 12 + i * (feather.width + 1);
feather.y = 0;
addChild(feather);
}
}
This code example will create 4 DarkFeather instances next to 2 LightFeather ones.
Edit :
How to add your objects to an array ?
// feathers array should be accessible for both codes (adding and removing objects)
var feathers:Array = [];
for (var i:int = 0; i < good_answers + bad_answers; i++) {
var feather:DisplayObject = i < good_answers ? new LightFeather() : new DarkFeather();
addChild(feather);
feathers.push(feather);
}
then to remove them from the stage, you can do for example :
for (var i:int = 0; i < feathers.length; i++) {
var feather:DisplayObject = DisplayObject(feathers[i]);
feather.parent.removeChild(feather);
}
Hope that can help.

Why doesn't my For loop create more than one object on the screen?

Having a bit of a problem. I'm trying to add 10 items to the stage but it is only adding 1. Any insight on what I'm doing wrong?
public var numCells:Array = [];
public function addCell():void
{
var cell:Cell = new Cell();
var i:int = 0;
cell.x = Math.floor(Math.random() * 1366);
cell.y = Math.floor(Math.random() * 768);
for(var i:int = 0; i < 10; i++)
{
numCells.push(cell);
addChild(cell);
}
return;
}
You are only ever instantiating one cell. calling addChild a second time with the same object passed in doesn't make a copy of that object, it just moves it to the top most 'layer'.
You need to instantiate a new cell inside the for loop. Something like this:
private function addCells():void {
for(var i:int = 0; i < 10; i++){
var cell:Cell = new Cell();
cell.x = Math.floor(Math.random() * 1366);
cell.y = Math.floor(Math.random() * 768);
numCells.push(cell);
addChild(cell);
}
}

A more efficient way to pick and place tiles?

is it wrong to pick and place my tiles like this?
In other words, whats a better way to place the tiles so removing and adding a different tile is easy. Or what is a good method of doing so with the way i have it set up.
Whats a good way to reference a specific tile on the map?
public class Stage extends MovieClip
{
protected var tilesInWorld:Vector.<MovieClip> = new Vector.<MovieClip>();
public var worldTiles:Sprite;
protected var tile:MovieClip;
protected var TILE_SIZE:int = 5;
protected var map_width:int = 800;
protected var map_height:int = 600;
protected var pmap:BitmapData = new BitmapData(map_width,map_height);
protected var _seed:uint = Math.round(Math.random() * 100);
protected var grid_width:uint = new uint(map_width / TILE_SIZE);
protected var grid_height:uint = new uint(map_height / TILE_SIZE);
protected var heightmap:Array = new Array();
protected var pixelPoint:Point = new Point();
protected var darkest_pixel:Number = 1;
protected var brightest_pixel:Number = 0;
protected var hm :Number;
public function Stage()
{
pmap.perlinNoise(map_width,map_height, 6, _seed, true, false, 1, true);
for (var i:uint=0; i < grid_width; i++)
{
heightmap[i] = new Array();
for (var j:uint=0; j < grid_height; j++)
{
heightmap[i][j] = new uint();
}
}
//Divide the map in to a 7x7 grid and take data at each interval
for (i=0; i < grid_width; i++)
{
for (j=0; j < grid_height; j++)
{
pixelPoint.x = Math.round((i/grid_width) * pmap.width)+1;
pixelPoint.y = Math.round((j/grid_width) * pmap.height)+1;
heightmap[i][j] = pmap.getPixel(pixelPoint.x,pixelPoint.y);
heightmap[i][j] /= 0xffffff;
if (heightmap[i][j] < darkest_pixel)
{
darkest_pixel = heightmap[i][j];
}
}
}
//Adjust values to a min of 0
for (i=0; i < grid_width; i++)
{
for (j=0; j < grid_height; j++)
{
heightmap[i][j] -= darkest_pixel;
if (heightmap[i][j] > brightest_pixel)
{
brightest_pixel = heightmap[i][j];
}
}
}
//Adjust values to highest value of 1
for (i=0; i < grid_width; i++)
{
for (j=0; j < grid_height; j++)
{
heightmap[i][j] /= brightest_pixel;
}
}
worldTiles = new Sprite();
addChild(worldTiles);
placeTile();
}
The part below this is the main part im referring too
protected function placeTile()
{
for (var i=0; i < grid_width; i++)
{
for (var j=0; j < grid_height; j++)
{
hm = heightmap[i][j];
if (hm >= 0.84)
{
tile = new Water();
}
else if (hm >= 0.8 && hm < 0.84)
{
tile = new Shallow();
}
else if (hm >= 0.7 && hm < 0.8)
{
tile = new Sand();
}
else if (hm >= 0.2 && hm < 0.7)
{
tile = new Tile();
}
else
{
tile = new Stone();
}
tile.width = TILE_SIZE;
tile.height = TILE_SIZE;
worldTiles.x = 0;
worldTiles.y = 0;
tile.x = TILE_SIZE * (i % grid_width);
tile.y = TILE_SIZE * (j % grid_height);
tilesInWorld.push(tile);
worldTiles.addChild(tile);
}
}
}
}
is there a more efficient way of picking and placing the tiles?
and while i have your attention, how can i go about deleting and replacing the tiles?
It would be better to not do so many array look-ups.
//..
var hm :Number;
for (var i=0; i < grid_width; i++)
{
for (var j=0; j < grid_height; j++)
{
hm = heightmap[i][j];
if (hm >= 0.84)
{
tile = new Water();
}
else if ( hm >= 0.8 && hm < 0.84)
{
//...
Also you might want to look at object pooling. Here is a nice video tutorial about object pooling.
Apart of that I can't see much more to optimise here. But I am sure others will give you more tips.

Position of buttons as3

I need some help with Positions of buttons in AS3. Same as before Topic, i made a IRC client with AS3, but when a user join a channel, there will be a button added, but if there is already a button and the user join new channel on IRC, there will be added new button also, this for every channel that a user does join, but It should to be positioned after the last button (side by side). Same for if a user join more channels. How can i do this on best way with x and y positions?
This is my code for now:
function onChannelButton(channel)
{
var test:MovieClip = new MovieClip();
var btn:Button;
for(var j:int = 0; j < btn.length; j++) {
btn = new Button();
btn.name = "btn";
btn.label = channel;
btn.width = 90;
btn.x = 120;
btn.y = 487.25;
test.addChild(btn);
}
addChild(test);
}
Hopefully, u can help me! Thanks!
Try this:
const PADDING:uint = 10;
const NUM_BUTTONS:uint = 10;
onChannelButton();
function onChannelButton():void {
var test:Sprite = new Sprite();
var btn:Button;
//NUM_BUTTONS or btn.length ? (Don't know about your Button class
for (var i:int = 0; i < NUM_BUTTONS; i++)
{
btn = new Button();
btn.name = "btn";
btn.width = 90;
btn.x = (btn.width + PADDING) * i;
test.addChild(btn);
}
addChild(test);
}
I typically do something like the following, using your iterator j to determine the x and y position.
I've created four variables to hopefully make the code pretty self explanatory. In this case, the y position does not change per btn, which is why the btnSpacingY is set to 0.
var btnStartX:Number = 120;
var btnStartY:Number = 487.25;
var btnSpacingX:Number = 120;
var btnSpacingY:Number = 0;
function onChannelButton(channel) {
var test:MovieClip = new MovieClip();
var btn:Button;
for (var j:int = 0; j < 10; j++) {
btn = new Button();
btn.name = "btn";
btn.label = channel;
btn.width = 90;
btn.x = btnStartX + (j * btnSpacingX);
btn.y = btnStartY + (j * btnSpacingY);
test.addChild(btn);
}
addChild(test);
}