Actionscript 3 - How to Check if an Array Position Already Exists - arrays

Hello my question is as stated. I have a randomly generated dungeon with a player and random blocks. All the rooms in the dungeon are saved in the ROOMS 2D array which contains the data for the rooms. You have a current Row and current Col which is where the player is at. What i need to know is how to say IF there is no room above the current position then change the outside wall graphic to close the exits/doors where there is no room. I have this somewhat working but everyway i change it there is always one room which just will not work if i try to add the code. What i have now is abunch of if statements saying IF ROOMS[currentRow + 1][currentCol](< that would be equal to down) so if one row up exists then change the graphic by doing gotoAndStop. So how or which is the best way to determine if a position exists because with this, it will randomly comeback with errors like "term is undefined and has no properties." Also i have really dirty code, sorry im new, ill try to clean it up later but if any of you feel like it, i wont stop you haha!
Im grateful for any replies! Here is my room class
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Room extends MovieClip{
var room1:Array = new Array();
var room2:Array = new Array();
var room3:Array = new Array();
var room4:Array = new Array();
var room5:Array = new Array();
var room6:Array = new Array();
var room7:Array = new Array();
var room8:Array = new Array();
var room9:Array = new Array();
var room10:Array = new Array();
var currentRow:int = 0;
var currentCol:int = 0;
var box:Box;
var boxes:Array;
var ROOMS:Array;
var onTop:Boolean;
var moved:Boolean;
private var player:Player;
private var walls:Walls;
private var blocker1:Blocker;
private var blocker2:Blocker;
private var blocker3:Blocker;
private var blocker4:Blocker;
private var arrowImage:ArrowSymbol;
public function Room(){
init();
createRooms();//add the walls + boxes of first room to the first array value // later make floors array that contains all the rooms and room array that contains all the boxes and enemies + events
stage.addChild(ROOMS[currentRow][currentCol]);
Constants.wallsRef = ROOMS[currentRow][currentCol];
addEventListener(Event.ENTER_FRAME, update);
stage.addChild(arrowCount);
stage.addChild(arrowImage);
}
function init(){
Constants.stageRef=stage;
player = new Player();
//add walls
walls = new Walls();
Constants.wallsRef=walls;
blocker1 = new Blocker();//BLOCKER WHEN PLAYER TOUCHES IT CHANGES ROOM
blocker1.x = 350;
blocker1.y = 1;
stage.addChild(blocker1);
blocker2 = new Blocker();
blocker2.x = 350;
blocker2.y = 619;
stage.addChild(blocker2);
blocker3 = new Blocker();
blocker3.x = -30;
blocker3.y = 300;
blocker3.rotation = 90;
stage.addChild(blocker3);
blocker4 = new Blocker();
blocker4.x = 700;
blocker4.y = 300;
blocker4.rotation = 90;
stage.addChild(blocker4);
Constants.blockerRef1 = blocker1;
Constants.blockerRef2 = blocker2;
Constants.blockerRef3 = blocker3;
Constants.blockerRef4 = blocker4;
//add player
player.x = 300;
player.y = 200;
stage.addChild(player);
arrowImage = new ArrowSymbol();
arrowImage.x = 630;
arrowImage.y = 30;
box = new Box();
boxes = new Array();
ROOMS = new Array([room2],
[room6, room1, room5], /// THIS IS THE MAP OF THE FLOOR /// GOING UP ON THE GAME IS GOING DOWN ON IT
[room7, room8],
[room3, room9],
[room4]);//THIS WILL EVENTUALLY BE COMPLETELY RANDOMIZED//
onTop = false;
moved = false;
}
function update(e:Event){
arrowCount.text = " " + Constants.arrowNumRef;//arrow amount left
closeUnnecessaryExits();
//UP
if(Constants.blockerRef1.hitTestPoint(player.x,player.y) && moved != true){
stage.removeChild(ROOMS[currentRow][currentCol]);//remove the room you are in so the new room doesnt overlap
currentRow++;//change where the player is in
stage.addChild(ROOMS[currentRow][currentCol]);//add new room
Constants.wallsRef = ROOMS[currentRow][currentCol];//add colision
player.y = 600;
stage.addChild(arrowCount);
stage.addChild(arrowImage);
trace();
moved = true;
}else if(Constants.playerRef.hitTestObject(Constants.blockerRef1) == false && moved == true){
moved = false;
}
//DOWN
if(Constants.blockerRef2.hitTestPoint(player.x,player.y) && moved != true){
//this will be where i want to change rooms
stage.removeChild(ROOMS[currentRow][currentCol]);
currentRow--;
Constants.wallsRef = ROOMS[currentRow][currentCol];
stage.addChild(ROOMS[currentRow][currentCol]);
player.y = 10;//change to 600
moved = true;
trace("changed rooms");
stage.addChild(arrowCount);
stage.addChild(arrowImage);
}else if(Constants.playerRef.hitTestObject(Constants.blockerRef1) == false && moved == true){
moved = false;
}
//LEFT
if(Constants.blockerRef3.hitTestPoint(player.x,player.y) && moved != true){
stage.removeChild(ROOMS[currentRow][currentCol]);//remove the room you are in so the new room doesnt overlap
currentCol--;//change where the player is in
stage.addChild(ROOMS[currentRow][currentCol]);//add new room
Constants.wallsRef = ROOMS[currentRow][currentCol];//add colision
player.x = 600;
stage.addChild(arrowCount);
stage.addChild(arrowImage);
moved = true;
}else if(Constants.playerRef.hitTestObject(Constants.blockerRef1) == false && moved == true){
moved = false;
}
//RIGHT
if(Constants.blockerRef4.hitTestPoint(player.x,player.y) && moved != true){
//this will be where i want to change rooms
stage.removeChild(ROOMS[currentRow][currentCol]);
currentCol++;
Constants.wallsRef = ROOMS[currentRow][currentCol];
stage.addChild(ROOMS[currentRow][currentCol]);
player.x = 10;//change to 600
moved = true;
trace("changed rooms");
stage.addChild(arrowCount);
stage.addChild(arrowImage);
}else if(Constants.playerRef.hitTestObject(Constants.blockerRef1) == false && moved == true){
moved = false;
}
}
function createRooms(){
for(var r = 0; r <ROOMS.length; r++){
walls = new Walls();
addRandomBlocks();
for(var c = 0; c < ROOMS[r].length; c++){
walls = new Walls();
addRandomBlocks();
ROOMS[r][c] = walls;
}
trace(ROOMS[r][c]);
}
}
// [room2, NaN],
// [room6, room1, room5], /// THIS IS THE MAP OF THE FLOOR /// GOING UP ON THE GAME IS GOING DOWN ON IT
// [room7, room8],
// [room3, room9],
// [room4]);
function closeUnnecessaryExits(){
trace("ROW: " + currentRow + " COL: " + currentCol);
var up = ROOMS[currentRow + 1];
var down = ROOMS[currentRow - 1];
var right = ROOMS[currentRow][currentCol + 1];
var left = ROOMS[currentRow][currentCol - 1];
//check to see which outside wasall to use
if(ROOMS[currentRow + 1] == null && up && right && left){
ROOMS[currentRow][currentCol].gotoAndStop(2);
}else if(down == null && left == null && right && up){
ROOMS[currentRow][currentCol].gotoAndStop(3);
}else if(down == null && left == null && up == null && right){
ROOMS[currentRow][currentCol].gotoAndStop(4);
}else if(left == null && down && right && up){// IF HAVING PROBLEMS THEN MAKE THIS MAKE SURE ALL OTHER SIDES ARE TRUE
ROOMS[currentRow][currentCol].gotoAndStop(5);
}else if(down == null && left == null && right == null && up){
ROOMS[currentRow][currentCol].gotoAndStop(6);
}else if(down && up == null && right == null && left == null){
ROOMS[currentRow][currentCol].gotoAndStop(7);
}else if(ROOMS[currentRow + 1][currentCol] == null && ROOMS[currentRow - 1][currentCol] && left && right){
ROOMS[currentRow][currentCol].gotoAndStop(8);
trace("works 1");
}else if(left && right && ROOMS[currentRow - 1][currentCol] == null && ROOMS[currentRow + 1][currentCol] == null){
ROOMS[currentRow][currentCol].gotoAndStop(9);
trace("works 2");
}else if(left && ROOMS[currentRow - 1][currentCol] && right == null && ROOMS[currentRow + 1][currentCol] == null){
ROOMS[currentRow][currentCol].gotoAndStop(10);// LEFT DOWN
trace("works 3");
}else if(left && ROOMS[currentRow + 1][currentCol] && ROOMS[currentRow - 1][currentCol] == null && right == null){
ROOMS[currentRow][currentCol].gotoAndStop(11);//BROKEN left up
trace("working 4");
}else if(left && ROOMS[currentRow + 1][currentCol] == null && ROOMS[currentRow - 1][currentCol] == null && right == null){
ROOMS[currentRow][currentCol].gotoAndStop(12);
trace("works 5");
}else if(right == null && left && up && down){
ROOMS[currentRow][currentCol].gotoAndStop(13);
trace("works 6");
}
}
function addRandomBlocks(){
for(var e=0; e <Math.random() * 10; e++){
//trace("started block");
box = new Box();
box.x = Math.random() * (615 - 100) + 100;
box.y = Math.random() * (500 - 120) + 120;
//colision for block to block
for(var col = 0; col < boxes.length; col++){
if(box.hitTestObject(boxes[col])){
onTop = false;/// THIS NEEDS TO BE TRUE FOR THE DETECTION TO WORK
//trace("THIS BOX IS ON TOP OF ANOTHER");
}
}
if(onTop == false){
boxes.push(box);
walls.addChild(box);
trace("BOX CREATED " + onTop);
//trace(boxes);
}
}
}
}
}

You could streamline your code by creating some simple functions that deal with assigning and accessing values in your 2D array. One that checks if an element within a 2D array exists might look like:
function cellExists(array:Array, x:int, y:int):Boolean {
return array[y] !== undefined && array[y][x] !== undefined;
}
Used like, in your example:
if (cellExists(ROOMS, currentCol, currentRow)) {
//
}
Although with this type of task you would benefit greatly from implementing a class that handles grid + cell data, something along the lines of this to get you started:
public class Grid {
private var _content:Vector.<Vector.<Cell>>;
public function Grid(columns:int, rows:int) {
// Fill _content with empty slots based on columns, rows.
}
public function getCell(x:int, y:int):Cell {}
public function cellExists(x:int, y:int):Boolean {}
}

Related

Loop through specific columns and setting value

I have a script but it works pretty slow and Im trying to see if I could make it work faster by possibly making it loop through the columns 10,12,15,17,20,22,25,27,30,32,35,37,40,42,45,47,50,52,55,57 instead of writing an if statement for each column. The way I currently have it works but it's slow and looks like this
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Student Data-NEA" ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( r.getColumn() == 10 && r.getValue() == 'P') { //checks the column
var nextCell = r.offset(0, 1);
//if( nextCell.getValue() !== '' ) //is empty?
nextCell.setValue("P- N/A");
}
if( r.getColumn() == 12 && r.getValue() == 'P') { //checks the column
var nextCell = r.offset(0, 1);
//if( nextCell.getValue() !== '' ) //is empty?
nextCell.setValue("P- N/A");
}
if( r.getColumn() == 15 && r.getValue() == 'P') { //checks the column
var nextCell = r.offset(0, 1);
//if( nextCell.getValue() !== '' ) //is empty?
nextCell.setValue("P- N/A");
}
if( r.getColumn() == 17 && r.getValue() == 'P') { //checks the column
var nextCell = r.offset(0, 1);
//if( nextCell.getValue() !== '' ) //is empty?
nextCell.setValue("P- N/A");
}
Etc.
What it does is it looks at a column and if there is a P then it offsets 1 column and pastes a P- N/A. Could someone help making the script shorter so it can run faster? Thank you.
You need to use getValues(range). This way you get an array. You can process this array and then use setValues(range) to fill all cells in the range at once with values of the array. It will work much faster.
Probably something like this:
function main() {
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() != "Student Data-NEA") return;
var r = s.getActiveCell(); // current cell
var row = r.getRow(); // index of current row
var row_range = s.getRange("A"+row+":Z"+row); // get range of the row
var row_values = row_range.getValues().flat(); // get array [cell, cell, cell]
var value = "P- N/A";
// change the array (not the sheet)
if (row_values[9] == "P") row_values[10] = value;
if (row_values[11] == "P") row_values[12] = value;
if (row_values[14] == "P") row_values[15] = value;
if (row_values[16] == "P") row_values[17] = value;
// change the sheet
row_range.setValues([row_values]); // set all values for the row at once
}
If your conditions all the same, you can loop through list of columns this way:
var condition = "P";
var columns = [9, 11, 14, 16];
for (var col of columns) {
if (row_values[col] == condition) row_values[col+1] = value;
}
// instead of this
// if (row_values[9] == "P") row_values[10] = value;
// if (row_values[11] == "P") row_values[12] = value;
// if (row_values[14] == "P") row_values[15] = value;
// if (row_values[16] == "P") row_values[17] = value;
Update
I don't know why I do it, since the author of the question still provided almost no information about what he does with the table and we have no sample of the table, etc. But whatever:
If you need to change next cell to "P- N/A" (do you need it? I still have no idea) in some columns if edited cell contains "P", here is a script:
function onEdit(e) {
var s = e.source.getActiveSheet();
if (s.getName() != "Student Data-NEA") return;
var col = e.range.columnStart;
var row = e.range.rowStart;
var range = s.getRange(row,col,1,2);
var range_array = range.getValues();
var cell_value = range_array[0][0];
var next_cell_value = "P- N/A";
var cols = [10, 12, 15, 17];
if (cell_value == "P" && cols.includes(col)) {
range_array[0][1] = next_cell_value;
range.setValues(range_array);
}
}
But actually it can be done much easier and faster with standard Excel-like function (example for the cell "K1"):
=IF(EQ(J1,"P"),"P- N/A","")
Just populate with this function the columns K, M, P, R...

Efficiently navigating arrays and selected strings

I am a noob playing around with actionscript but i feel this question is a basic coding questionMy project is similar to this picture.
I have four quadrant areas (Red, blue, yellow, and green) that I am adding text buttons to each area with a single word in each button. There are 16 words in each section that are added from 4 arrays that have the preset words (redWordArray, greenWordArray, yellowWordArray, blueWordArray). When clicked, the text button glows using a glow filter and the word gets added to another array for data collecting. For instance, a red word when clicked gets added to a red array (redChosenArray). When the word is clicked again, it removes the glow filter and is removed from the chosen array.
I am finding that my performance is slow and I am wondering if I am adding and deleting words correctly and efficiently. These are my functions for adding the glow filters and the selected word to the array. I would love your insights for best coding practices as I am sure it is a mess!
Thank you!
function selectWord(event:MouseEvent):void
{
var tempWord:String = event.currentTarget.mood.text;
var tempArray:Array;
if (event.currentTarget.clicked == false)
{
event.currentTarget.filters = filterArray;
event.currentTarget.clicked = true;
tempArray = addToArray(tempWord)
tempArray.push(tempWord);
trace(redChosen);
trace(blueChosen);
trace(yellowChosen);
trace(greenChosen);
trace("");
}else if(event.currentTarget.clicked == true)
{
event.currentTarget.filters = emptyFilterArray;
event.currentTarget.clicked = false;
removeMoodWord(tempWord);
trace(redChosen);
trace(blueChosen);
trace(yellowChosen);
trace(greenChosen);
trace("");
}
}
function addToArray(moodWord:String):Array
{
var wordFound:Boolean = false;
var allWords:int = 16;
var chosenArray:Array;
while (!wordFound)
{
for (var h:int = 0; h < allWords; h++)
{
if (moodWord == redWords[h])
{
chosenArray = redChosen;
wordFound = true;
}else if (moodWord == yellowWords[h])
{
chosenArray = yellowChosen
wordFound = true;
}else if (moodWord == greenWords[h])
{
chosenArray = greenChosen
wordFound = true;
}else if (moodWord == blueWords[h])
{
chosenArray = blueChosen
wordFound = true;
}
}
}
return chosenArray;
}
function removeMoodWord(moodWord:String):void
{
if (redChosen.indexOf(moodWord) >= 0)
{
redChosen.splice(redChosen.indexOf(moodWord), 1);
}else if (blueChosen.indexOf(moodWord) >= 0)
{
blueChosen.splice(blueChosen.indexOf(moodWord), 1);
}else if (yellowChosen.indexOf(moodWord) >= 0)
{
yellowChosen.splice(yellowChosen.indexOf(moodWord), 1);
}else if (greenChosen.indexOf(moodWord) >= 0)
{
greenChosen.splice(greenChosen.indexOf(moodWord), 1);
}
i fee}

D3 import .csv to 2Darray & opacity change when hover

I'm currently writing a visualization via D3 and I hope you can help me out.
To get an idea of what I'm making you can view this link: https://dl.dropboxusercontent.com/u/56480311/Data-visualization/index.html
I'm facing two problems: the first is that I can't seem to place .csv data in a 2D array. I found multiplie tutorials about placing it in a normal array but the only solution I came up with if your data is in a table, is to use a 2D array. I couldn't find how to do this so what I thought would help:
var lines = []; //define lines as an array
//retrieve data from .csv file
d3.csv("https://dl.dropboxusercontent.com/u/56480311/Data-visualization/growth-prep.csv", function(data) {
lines = data.map(function(d) {
return d;
});
});
//create 2D array named myArray
var myArray = new Array(10);
for (var i = 0; i < 10; i++) {
myArray[i] = new Array(18);
}
//place each value of .csv file into myArray
for (var j = 0; j < lines.length; j++) {
var values = lines[j].split(";");
for (var k = 0; k < values.length; k++) {
myArray[k][j] = values[k];
}
}
This code doesn't work, however. Console keeps saying that the arrays are undefined and they're empty.
A second problem I'm facing is in visualizing the data. I sum three values that are next to each other (so for example dataset[0][0] + dataset[0][1] + dataset[0][2]). I draw this value as the width of a rectangle. On top of that, I want to draw three different rectangles each with the value of one of three. So in this case there is one rectangle consisting of dataset[0][0] + dataset[0][1] + dataset[0][2] and on top there is a rectangle showing data dataset[0][0], one showing data dataset[0][1] and a third showing data dataset[0][2]. I want the three smaller ones only to appear once the mouse hovers over the 'sum' / parent rectangle.
If you view the link you can see what I mean. Everything is already there, only the three smaller rectangles have opacity 0 so you don't see them yet (but you can find them via inspect elements).
I figured I could do this by setting the opacity of the three rectangles to 0 and to 1 once the mouse hovers. The best solution to me would be to place the three rectangles into one kind of div. Once the mouse hovers over it, its opacity is 1. Only I can't figure out how to easily give different class names without having to do it by hand for each rectangle separately. Does anyone know how to do this or else have a better solution to change the opacity of all three rectangles once the mouse hovers over the 'bigger' rectangle?
This is the code:
var dataset = [[6,6,3,3,3,0,6,6,0,12,6,6,0,0,18,6,3,3],[3,0,0,6,3,0,3,3,0,9,3,0,0,0,18,6,6,6],[3,0,3,6,3,3,6,0,3,9,6,3,0,0,15,6,6,6],[6,6,3,3,0,3,6,6,6,12,6,6,0,0,18,6,6,3],[6,6,0,6,0,0,6,6,6,12,6,6,0,0,24,6,6,0],[3,6,3,6,3,3,6,6,3,3,0,0,0,0,15,3,9,6],[3,3,0,3,0,3,3,3,3,9,3,0,0,0,15,6,3,9],[0,0,0,3,0,6,6,3,3,3,0,3,0,0,24,6,12,6],[6,6,3,6,0,0,9,9,6,12,6,6,0,0,15,3,3,3],[6,6,0,6,3,0,6,6,0,9,6,3,0,0,9,3,6,0]];
var h = 800;
var w = 800;
//create svg of 800x800px
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
var xPos = 150;
for (var k = 0; k < 10; k++) { //loop through lines of array
var yPos = 40 + k*80;
for (var j = 0; j < 18; j++) { //loop through rows of array
var count = j + 1;
//assign data of three boxes to value1/value2/value3 with which we will later on draw three separate rectangles to visualize the data
if (count == 1 || count == 4 || count == 7 || count == 10 || count == 13 || count == 16) {
var value1 = dataset[k][j];
}
if (count == 2 || count == 5 || count == 8 || count == 11 || count == 14 || count == 17) {
var value2 = dataset[k][j];
}
if (count == 3 || count == 6 || count == 9 || count == 12 || count == 15 || count == 18) {
var value3 = dataset[k][j];
}
if (count % 3 ==0) {
var sum = dataset[k][j] + dataset[k][j-1] + dataset[k][j-2]; //count the three values to also draw one bigger rectangle of their sum
var rectangle = svg.append("rect")
.attr("x", xPos)
.attr("y", yPos)
.attr("width", sum*5)
.attr("height", 20)
.attr("fill", function(d) {
if (count == 3) {
return "LightSeaGreen";
}
else if (count == 6) {
return "MediumSeaGreen";
}
else if (count == 9) {
return "MediumSpringGreen";
}
else if (count == 12) {
return "LimeGreen";
}
else if (count == 15) {
return "ForestGreen"
}
else if (count == 18) {
return "GreenYellow"
}
});
for (var l = 0; l < 3; l++) { //draw three 'sub' rectangles on top of the one 'sum' rectangle. they should appear when the mouse hovers over their 'sum' rectangle
var rectangle2 = svg.append("rect")
.attr("class", "sqr")
.attr("x", function() {
if (l == 0) {
return xPos;
} else if (l == 1) {
return xPos + value1*5;
} else if (l == 2) {
return xPos + (value1+value2)*5;
}
})
.attr("y", yPos)
.attr("width", function() {
if (l == 0) {
return value1*5;
} else if (l == 1) {
return value2*5;
} else if (l == 2) {
return value3*5;
}
})
.attr("height", 20)
.attr("fill", function() {
if (l == 0) {
return "SteelBlue";
} else if (l == 1) {
return "aquamarine";
} else if (l == 2) {
return "SkyBlue";
}
})
.attr("opacity", 0); //in first instance the rectangles are not visible. Opacity should turn to 1 when the mouse hovers over their according div
}
if (sum > 0) {
xPos = xPos + sum*5 + 5;
}
}
}
xPos = 150;
}

actionscript 3 if array in condition

i want to ask about this code..
if (objek.dropTarget.parent.name == "book")
{
if ((objek == alif) || (objek == ba)){ //yg perlu diganti
//if (objek == objBenar){ //yg perlu diganti
objek.x = objek.dropTarget.parent.x;
objek.y = objek.dropTarget.parent.y + 50;
objek.removeEventListener(MouseEvent.MOUSE_DOWN, down);
objek.buttonMode = false;
var _loc_2:Number;
objek.scaleY = 0.4;
objek.scaleX = _loc_2;
objek.alpha = 0.6;
score+=5;
scorebox.text = "Score: " + score;
}
else {
objek.x = objek.dropTarget.parent.x;
objek.y = objek.dropTarget.parent.y + 50;
objek.removeEventListener(MouseEvent.MOUSE_DOWN, down);
objek.buttonMode = false;
var _loc_2:Number;
objek.scaleY = 0.4;
objek.scaleX = _loc_2;
objek.alpha = 0.6;
score-=2;
scorebox.text = "Score: " + score;}
}
}
i have movieclip alif, ba, and dal..this three can be dragged to movieclip named "book" and the score will change.
if i drag alif and ba movieclip to book, score will increase..
if i drag dal movieclip to book score will decrease..
how if i want to make the movieclip alif and ba of an array??and how to write the condition??
help pliss :(
I'm not sure if I understand, but do you want to have an array containing alif and ba and then check if the movieclip is in that array? This is how you would do that:
var scoreIncreasers:Array = [alif, ba];
var isScoreIncreaser:Boolean = (scoreIncreasers.indexOf(objeck) !== -1);
if(isScoreIncreaser) {
// Increase score
}
Edit:
Based on your comment, I think this is what you want:
var objBener:Array = [alif, ba];
if(objBener.indexOf(objek) !== -1) {
//yg perlu diganti
}

AS3 - Remove spaces from an array for word game

I'm building a word search game using the following AS3 code. My problem is I need to have spaces in my array of words, so that I can have things like states names, but I need the spaces removed before the words go into the puzzle.
The other concern is also that when a person selects a word from the puzzle will it still match the word in the list even though the word in the list still has a space.
I've struggled with this for a few days now and could use some help.
I've pasted all appropriate code below, I believe. Thanks.
Rich
// words and grid
private var wordList:Array;
private var usedWords:Array;
private var grid:Array;
// sprites
private var letterSprites:Sprite;
private var wordsSprite:Sprite;
wordList = ("New York,New Jersey,South Carolina,North Carolina").split(",");
// set up the sprites
gameSprite = new Sprite();
addChild(gameSprite);
letterSprites = new Sprite();
gameSprite.addChild(letterSprites);
wordsSprite = new Sprite();
gameSprite.addChild(wordsSprite);
// array of letters
var letters:Array = placeLetters();
// create word list fields and sprites
for(var i:int=0;i<usedWords.length;i++) {
var newWord:TextField = new TextField();
newWord.defaultTextFormat = letterFormatForList;
if(i < 20){ // first list
newWord.x = listXposition;
newWord.y = i*spacingForList+listYposition;
} else { // second list
newWord.x = listXposition + 130;
newWord.y = i*spacingForList+listYposition - (20 * 19);
}
newWord.width = 135;
newWord.height = spacingForList;
newWord.text = usedWords[i];
newWord.selectable = false;
wordsSprite.addChild(newWord);
}
// set game state
dragMode = "none";
numFound = 0;
}
// place the words in a grid of letters
public function placeLetters():Array {
// create empty grid
var letters:Array = new Array();
for(var x:int=0;x<puzzleSize;x++) {
letters[x] = new Array();
for(var y:int=0;y<puzzleSize;y++) {
letters[x][y] = "*";
}
}
// make copy of word list
var wordListCopy:Array = wordList.concat();
usedWords = new Array();
// make 1000 attempts to add words
var repeatTimes:int = 1000;
repeatLoop:while (wordListCopy.length > wordsLeft) {
if (repeatTimes-- <= 0) break;
// pick a random word, location and direction
var wordNum:int = Math.floor(Math.random()*wordListCopy.length);
var word:String = wordListCopy[wordNum].toUpperCase();
x = Math.floor(Math.random()*puzzleSize);
y = Math.floor(Math.random()*puzzleSize);
var dx:int = Math.floor(Math.random()*3)-1;
var dy:int = Math.floor(Math.random()*3)-1;
if ((dx == 0) && (dy == 0)) continue repeatLoop;
// check each spot in grid to see if word fits
letterLoop:for (var j:int=0;j<word.length;j++) {
if ((x+dx*j < 0) || (y+dy*j < 0) || (x+dx*j >= puzzleSize) || (y+dy*j >= puzzleSize)) continue repeatLoop;
var thisLetter:String = letters[x+dx*j][y+dy*j];
if ((thisLetter != "*") && (thisLetter != word.charAt(j))) continue repeatLoop;
}
// insert word into grid
insertLoop:for (j=0;j<word.length;j++) {
letters[x+dx*j][y+dy*j] = word.charAt(j);
}
// remove word from list
wordListCopy.splice(wordNum,1);
usedWords.push(word);
}
// fill rest of grid with random letters
for(x=0;x<puzzleSize;x++) {
for(y=0;y<puzzleSize;y++) {
if (letters[x][y] == "*") {
letters[x][y] = String.fromCharCode(65+Math.floor(Math.random()*26));
}
}
}
return letters;
}
// player clicks down on a letter to start
public function clickLetter(event:MouseEvent) {
var letter:String = event.currentTarget.getChildAt(0).text;
startPoint = findGridPoint(event.currentTarget);
dragMode = "drag";
}
// player dragging over letters
public function overLetter(event:MouseEvent) {
if (dragMode == "drag") {
endPoint = findGridPoint(event.currentTarget);
// if valid range, show outline
outlineSprite.graphics.clear();
if (isValidRange(startPoint,endPoint)) {
drawOutline(outlineSprite,startPoint,endPoint,0xCCCCCC);
}
}
}
// mouse released
public function mouseRelease(event:MouseEvent) {
if (dragMode == "drag") {
dragMode = "none";
outlineSprite.graphics.clear();
// get word and check it
if (isValidRange(startPoint,endPoint)) {
var word = getSelectedWord();
checkWord(word);
}
}
}
// when a letter is clicked, find and return the x and y location
public function findGridPoint(letterSprite:Object):Point {
// loop through all sprites and find this one
for(var x:int=0;x<puzzleSize;x++) {
for(var y:int=0;y<puzzleSize;y++) {
if (grid[x][y] == letterSprite) {
return new Point(x,y);
}
}
}
return null;
}
// determine if range is in the same row, column, or a 45 degree diagonal
public function isValidRange(p1,p2:Point):Boolean {
if (p1.x == p2.x) return true;
if (p1.y == p2.y) return true;
if (Math.abs(p2.x-p1.x) == Math.abs(p2.y-p1.y)) return true;
return false;
}
// draw a thick line from one location to another
public function drawOutline(s:Sprite,p1,p2:Point,c:Number) {
var off:Point = new Point(offset.x+spacing/2, offset.y+spacing/2);
s.graphics.lineStyle(outlineSize,c);
s.graphics.moveTo(p1.x*spacing+off.x ,p1.y*spacing+off.y-3);
s.graphics.lineTo(p2.x*spacing+off.x ,p2.y*spacing+off.y-3);
}
// find selected letters based on start and end points
public function getSelectedWord():String {
// determine dx and dy of selection, and word length
var dx = endPoint.x-startPoint.x;
var dy = endPoint.y-startPoint.y;
var wordLength:Number = Math.max(Math.abs(dx),Math.abs(dy))+1;
// get each character of selection
var word:String = "";
for(var i:int=0;i<wordLength;i++) {
var x = startPoint.x;
if (dx < 0) x -= i;
if (dx > 0) x += i;
var y = startPoint.y;
if (dy < 0) y -= i;
if (dy > 0) y += i;
word += grid[x][y].getChildAt(0).text;
}
return word;
}
// check word against word list
public function checkWord(word:String) {
// loop through words
for(var i:int=0;i<usedWords.length;i++) {
// compare word
if (word == usedWords[i].toUpperCase()) {
foundWord(word);
}
// compare word reversed
var reverseWord:String = word.split("").reverse().join("");
if (reverseWord == usedWords[i].toUpperCase()) {
foundWord(reverseWord);
}
}
}
// word found, remove from list, make outline permanent
public function foundWord(word:String) {
sndSuccess=new success_sound();
sndSuccessChannel=sndSuccess.play(200);
so.data.totalWordsFound = so.data.totalWordsFound + 1;
so.flush();
// draw outline in permanent sprite
drawOutline(oldOutlineSprite,startPoint,endPoint,0xDDDDDD);
// find text field and set it to gray
for(var i:int=0;i<wordsSprite.numChildren;i++) {
if (TextField(wordsSprite.getChildAt(i)).text.toUpperCase() == word) {
TextField(wordsSprite.getChildAt(i)).textColor = 0x777777;
}
}
// see if all have been found
numFound++;
if (numFound == usedWords.length) {
if (so.data.difficulty == "Easy") {
so.data.easyWon = so.data.easyWon + 1;
}
if (so.data.difficulty == "Medium") {
so.data.mediumWon = so.data.mediumWon + 1;
}
if (so.data.difficulty == "Hard") {
so.data.hardWon = so.data.hardWon + 1;
}
so.flush();
endGame();
}
}
I'm hesitant to post an answer as I'm not really sure what's going on, but hopefully this info will help:
Keep your words in the arrays with spaces, that's a good idea. When you want to check against the words in your game, just convert both words to the same format using a function. eg:
var wordList:Array = ("New York,New Jersey,South Carolina,North Carolina").split(",");
var selectedWord:String = "NEWYORK";
// minWord converts all words to the same format of no spaces and all lower case.
function minWord(word:String):String {
return word.replace(/\s/g, "").toLowerCase();
}
// this loop checks all the words from your array against the selectedWord.
for each(var word:String in wordList) {
trace(minWord(word) + " == " + minWord(selectedWord) + "; ", minWord(word) == minWord(selectedWord));
}
Hope that helps!

Resources