zoukankan      html  css  js  c++  java
  • IOS开发-影院选座算法 限制产生孤座

    众所周知目前影院选座是不允许随便选的,我们不可以任性的挑三拣四,最后留下N个单独的座位,目的就是要留下至少2个连着的座位;

    另外有些影院的座位摆放并不是规则的,有些座位被过道或者特殊座位分割开,产生了不同的分区,这里就实现检测有没有座位变成了孤座,

    孤座的含义简单说就是两个小情侣不能挨着坐了~

    但是也存在特殊情况,及因为分区的缘故,某一排连着的座位只有2个,或者只有3个,这时候还是可以允许人家买其中之一,或者之二的~

    好,条件说完之后,开始介绍数据结构,正常情况下,影院的每一个座位数据会包含坐标,座位号,如x,y,row,column。

    其中,影厅中的面积会以单个座位的大小被分割成M*N的坐标系,即过道也有它的坐标;而row和column才是真正的座位;

    啰嗦了半天,下面上代码:

    入口函数是verifySelectedSeatsWithSeatsDic,

      1. 参数seatsDic是一个字典,注意该字典过滤掉了非座位的数据!(字典是本项目所需,你可以直接用一个array,方法中我也是获取了array;注意座位数据的顺序一定是有序的,这样才能获取到一个座位的左右座位)

      2. 每个座位的数据我封装成了一个WCSeatButton,并提供了isSeatAvailable方法判断该座位是否可以被购买(未被售出)

      3. 函数getNearBySeatsInSameRowForSeat负责获取没有被过道等非座位隔开的所有座位

        4. 函数(BOOL)isSeat:(WCSeatButton *)s1 nearBySeatWithoutRoad:(WCSeatButton *)s2判断两个座位是否被过道隔开

    -(BOOL)verifySelectedSeatsWithSeatsDic:(NSDictionary *)seatsDic {
        NSArray *seatBtns = [seatsDic allValues];
        if ([seatBtns count] > 0) {
            for (WCSeatButton *btn in seatBtns) {
                //查看可选座位是否落单
                if([btn isSeatAvailable]){
                    int idx = btn.seatIndex;
    
                    WCSeatButton *preBtn = [seatsDic objectForKey:[NSString stringWithFormat:@"%i", idx - 1]];
                    WCSeatButton *nextBtn = [seatsDic objectForKey:[NSString stringWithFormat:@"%i", idx + 1]];
    
                    //检验是否存在相邻座位 and 可用
                    BOOL isPreOK = preBtn != nil &&
                            [preBtn.serviceSeat.row isEqualToString:btn.serviceSeat.row] &&
                            [preBtn isSeatAvailable];
                    BOOL isNextOK = nextBtn != nil &&
                            [nextBtn.serviceSeat.row isEqualToString:btn.serviceSeat.row]&&
                            [nextBtn isSeatAvailable] ;
    
                    //再判断同一分区
                    if (isPreOK) {
                        isPreOK =  ABS([btn.serviceSeat.yCoord intValue] - [preBtn.serviceSeat.yCoord intValue]) == 1;
    
                    }
                    if (isNextOK) {
                        isNextOK = ABS([btn.serviceSeat.yCoord intValue] - [nextBtn.serviceSeat.yCoord intValue]) == 1;
    
                    }
    
                    if (!isPreOK && !isNextOK) {
                        NSArray *nearBySeats = [self getNearBySeatsInSameRowForSeat:btn withSeatsDic:seatsDic];
                        //例外 两个座位只选一个
                        if ([nearBySeats count] == 2) {
                            continue;
                        }
                        //例外 3个座位中2个连续被选,剩下单个座位
                        if ([nearBySeats count] == 3) {
                            int idx = [nearBySeats indexOfObject:btn];
                            //空座位如果在两边说明中间的座位已经被选,则只要还有一个被选就可以
                            if (idx == 0 && ![nearBySeats[2] isSeatAvailable]) {
                                continue;
                            }else if(idx == 2 && ![nearBySeats[0] isSeatAvailable]) {
                                continue;
                            }
                        }
    
                        //只限制当前用户选择的座位,防止其他渠道产生孤座导致当前用户不能选座
                        for (WC630ServiceSeat *s in self.orderItem.seats) {
                             if((preBtn && [[[preBtn serviceSeat] cineSeatId] isEqualToString:s.cineSeatId]) ||
                                     (nextBtn && [[[nextBtn serviceSeat] cineSeatId] isEqualToString:s.cineSeatId])    ) {
                                 return NO;
                             }
                        }
                    }
    
    
                }
            }
        }
    
        return YES;
    }
    
    -(NSArray *)getNearBySeatsInSameRowForSeat:(WCSeatButton *)seat withSeatsDic:(NSDictionary *)seatsDic{
        NSMutableArray *result = [NSMutableArray array];
        [result addObject:seat];
    
        int idx = seat.seatIndex - 1;
        //left
        WCSeatButton *tmp= [seatsDic objectForKey:[NSString stringWithFormat:@"%i", idx]];
        while([self isSeat:tmp nearBySeatWithoutRoad:seat]){
            [result insertObject:tmp atIndex:0];
            idx--;
            tmp = [seatsDic objectForKey:[NSString stringWithFormat:@"%i", idx]];
        }
    
        idx = seat.seatIndex + 1;
        //right
        tmp= [seatsDic objectForKey:[NSString stringWithFormat:@"%i", idx]];
        while([self isSeat:tmp nearBySeatWithoutRoad:seat]){
            [result addObject:tmp];
            idx++;
            tmp = [seatsDic objectForKey:[NSString stringWithFormat:@"%i", idx]];
        }
    
    
        return result;
    }
    
    -(BOOL)isSeat:(WCSeatButton *)s1 nearBySeatWithoutRoad:(WCSeatButton *)s2{
    
        return     s1 != nil &&
                [s1.serviceSeat.row isEqualToString:s2.serviceSeat.row] &&
                ABS([s1.serviceSeat.yCoord intValue] - [s2.serviceSeat.yCoord intValue]) == ABS([s1.serviceSeat.column intValue] - [s2.serviceSeat.column intValue]) ;
    }
  • 相关阅读:
    时间形式的转换
    vue 按enter键 进行搜索或者表单提交
    关于Cookie 关于前端存储数据
    复杂数组去重
    蜜蜂
    MongoDB学习记录一
    python 基础 day03—函数
    python 基础 day03—文件操作
    python 基础 day02—列表List / 元组Tuple
    python 基础 day02—初识模块
  • 原文地址:https://www.cnblogs.com/v-jing/p/4180129.html
Copyright © 2011-2022 走看看