8

enter image description here

As My Screen shot show that i am working on word matching game.In this game i assign my words to different UIButtons in Specific sequence on different loctions(my red arrow shows this sequence)and of rest UIButtons i assign a one of random character(A-Z).when i Click on any UIButtons its title will be assign to UILabel which is in Fornt of Current Section:i campare this UILabel text to below UILabels text which is in fornt of timer.when it match to any of my UILabels its will be deleted.i implement all this process already.

But my problem is that which is show by black lines.if the player find the first word which is "DOG". he click the Two UIButtons in Sequence,but not press the Third one in Sequence.(as show by black line).so here i want that when player press the any UIButtons which is not in Sequence then remove the previous text(which is "DO") of UILabel and now the Text of UILabel is only "G" . Here is my code to get the UIButtons titles and assign it UILabel.

- (void)aMethod:(id)sender 
       {
    UIButton *button = (UIButton *)sender;
    NSString    *get = (NSString *)[[button titleLabel] text];
    NSString *origText = mainlabel.text;
    mainlabel.text = [origText stringByAppendingString:get];

 if ([mainlabel.text length ]== 3) 
    {
if([mainlabel.text isEqualToString: a]){
    lbl.text=@"Right";
    [btn1 removeFromSuperview];
    score=score+10;
    lblscore.text=[NSString stringWithFormat:@"%d",score];
    words=words-1;
    lblwords.text=[NSString stringWithFormat:@"%d",words];
    mainlabel.text=@"";
    a=@"tbbb";
}

    else    if([mainlabel.text isEqualToString: c]){
    lbl.text=@"Right";
    [btn2 removeFromSuperview];
    score=score+10;
    lblscore.text=[NSString stringWithFormat:@"%d",score];
    words=words-1;
    lblwords.text=[NSString stringWithFormat:@"%d",words];
    mainlabel.text=@"";
c=@"yyyy";

}
 else   
     if([mainlabel.text isEqualToString: d]){
    lbl.text=@"Right";
    [btn3 removeFromSuperview];
    score=score+10;
    lblscore.text=[NSString stringWithFormat:@"%d",score];
    words=words-1;
    lblwords.text=[NSString stringWithFormat:@"%d",words];
    mainlabel.text=@"";
    d=@"yyyy";
}
else {
    lbl.text=@"Wrong";
   mainlabel.text=@"";
  }

 }}

Thanx in advance

trumpetlicks
  • 7,033
  • 2
  • 19
  • 33
jamil
  • 2,419
  • 3
  • 37
  • 64
  • 2
    Could you perhaps subclass UIButton or create a UIButton category that adds a property that you could set at runtime, which specifies that the button is part of a word or not? This might help you: http://stackoverflow.com/questions/5500327/subclass-uibutton-to-add-a-property – Luke May 29 '12 at 09:10
  • 1
    Assign tag to each button. And get the tag when you press. save the tag in a variable e.g name , prevTapBtn=10 then the other variable nextTapBtn=11 should be 11, one greater than the previous tap. If so then countinue else remove. Hope this will help you. – Khalid Usman May 29 '12 at 11:47

4 Answers4

1

If I understand correctly, you need to know if the pushed button is adjacent to the previously pushed button? Use this function to test for adjacency in the grid:

bool isAdjacent(UIButton* current, UIButton* previous) {
    if( !previous )
        return false;

    //Create a rectangle around the previous button (assuming all buttons are in a fixed grid)
    CGRect previousRect = previous.frame;
    CGRect adjacentRect = CGRectMake(previous.frame.origin.x - previous.frame.size.width,
                                     previous.frame.origin.y - previous.frame.size.height,
                                     previous.frame.size.width*3,
                                     previous.frame.size.height*3);
    return CGRectIntersectsRect(adjacentRect, previousRect);
}

And only append if they are adjacent, ie:

- (void)aMethod:(id)sender 
{
    UIButton *button = (UIButton *)sender;
    static UIButton* previous = nil;
    NSString    *get = (NSString *)[[button titleLabel] text];
    NSString *origText = mainlabel.text;

   if( isAdjacent(button, previous) )
       mainlabel.text = [origText stringByAppendingString:get];

   previous = button;

   //Rest of function
}
Paul de Lange
  • 10,613
  • 10
  • 41
  • 56
  • thanks for reply. i have seen your code. what i have got from your code, you are making previousRect by passing previous.frame and another adjacentRect by using previous and checking Intersect for these two. but my question is where to check adjacency with current and previous? – jamil May 31 '12 at 13:16
  • it is checking in the -(void)aMethod function. If they are adjacent, append the letter otherwise don't...? – Paul de Lange Jun 01 '12 at 07:23
  • thanks for reply, but i am asking about current adjacency with previous button in isAdjacent code blcok. – jamil Jun 01 '12 at 07:32
  • 1
    The adjacent rect is three "grid" squares wide by three "grid" squares high centered around your previous button. If your current button is inside this grid of nine squares (ie: is adjacent) the method returns true. – Paul de Lange Jun 01 '12 at 16:10
  • @ paul thanx for helping me so for. i implement your method completly but its get the text of every where i click on UIButtons.its not replace the text of UILabel in case of player not follow the Sequence of UIButton that i mention in my question. – jamil Jun 02 '12 at 08:53
1

Fun question: In this particular case, I agree with Luke about subclassing the UIButton. This way you could give each button an (X, Y) on your grid, as well as a (Xnext, Ynext) list for all of the possible expected next press locations (if the button itself can be used to make multiple words). Externally you will compare the currently being hit against the expected (Xnext, Ynext). If the two dont match, this is the signal you are looking for.

This is an answer that accounts for all of your situations, forward and backward horizontal (if you choose to implement backware), upward and downward vertical (if you choose to implement upward), and any diagonal, or any other combination you can come up with!

This also accounts for lets say hitting the D, then the O then trying to press the D again versus hitting the G. It also takes care of hitting the incorrect G.

Create a new .m .h pair of files (a new object) and give it your name.

Some example code for implementing a custom UIButton (h file):

@interface myConnectedUIButton : UIButton {

    BOOL             isAWordBeginCharacter;
    unsigned int     beginWordKey;

    unsigned int     myGridX;
    unsigned int     myGridY;

    NSMutableArray * myConnectedSet;

}

-(id)init;
-(void)initWithGridX:(unsigned int)X GridY:(unsigned int)Y BeginChar:(BOOL)yesNo BeginWordKey:(unsigned int)key;
-(void)setGridPosWithX:(unsigned int)X Y:(unsigned int)Y;
-(void)setGridX:(unsigned int)X;
-(void)setGridY:(unsigned int)Y;
-(unsigned int)getGridX;
-(unsigned int)getGridY;

-(void)setIsABeginChar:(BOOL)yesNo;
-(BOOL)getIsABeginChar;

-(void)addPosToConnectedSetGridX:(unsigned int)X GridY:(unsigned int)Y WordKey:(unsigned int)key; 
-(NSArray *)getMyConnectedSetArray;
-(void)clearConnectedSet;

@end

In the .m file of your

@implementation myConnectedUIButton

-(id)init{
    [super init];

    // Lets go ahead and initialize the NSMutableArray here also IFF it hasnt already been allocated
    if( nil == myConnectedSet ){
        myConnectedSet = [[NSMutableArray alloc] init];
    }

    // Lets also zero out the x, y position
    myGridX = 0;
    myGridY = 0;

    // Lets also state that this is NOT a begin char for the time being and 0 for the begin char key
    isAWordBeginCharacter = NO;
    beginWordKey = 0;

    return self;
}

-(void)initWithGridX:(unsigned int)X GridY:(unsigned int)Y BeginChar:(BOOL)yesNo BeginWordKey:(unsigned int)key{
    // Lets go ahead and initialize the NSMutableArray here also IFF it hasnt already been allocated
    if( nil == myConnectedSet ){
        myConnectedSet = [[NSMutableArray alloc] init];
    }

    myGridX = X;
    myGridY = Y;

    isAWordBeginCharacter = yesNo;
    beginWordKey = key;
}

-(void)setGridPosWithX:(unsigned int)X Y:(unsigned int)Y{
    myGridX = X;
    myGridY = Y;
}

-(void)setGridX:(unsigned int)X{
    myGridX = X;
}

-(void)setGridY:(unsigned int)Y{
    myGridY = Y;
}

-(unsigned int)getGridX{
    return myGridX;
}

-(unsigned int)getGridY{
    return myGridY;    
}

-(void)setIsABeginChar:(BOOL)yesNo{
    isAWordBeginCharacter = yesNo;
}

-(BOOL)getIsABeginChar{
    return isAWordBeginCharacter;
}

-(void)addPosToConnectedSetGridX:(unsigned int)X GridY:(unsigned int)Y WordKey:(unsigned int)key{
    [myConnectedSet addObject:[GridPointNext GridPointNextWithX:X GridPointY:Y  NextWordKey:key]];
}

-(NSArray *)getMyConnectedSetArray{
    return myConnectedSet;
}

-(void)clearConnectedSet{
    [myConnectedSet removeAllObjects];
}

-(void)dealloc{
    [myConnectedSet release];

    [super dealloc];
}

@end

You will also now need a "GridPointNext" object.

The Grid Object header should look as follows:

@interface GridPointNext : NSObject {
    unsigned int GridPointX;
    unsigned int GridPointY;

    unsigned int nextWordKey;
}

+(GridPointNext *)GridPointNextWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key;
-(id)initWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key;

-(unsigned int)getGridX;
-(unsigned int)getGridY;
-(unsigned int)getNextWordKey;

@end

The m file for the object should look as follows:

@implementation GridPointNext

+(GridPointNext *)GridPointNextWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key{
    GridPointNext * aPoint = [[GridPointNext alloc] initWithX:X GridPointY:Y NextWordKey:key];

    [aPoint autorelease];

    return aPoint;
}

-(id)initWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key{
    GridPointX  = X;
    GridPointY  = Y;

    nextWordKey = key;

    return self;
}


-(unsigned int)getGridX{
    return GridPointX;
}

-(unsigned int)getGridY{
    return GridPointY;
}

-(unsigned int)getNextWordKey{
    return nextWordKey;
}

@end

You will have to deal with the dealloc portion. This at least give you some tools for creating your custom button and your word list algorithm around it.

trumpetlicks
  • 7,033
  • 2
  • 19
  • 33
  • Unfortunately, I can't edit your code above as you don't have the UIButton object code. Give me a couple of minutes and I will provide a couple of line of example code on how to subclass the UIButton class. – trumpetlicks Jun 02 '12 at 16:01
  • Sorry, realized i used NSButton instead of UIButton. – trumpetlicks Jun 02 '12 at 21:27
  • Can you give me the email address.i send you the application Code bcz i sure your methods is working for me,but for me its very difficult to implement in right way in my application. thanx – jamil Jun 03 '12 at 07:05
  • If you look at my profile, there will be a link to my website. From there you will be able to go to the "contact us" -> "Get Support" link. That is a link to my email address :-) – trumpetlicks Jun 03 '12 at 14:32
  • @ trumpetlicks once again thanx i already send you the complete code on your email address.please check it.waiting for your response. – jamil Jun 03 '12 at 14:55
1

Assign tag to each button from left to right. So you will have,

GButton.tag = 0; TButton.tag = 1; DButton.tag = 2; . . . VButton.tag = 9; . . . EButton.tag = 18; . . . CButton.tag = 26;

Now keep the track of previous pressed button and current pressed button. Call below function when your button delegate hits:

Write below code into your .h file

#define SEQ_TYPE_ANY  0
#define SEQ_TYPE_RIGHT 1
#define SEQ_TYPE_LEFT 2
#define SEQ_TYPE_TOP 3
#define SEQ_TYPE_BOTTOM 4
#define SEQ_TYPE_RIGHT_DIAGONAL_DOWN 5
#define SEQ_TYPE_RIGHT_DIAGONAL_UP 6
#define SEQ_TYPE_LEFT_DIAGONAL_DOWN 7
#define SEQ_TYPE_LEFT_DIAGONAL_UP 8

#define NO_OF_BUTTONS_IN_ROW 9

//Add below variables into your class
int curentSequence;
UILabel *resultLabel;
UIButton *previousButton;

//Declare property for previousButton
@property(nonatomic, retain) UIButton *previousButton;


//Write below code to .m file
@synthesize previousButton;

-(BOOL) isAdjacent:(UIButton *)currentButton
{
     if(previousButton == nil)
     {
          resultLabel.text = currentButton.titleLabel.text;
          curentSequence = SEQ_TYPE_ANY;
          return TRUE;
     }


     if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_RIGHT) &&
          (previousButton.tag + 1 == currentButton.tag))
     {
          resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
          curentSequence = SEQ_TYPE_ANY;
          return TRUE;
     }

     else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_LEFT) &&
        (previousButton.tag - 1 == currentButton.tag))
     {
          resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
          curentSequence = SEQ_TYPE_LEFT;
          return TRUE;
     }

     else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_TOP) &&
             (previousButton.tag - NO_OF_BUTTONS_IN_ROW == currentButton.tag))
     {
          resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
          curentSequence = SEQ_TYPE_TOP;
          return TRUE;
     }

     else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_BOTTOM) &&
             (previousButton.tag + NO_OF_BUTTONS_IN_ROW == currentButton.tag))
     {
          resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
          curentSequence = SEQ_TYPE_BOTTOM;
          return TRUE;
     }

     else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_RIGHT_DIAGONAL_DOWN) &&
             (previousButton.tag + NO_OF_BUTTONS_IN_ROW + 1 == currentButton.tag))
     {
          resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
          curentSequence = SEQ_TYPE_RIGHT_DIAGONAL_DOWN;
          return TRUE;
     }

     else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_RIGHT_DIAGONAL_UP) &&
             (previousButton.tag -  NO_OF_BUTTONS_IN_ROW + 1 == currentButton.tag))
     {
          resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
          curentSequence = SEQ_TYPE_RIGHT_DIAGONAL_UP;
          return TRUE;
     }

     else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_LEFT_DIAGONAL_UP) &&
             (previousButton.tag - NO_OF_BUTTONS_IN_ROW - 1 == currentButton.tag))
     {
          resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
          curentSequence = SEQ_TYPE_LEFT_DIAGONAL_UP;
          return TRUE;
     }
     else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_LEFT_DIAGONAL_DOWN) &&
             (previousButton.tag + NO_OF_BUTTONS_IN_ROW - 1 == currentButton.tag))
     {
          resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
          curentSequence = SEQ_TYPE_LEFT_DIAGONAL_DOWN;
          return TRUE;
     }
     else
     {
          resultLabel.text = @"";
          curentSequence = SEQ_TYPE_ANY;
          return FALSE;
     }     
}

// Event handler for button event
- (void)aMethod:(id)sender
{
     UIButton *currentButton = (UIButton *)sender;
     BOOL result = [self isAdjacent:currentButton];
     if(result == FALSE)
     {
          self.previousButton = nil;
          resultLabel.text = @"";
          curentSequence = SEQ_TYPE_ANY;
     }
     else
     {
          self.previousButton = sender;
     }
}

Hope it will help.

Apurv
  • 17,116
  • 8
  • 51
  • 67
  • i try to implement your code ,but on button click how we can check your condition that you mention in u r code.bcz on button i call the function - (void)aMethod:(id)sender,can u give me help to implement your code in right way.thanx – jamil Jun 06 '12 at 14:01
  • i assing the tag to each uibutton ,but on button click how we can call u r funtion i try this.. [btn addTarget:self action:@selector(isAdjacent:)forControlEvents:UIControlEventTouchUpInside]; but when i call this on each button click its kill my application. – jamil Jun 06 '12 at 14:50
  • Thanx @Apurv its work as i want..bundle of thanx dear ..i feel very happy..to see it work for me..thanx – jamil Jun 06 '12 at 15:10
0

If I understand correctly. The user can only have a correct word, if the letters chosen are all sitting next to each other?

Have you tried this: Keep two references. One UIButton for previousPressedButton and one UIButtonfor lastPressedButton.

First a user presses D. lastPressedButton will refer to the D. Then a user presses O. previousPressedButton will be D. lastPressedButton will be O.

Now, get the width and height of the UIButtons and compare if the lastPressedButton.frame.origin.x will be less than width or -width away. Also check if the lastPressedButton.frame.origin.y will be less than height or -height away. Now you know if it's touching the previous button. Use this to decide if it's a new word or not.

I would put this into a method.

    -(BOOL)isAdjacentLetter {
          float buttonWidth = lastPressedButton.size.width;
          float buttonHeight = lastPressedButton.size.height;
          if(lastPressedButton.frame.origin.x>previousPressedButton.frame.origin.x+buttonWidth) return NO;
          if(lastPressedButton.frame.origin.y>previousPressedButton.frame.origin.y+buttonHeight) return NO;
          if(lastPressedButton.frame.origin.x<previousPressedButton.frame.origin.x-buttonWidth) return NO;
          if(lastPressedButton.frame.origin.y<previousPressedButton.frame.origin.y-buttonHeight) return NO;

          return YES;
}

Then whenever a button is clicked. you can use

if ([self isAdjacentLetter]) {
   //still same word
} else {
   //new word. erase
}

Or, if I understand differently. The words can only be made when the letters are in a row.Such as : From left to right. From down to up. From bottom right to top left etc. In this case, determine all directions. Such as, top left is 0, top is 1, top right is 2. right is 3. down right is 4. down is 5. down left is 6. left is 7.

When two buttons are clicked, store the directions. For example: If it's from left to right, direction = 3; Then when another button is clicked, check the new direction. If it's 3, the word is still in the same direction. if it's something else, then erase and start over.

Hope this helps.

  • @ Tjeerd i implement your code but its not work for me can you edit your answer using my code. – jamil Jun 02 '12 at 08:56