确定基于网格的游戏中可能的移动/路径

时间:2015-01-21 04:45:55

标签: ios xcode

背景: 我正在制作一个将3个圆圈放到网格上的游戏,并允许用户通过点击圆圈而不是点击网格上的另一个空格一次移动一个圆圈。每次移动都会在网格上放下更多圆圈。

游戏的工作方式是,如果没有明确的路径到达所选地点(例如你被其他圈子封锁或者你没有被封锁但是当时董事会没有开放空间的路径到那个地方)游戏会提醒你,你试图做出无效动作,并拒绝移动。

我的问题: 我无法找到一种方法来获取代码来检查播放(点击)的移动是有效还是无效。

我已经为每个按钮指定了一个标记,其中的数字与网格上的点相对应(请参阅代码.m)  例: Game Board a few turns into the game 在游戏的这一点上,从空间#70移动 - >从#70 - >迁移到#39将无效#71会好的。

注意:对角线移动也是无效的。

我怎样才能获得确定此代码的代码?

代码:(。米)

#import "ViewController.h"

@interface ViewController ()

@end
int name;
bool oneSelect;
UIImage *imageName;
UIButton *selectedButton;
NSArray *items;
NSMutableArray *occupied;
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
items = [NSArray arrayWithObjects:@"marble_red",@"marble_blue",@"marble_yellow",@"marble_green",@"marble_purple",@"marble_black",@"marble_orange",nil];

    for (int y=0; y < 9; y++) {
        for (int x = 0; x < 9; x++) {
            UIButton * button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
            button.frame = CGRectMake(22 + 30 * x, 100 + 30 * y, 30, 30);
            unsigned buttonNumber = name;
            button.tag = buttonNumber;
            [button setTitle:[NSString stringWithFormat:@"%u", buttonNumber] forState:UIControlStateNormal];
            [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
            [self.view addSubview: button];
            name= name +1;
        }

    }

    for (int i = 0; i <= 2; i++) {
        int space = arc4random()%81;
        int pic = arc4random()%7;
        NSString *string = [items objectAtIndex:pic];
        UIButton *button = (UIButton *)[self.view viewWithTag:space];
        [button setBackgroundImage:[UIImage imageNamed:string] forState:UIControlStateNormal];
        NSLog(@"String(%@) / Button(%@)",string,button.description);

    }

}


-(void)buttonPressed:(UIButton *)button
{
    if (!oneSelect) {
        if ([button backgroundImageForState:UIControlStateNormal] != NULL) {
        button.selected = YES;
        imageName = [button backgroundImageForState:UIControlStateNormal];
        selectedButton = button;
        oneSelect = YES;
        }else{
            button.selected = NO;
        }
    }else{
        if ([button backgroundImageForState:UIControlStateNormal] ==  NULL) {
        oneSelect = NO;
        [button setBackgroundImage:imageName forState:UIControlStateNormal];
        button.selected = NO;

        [selectedButton setBackgroundImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];
        selectedButton.selected = NO;
            [self nextMove];
        }else{
            selectedButton.selected = NO;
            button.selected = NO;
        }
    }
    NSLog(@"button %ld -- frame: %@", (long)button.tag, NSStringFromCGRect(button.frame));
}

-(void)nextMove{

    for (int i = 0; i <= 2; i++) {
        int space = arc4random()%81;
        int pic = arc4random()%7;
        NSString *string = [items objectAtIndex:pic];
        UIButton *button = (UIButton *)[self.view viewWithTag:space];
        if ([button backgroundImageForState:UIControlStateNormal] == NULL) {
            [button setBackgroundImage:[UIImage imageNamed:string] forState:UIControlStateNormal];
        }else{
            i = i - 1;
        }
        NSLog(@"String(%@) / Button(%@)",string,button.description);
    }
}

此外,如果我的代码中有任何内容可以修改,以便更好地进行游戏,请告诉我。

2 个答案:

答案 0 :(得分:1)

我的方法是实施Iterative Deepening Depth First Search

首先,我创建了一个类来表示每个单元格&#39;在董事会(因为我不喜欢使用viewWithTag

<强> BoardCell.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface BoardCell : NSObject


@property (weak,nonatomic,readonly) UIButton *button;
@property BOOL occupied;


-(id) initWithButton:(UIButton *)button;

@end

<强> BoardCell.m

#import "BoardCell.h"

@implementation BoardCell

-(id) initWithButton:(UIButton *)button {
    if (self=[super init]) {
        _button=button;
    }

    return self;
}

@end

然后我实现了我的游戏版本(我改变了图像以使用我已经拥有的图像,所以我也改变了单元格布局的尺寸)。我不太确定&#39;规则&#39;你的游戏,所以我做了一些。它没有检查&#34;游戏结束&#34;但那是微不足道的。

<强> ViewController.m

#import "ViewController.h"
#import "BoardCell.h"

@interface ViewController ()

@property (strong,nonatomic) NSArray *imageNames;
@property (strong,nonatomic) NSMutableArray *board;
@property NSInteger lastMove;

#define BOARDWIDTH 9
#define BOARDHEIGHT 9

@end

static int moves[]={-BOARDWIDTH,-1,1,BOARDWIDTH};

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.imageNames = @[@"redhex",@"bluehex",@"purplehex",@"orangehex",@"greenhex"];

    self.board = [NSMutableArray new];

    for (int y=0; y < BOARDWIDTH; y++) {
        for (int x = 0; x < BOARDHEIGHT; x++) {
            UIButton * button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
            button.frame = CGRectMake(40 * x, 100 + 40 * y, 60, 60);
            button.tag = y*BOARDWIDTH+x;
            [button setTitle:[NSString stringWithFormat:@"%ld", button.tag] forState:UIControlStateNormal];

            [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
            [self.view addSubview: button];
            [self.board addObject:[[BoardCell alloc] initWithButton:button]];
        }
    }

    self.lastMove=arc4random_uniform(BOARDWIDTH*BOARDHEIGHT);
    UIButton *button=(UIButton *)[self.view viewWithTag:self.lastMove];
    [button setBackgroundImage:[UIImage imageNamed:@"greensquare"] forState:UIControlStateNormal];

    [self addRandoms:3];


}

-(void) addRandoms:(NSInteger)randomCount {
    for (int i = 0; i < randomCount; i++) {
        int space = arc4random_uniform(BOARDWIDTH*BOARDHEIGHT);
        BoardCell *cell=self.board[space];
        if (!cell.occupied) {
            int pic = arc4random_uniform((u_int32_t)self.imageNames.count);
            NSString *string = [self.imageNames objectAtIndex:pic];
            [cell.button setBackgroundImage:[UIImage imageNamed:string] forState:UIControlStateNormal];
            cell.occupied=YES;
        }
        else {
            i--;
        }

    }
}



-(void)buttonPressed:(UIButton *)button
{
    NSInteger buttonId=button.tag;
    BoardCell *cell=self.board[buttonId];

    if (!cell.occupied) {

        BoardCell *startCell=self.board[self.lastMove];
        startCell.occupied=NO;

        if ([self validMoveFromSquare:self.lastMove toDestination:buttonId]) {
            [startCell.button setBackgroundImage:[UIImage imageNamed:@"orangesquare"] forState:UIControlStateNormal];
            [cell.button setBackgroundImage:[UIImage imageNamed:@"greensquare"] forState:UIControlStateNormal];

            self.lastMove=buttonId;
            cell.occupied=YES;
        }
        startCell.occupied=YES;

    }

    [self addRandoms:3];
}


-(BOOL) validMoveFromSquare:(NSInteger)startSquare toDestination:(NSInteger)destination {

    for (int limit=1;limit<50;limit++ ) {
        NSMutableIndexSet *visitList=[NSMutableIndexSet new];
        if ([self DFSFromStart:startSquare toGoal:destination withLimit:limit andVisitList:visitList]) {
            return YES;
        }
    }

    return NO;

}

-(BOOL) DFSFromStart:(NSInteger)start toGoal:(NSInteger)goal withLimit:(NSInteger)limit andVisitList:(NSMutableIndexSet *)visitList {

    if (start==goal) {
        return YES;
    }

    if (limit >=0) {

        if (((BoardCell *)self.board[start]).occupied) {
            return NO;
        }

        [visitList addIndex:start];

        for (int i=0;i<4;i++) {
            NSInteger nextPosition=start+moves[i];

            if ([self validDestination:nextPosition withMove:moves[i] fromSquare:start]) {
                if (![visitList containsIndex:nextPosition]) {
                    if ([self DFSFromStart:nextPosition toGoal:goal withLimit:limit-1 andVisitList:visitList]) {
                        return YES;
                    }
                }

            }
        }
    }
    return NO;

}
-(BOOL) validDestination:(NSInteger)destination withMove:(int)move fromSquare:(NSInteger)start {

    if (destination <0 || destination >= BOARDWIDTH*BOARDHEIGHT) {
        return NO;
    }

    if (abs(move)==1) {
        int sourceRow= (int)start / BOARDWIDTH;
        int destinationRow=(int)destination / BOARDWIDTH;
        if (sourceRow != destinationRow) {
            return NO;
        }
    }

    return YES;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

编辑我最初误读了你的问题,所以我的代码允许对角移动。我修好了这个

编辑2 我已将DFS限制增加到50并添加了一种新方法来正确检查有效移动 - 您无法移动&#39;离开&#39;或者&#39;对&#39;到另一排。 - 请参阅最后的新方法以及DFSFromStart

中对该方法的调用

编辑3 在比较目标是否达到目标之前,DFSFromStart没有考虑移动的有效性。

答案 1 :(得分:0)

基本上,您想要查看当前位置是否距离所选位置一个区域。

有几个步骤可以验证这一点。首先,找到两个职位的difference。如果两个点的绝对差值等于每一行的长度(在这种情况下为9),则表示所选位置高于或低于当前位置,使移动有效。

如果该步骤失败,则需要检查两个点是否彼此相邻,如果是,请确保它们在同一行。为此,您可以看到difference是否等于1,如果是,则将每个位置除以行的长度,看它们是否相等。你剩下的就是与此类似的东西:

int difference = Absolute(CURRENT - SELECTED)

int CURRENT_ROW_NUMBER = CURRENT / ROW_LENGTH
int SELECTED_ROW_NUMBER = SELECTED / ROW_LENGTH

if(difference == ROW_LENGTH)
{
    ValidMove();
}
else if(difference == 1 && CURRENT_ROW_NUMBER == SELECTED_ROW_NUMBER))
{
    ValidMove();
}
else
{
    InvalidMove();
}

我对语言不太熟悉,但这是你尝试过的逻辑背后的原因。

祝你好运!