Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411490 Posts in 69371 Topics- by 58428 Members - Latest Member: shelton786

April 24, 2024, 10:30:56 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Minesweeper trouble *UPDATED*
Pages: [1]
Print
Author Topic: Minesweeper trouble *UPDATED*  (Read 1143 times)
xhunterko
Level 2
**



View Profile
« on: April 01, 2012, 07:34:34 PM »

So.

A nice person dropped a few pieces of example code on the Flixel forums a bit ago, only stayed for a little bit, and has not been seen on the forums since. One of those is a minesweeper clone, done entirely in Flixel. I decided to play with it to see what I could figure out. So, I want to let the user define the board size themselves by inputting data into a input text field. However, whenever I parse that data to numbers (my trace says so) I get an error in one of the algorithims. Basically, I think it means that the data the player has entered doesn't exist.

Or:
Code:
Fault] exception, information=TypeError: Error #1010: A term is undefined and has no properties.

It occurs on lines 157,153,161,140, and 84 here:
Code:
package  
[size=10pt][size=10pt]{
import org.flixel.*;



public class Minesweeper extends FlxState
{

public var mines:int = 10; // how many mines
public var mines2:int = 10; // how many mines
public var mineTxt:FlxText = new FlxText(132, 2, 45, 'Mines: '+mines.toString()); // show how many mines
public var boardSize:int = 10; // board size
public var boardSize2:int = 10; // board size
public var boardGroup:FlxGroup = new FlxGroup(boardSize * boardSize); // group of zones
public var boardGroup2:FlxGroup = new FlxGroup(boardSize2 * boardSize2); // group of zones
public var boardSpaces:int = (boardSize * boardSize) - mines; // how many zones
public var boardSpaces2:int = (boardSize2 * boardSize2) - mines2; // how many zones

public var initialsInput:FlxInputText;
public var inputNum:uint = 0;

public function Minesweeper():void
{
super.create();

initialsInput  = new FlxInputText(22, 164, 32, 16, "22", 0xffffff, null);
initialsInput.setMaxLength(2);
initialsInput.filterMode = 2;
inputNum = parseInt(initialsInput.text);

trace(inputNum);
add(initialsInput);


FlxG.mouse.show() // show mouse
for (var y:int = 1; y <= boardSize; y++) { // y positions
for (var x:int = 1; x <= boardSize; x++) { // x positions
var zone:Zone = new Zone(((x-1) * 13) + 2, ((y - 1) * 13) + 2); // create zone
zone.place[0] = x+inputNum; // set board x location
zone.place[1] = y+inputNum; // set board y location

boardGroup.add(zone); // add zone to the board

}
}

for (var y2:int = 1; y2 <= boardSize2; y2++) { // y positions
for (var x2:int = 1; x2 <= boardSize2; x2++) { // x positions
var zone2:Zone = new Zone(216, 2); // create zone
zone2.place[0] = x2; // set board x location
zone2.place[1] = y2; // set board y location

boardGroup2.add(zone2); // add zone to the board

}
}


placeMines(); // place mines on the board
updateCount(); // update zone mine counts
add(mineTxt); // add mine text to stage
add(boardGroup); // add board to stage
add(boardGroup2); // add board to stage
}

override public function update():void
{
if (FlxG.keys.justReleased("ENTER"))
{
boardSize = inputNum;
}
inputNum = uint(initialsInput.text);



if (FlxG.mouse.justReleased()) { // mouse clicked
var cursor:FlxPoint = new FlxPoint(FlxG.mouse.x, FlxG.mouse.y); // cursor location
for each(var zone:Zone in boardGroup.members) { // go through the zones
if (zone.graphic.overlapsPoint(cursor)) { // cursor overlaps a zone
if (!zone.liveMine) { // is the zone a mine?
if(zone.hidden){ // is zone still hidden?
if (zone.mineNum == 0) { // does it have a count?
fillFlood(zone); // fill empty zones
boardSpaces--; // subtract zone from board spzces
}else {
zone.updateText(); // zone show text and change color
boardSpaces--; // subtract zone from board spaces
}
}
}else {
//FlxG.switchState(new EndState(false)); // you lose
}
}
}
}

if (FlxG.mouse.justReleased()) { // mouse clicked
// cursor location
for each(var zone2:Zone in boardGroup.members ) { // go through the zones
if (zone2.graphic.overlapsPoint(cursor)) { // cursor overlaps a zone
if (!zone2.liveMine) { // is the zone a mine?
if(zone2.hidden){ // is zone still hidden?
if (zone2.mineNum == 0) { // does it have a count?
fillFlood(zone2); // fill empty zones
boardSpaces--; // subtract zone from board spzces
}else {
zone2.updateText(); // zone show text and change color
boardSpaces--; // subtract zone from board spaces
}
}
}else {
//FlxG.switchState(new EndState(false)); // you lose
}
}
}
}

if (boardSpaces == 0) { // anymore spaces?
//FlxG.switchState(new EndState(true)); // you win
}
super.update();
}

/*
* fill empty zones
*/
private function fillFlood(zone:Zone):void
{
var index:int = boardGroup.members.indexOf(zone);
if(zone.mineNum == 0){ // is zone empty
zone.mineNum = -1; // change zone number prevent reruning this zone
zone.updateText(); // update current zone text
//left
if (zone.place[0] != 1) { // is zone on edge of the playing area?
if(boardGroup.members[index - 1].hidden){ // is next zone hidden?
boardGroup.members[index - 1].updateText(); // show one more zone
boardSpaces--; // subtract zone from board spaces
}
fillFlood(boardGroup.members[index - 1]); // run fill again with next zone
}

/*
* The rest of the if statements are basicly the same as the first one.
*/

//right
if (zone.place[0] != boardSize) {
if(boardGroup.members[index + 1].hidden){
boardGroup.members[index + 1].updateText();
boardSpaces--;
}
fillFlood(boardGroup.members[index + 1]);
}
//up
if (zone.place[1] != 1) {
if(boardGroup.members[index - boardSize].hidden){
boardGroup.members[index - boardSize].updateText();
boardSpaces--;
}
fillFlood(boardGroup.members[index - boardSize]);
}
//down
if (zone.place[1] != boardSize) {
if(boardGroup.members[index + boardSize].hidden){
boardGroup.members[index + boardSize].updateText();
boardSpaces--;
}
fillFlood(boardGroup.members[index + boardSize]);
}
//up left
if (zone.place[1] != 1 && zone.place[0] != 1) {
if(boardGroup.members[index - (boardSize + 1)].hidden){
boardGroup.members[index - (boardSize + 1)].updateText();
boardSpaces--;
}
fillFlood(boardGroup.members[index - (boardSize + 1)]);
}
//up right
if (zone.place[1] != 1  && zone.place[0] != boardSize) {
if(boardGroup.members[index - (boardSize - 1)].hidden){
boardGroup.members[index - (boardSize - 1)].updateText();
boardSpaces--;
}
fillFlood(boardGroup.members[index - (boardSize-1)]);
}
//down left
if (zone.place[1] != boardSize && zone.place[0] != 1) {
if(boardGroup.members[index + (boardSize - 1)].hidden){
boardGroup.members[index + (boardSize - 1)].updateText();
boardSpaces--;
}
fillFlood(boardGroup.members[index + (boardSize - 1)]);
}
//down right
if (zone.place[1] != boardSize  && zone.place[0] != boardSize) {
if(boardGroup.members[index + (boardSize + 1)].hidden){
boardGroup.members[index + (boardSize + 1)].updateText();
boardSpaces--;
}
fillFlood(boardGroup.members[index + (boardSize+1)]);
}
}
}

/*
* place mine on the board
*/
private function placeMines():void
{
while (mines > 0) { // mines left
var randomMine:Number = Math.floor(Math.random() * ((boardSize * boardSize) - 1)); // pick random zone
boardGroup.members[randomMine].liveMine = true; // set mine
mines--; // subtract from mines
}
}

/*
* go through the board and update mine count
*/
private function updateCount():void
{
for each (var zone:Zone in boardGroup.members) { // go through the board
var index:int = boardGroup.members.indexOf(zone); // index of current zone
if (zone.liveMine) { // is it a live mine?
//left
if (boardGroup.members[index - 1] && !boardGroup.members[index - 1].liveMine && zone.place[0] != 1) { // is next zone set, is it a mine, is current zone on the edge?
boardGroup.members[index - 1].mineNum ++; // add to zone's mine number
}

/*
* The next if statement are about the same as the first one
*/

//right
if(boardGroup.members[index + 1] && !boardGroup.members[index + 1].liveMine && zone.place[0] != boardSize){
boardGroup.members[index + 1].mineNum++;
}
//up
if (boardGroup.members[index - boardSize] && !boardGroup.members[index - boardSize].liveMine && zone.place[1] != 1) {
boardGroup.members[index - boardSize].mineNum++;
}
//down
if (boardGroup.members[index + boardSize] && !boardGroup.members[index + boardSize].liveMine && zone.place[1] != boardSize) {
boardGroup.members[index + boardSize].mineNum++;
}
//up left
if (boardGroup.members[index - (boardSize+1)] && !boardGroup.members[index - (boardSize+1)].liveMine && zone.place[1] != 1 && zone.place[0] != 1) {
boardGroup.members[index - (boardSize+1)].mineNum++;
}
//up right
if (boardGroup.members[index - (boardSize-1)] && !boardGroup.members[index - (boardSize-1)].liveMine && zone.place[1] != 1 && zone.place[0] != boardSize) {
boardGroup.members[index - (boardSize-1)].mineNum++;
}
//down left
if (boardGroup.members[index + (boardSize-1)] && !boardGroup.members[index + (boardSize-1)].liveMine && zone.place[1] != boardSize && zone.place[0] != 1) {
boardGroup.members[index + (boardSize-1)].mineNum++;
}
//down right
if (boardGroup.members[index + (boardSize+1)] && !boardGroup.members[index + (boardSize+1)].liveMine && zone.place[1] != boardSize && zone.place[0] != boardSize) {
boardGroup.members[index + (boardSize+1)].mineNum++;
}
}
}
}
}
}[/size][/size]

I'm trying to parse the input from the user two different ways. And both ways seem to give that error. Here's the flxInput class I'm using as well:

Code:
package
{
import org.flixel.*;
import flash.events.Event;
import flash.text.TextFieldType;

//@desc Input field class that "fits in" with Flixel's workflow
public class FlxInputText extends FlxText {

static public const NO_FILTER:uint = 0;
static public const ONLY_ALPHA:uint = 1;
static public const ONLY_NUMERIC:uint = 2;
static public const ONLY_ALPHANUMERIC:uint = 3;
static public const CUSTOM_FILTER:uint = 4;

//@desc Defines what text to filter. It can be NO_FILTER, ONLY_ALPHA, ONLY_NUMERIC, ONLY_ALPHA_NUMERIC or CUSTOM_FILTER
// (Remember to append "FlxInputText." as a prefix to those constants)
public var filterMode:uint = NO_FILTER;

//@desc This regular expression will filter out (remove) everything that matches. This is activated by setting filterMode = FlxInputText.CUSTOM_FILTER.
public var customFilterPattern:RegExp = /[]*/g;

//@desc If this is set to true, text typed is forced to be uppercase
public var forceUpperCase:Boolean = false;

//@desc Same parameters as FlxText
public function FlxInputText(X:Number, Y:Number, Width:uint, Height:uint, Text:String, Color:uint=0x000000, Font:String=null, Size:uint=8, Justification:String=null, Angle:Number=0)
{
//super(X, Y, Width, Height, Text, Color, Font, Size, Justification, Angle);
super(X, Y, Width, Text);
_textField.x = X;
_textField.y = Y;
_textField.selectable = true;
_textField.type = TextFieldType.INPUT;
_textField.background = true;
_textField.backgroundColor = (~Color) & 0xffffff;
_textField.textColor = Color;
_textField.border = true;
_textField.borderColor = Color;
_textField.visible = false;
_textField.height = Height;
this.height = Height;
this.angle = Angle;

_textField.addEventListener(Event.ENTER_FRAME, onEnterFrame);
_textField.addEventListener(Event.REMOVED_FROM_STAGE, onInputFieldRemoved);
_textField.addEventListener(Event.CHANGE, onTextChange);
//FlxG.state.addChild(_textField);
FlxG.stage.addChild(_textField);
}

//@desc Boolean flag in case render() is called BEFORE onEnterFrame() (_textField would be always hidden)
// NOTE: I don't think it's necessary, but I'll leave it just in case.
//@param Direction True is Right, False is Left (see static const members RIGHT and LEFT)
private var nextFrameHide:Boolean = false;

override public function draw():void
{
//_textField.x=x+FlxG.scroll.x;
//_textField.y=y+FlxG.scroll.y;
_textField.visible = true;
nextFrameHide = false;
}

private function onInputFieldRemoved(event:Event):void
{
//Clean up after ourselves
_textField.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
_textField.removeEventListener(Event.REMOVED, onInputFieldRemoved);
_textField.removeEventListener(Event.CHANGE, onTextChange);
}

private function onEnterFrame(event:Event):void
{
if(nextFrameHide)
_textField.visible=false;
nextFrameHide = true;
}

private function onTextChange(event:Event):void
{
if(forceUpperCase)
_textField.text = _textField.text.toUpperCase();

if(filterMode != NO_FILTER) {
var pattern:RegExp;
switch(filterMode) {
case ONLY_ALPHA: pattern = /[^a-zA-Z]*/g; break;
case ONLY_NUMERIC: pattern = /[^0-9]*/g; break;
case ONLY_ALPHANUMERIC: pattern = /[^a-zA-Z0-9]*/g; break;
case CUSTOM_FILTER: pattern = customFilterPattern; break;
default:
throw new Error("FlxInputText: Unknown filterMode ("+filterMode+")");
}
_textField.text = _textField.text.replace(pattern, "");
}
}

//@desc Text field background color
public function set backgroundColor(Color:uint):void { _textField.backgroundColor = Color; }
//@desc Text field border color
public function set borderColor(Color:uint):void { _textField.borderColor = Color; }
//@desc Shows/hides background
public function set backgroundVisible(Enabled:Boolean):void { _textField.background = Enabled; }
//@desc Shows/hides border
public function set borderVisible(Enabled:Boolean):void { _textField.border = Enabled; }

//@desc Text field background color
public function get backgroundColor():uint { return _textField.backgroundColor; }
//@desc Text field border color
public function get borderColor():uint { return _textField.borderColor; }
//@desc Shows/hides background
public function get backgroundVisible():Boolean { return _textField.background; }
//@desc Shows/hides border
public function get borderVisible():Boolean { return _textField.border; }

//@desc Set the maximum length for the field (e.g. "3" for Arcade type hi-score initials)
//@param Length The maximum length. 0 means unlimited.
public function setMaxLength(Length:uint):void
{
_textField.maxChars = Length;
}

//@desc Get the text the user has typed
public function getText():String
{
return _textField.text;
}

}
}

So, if you wouldn't mind, I have a few questions:

So, how do I get the number data from the input object correctly?
Why does he use this equation:
Code:
var zone:Zone = new Zone(((x-1) * 13) + 2, ((y - 1) * 13) + 2);	// create zone
zone.place[0] = x+inputNum; // set board x location
zone.place[1] = y+inputNum;
?

And how would I change the board size to begin with? (new test to the boardsize value itself brings up the same errors, so it's apparently unable to handle boards of sizes other then 10?)
(was still using the input number too)

Thanks in advance!
« Last Edit: April 04, 2012, 04:19:14 PM by xhunterko » Logged

xhunterko
Level 2
**



View Profile
« Reply #1 on: April 04, 2012, 05:36:31 PM »

So, I finally got a parsed string to a number that everybody's happy with. So, now the problem can be seen down below:

Inputting the number:
http://www.majhost.com/gallery/rob/Friends/deminedscn1.png

The next frame:
http://www.majhost.com/gallery/rob/Friends/deminedscn2.png

Oh, wait, how did, that, box, transfer, from one frame to the next??? Also, notice the second minefield. While it's taking the number, it's not doing what it's supposed to be doing. It's supposed to be creating a grid of the input number  by the input number. Or for example, a 10x10 grid, as in the first one. The code for creating the grids is the exact same. Take a look:

Code:
for (var y:int = 1; y <= boardSize; y++) {									// y positions
for (var x:int = 1; x <= boardSize; x++) { // x positions
var zone:Zone = new Zone(((x-1) * 13) + 2, ((y - 1) * 13) + 2); // create zone
zone.place[0] = x; // set board x location
zone.place[1] = y; // set board y location

boardGroup.add(zone); // add zone to the board

}
}

for (var y2:int = 1; y2 <= Registry.inputNum; y2++) { // y positions
for (var x2:int = 1; x2 <= Registry.inputNum; x2++) { // x positions
var zone2:Zone = new Zone(((x2-1) * 13) + 216, ((x2-1) * 13) + 2); // create zone
zone2.place[0] = x2; // set board x location
zone2.place[1] = y2; // set board y location

boardGroup2.add(zone2); // add zone to the board

}
}

I've tweaked most of the code in the statements handling various aspects to handle two boards. But I'm still not getting a complete grid. So, I'm wondering if somebody can help me with a couple things:

What can I do to get the second grid to complete?
How do I remove that object after switching to another frame? (trying kill and destroy, but it's still there, shrugs)

Thanks in advance!
Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic