"""
    逻辑处理模块
    1.0 将核心算法粘贴进来
    2.0 将所有参数，改为成员变量．
    3.0 在空白位置上随机产生新数字．
    4.0 如果地图有变化(数字移动／数字合并)
    5.0 判定游戏是否结束
"""

from model import Location
from model import Direction
import random
import copy


class GameCoreController:
    """
        游戏核心控制器
    """

    def __init__(self):
        # self.__map = [
        #     [0, 0, 0, 0],
        #     [0, 0, 0, 0],
        #     [0, 0, 0, 0],
        #     [0, 0, 0, 0],
        # ]
        self.__map = [
            [0] * 4,
            [0] * 4,
            [0] * 4,
            [0] * 4,
        ]
        # 以下数据，是为了测试地图是否发生变化创建的．
        # self.__map = [
        #     [2, 4, 2, 4],
        #     [0, 0, 0, 2],
        #     [0, 0, 0, 0],
        #     [0, 0, 0, 0],
        # ]
        # 以下数据，是为了测试游戏是否结束创建的．
        # self.__map = [
        #     [2, 4, 2, 4],
        #     [8, 16, 4, 32],
        #     [32, 4, 2, 64],
        #     [64, 32, 16, 0],
        # ]
        # 用于存储去零和合并的列表
        self.__list_merge = []
        # 用于存储空位置的列表
        self.__list_empty_location = []
        # 地图是否发生变化
        self.is_change = False

    @property
    def map(self):
        return self.__map

    @property
    def is_change(self):
        return self.__is_change

    @is_change.setter
    def is_change(self, value):
        self.__is_change = value

    def __zero_to_end(self):
        for i in range(len(self.__list_merge) - 1, -1, -1):
            if self.__list_merge[i] == 0:
                del self.__list_merge[i]
                self.__list_merge.append(0)

    def __merge(self):
        self.__zero_to_end()
        for i in range(len(self.__list_merge) - 1):
            if self.__list_merge[i] == self.__list_merge[i + 1]:
                self.__list_merge[i] += self.__list_merge[i + 1]
                self.__list_merge[i + 1] = 0
        self.__zero_to_end()

    def __move_left(self):
        for r in range(len(self.__map)):
            self.__list_merge[:] = self.__map[r]
            self.__merge()
            self.__map[r][:] = self.__list_merge

    def __move_right(self):
        for r in range(len(self.__map)):
            self.__list_merge[:] = self.__map[r][::-1]
            self.__merge()
            self.__map[r][::-1] = self.__list_merge

    def __move_up(self):
        for c in range(4):
            # 清空合并列表，目的：避免之前列表中的结果，对本次有影响．
            self.__list_merge.clear()
            for r in range(4):
                self.__list_merge.append(self.__map[r][c])
            self.__merge()
            for r in range(4):
                self.__map[r][c] = self.__list_merge[r]

    def __move_down(self):
        for c in range(4):
            self.__list_merge.clear()
            for r in range(3, -1, -1):
                self.__list_merge.append(self.__map[r][c])
            self.__merge()
            for r in range(3, -1, -1):
                self.__map[r][c] = self.__list_merge[3 - r]

    def move(self, dir):
        """
            移动
        :param dir: Direction类型　
        :return:
        """
        # 通过深拷贝(二维列表)记录移动前的地图　
        original_map = copy.deepcopy(self.__map)

        if dir == Direction.up:
            self.__move_up()
        elif dir == Direction.down:
            self.__move_down()
        elif dir == Direction.left:
            self.__move_left()
        elif dir == Direction.right:
            self.__move_right()

        # 移动后对比地图
        self.is_change = original_map != self.__map

    def __calculate_empty_location(self):
        self.__list_empty_location.clear()#清空列表
        for r in range(4):
            for c in range(4):
                if self.__map[r][c] == 0:
                    # 创建位置对象
                    loc = Location(r, c)
                    self.__list_empty_location.append(loc)

    def generate_new_number(self):
        """
            随机生成新数字
        :return:
        """
        self.__calculate_empty_location()
        if len(self.__list_empty_location) == 0:
            return
        # 从空位置列表中，随机选择一个元素．
        loc = random.choice(self.__list_empty_location)
        # 随机生成数字
        self.__map[loc.r_index][loc.c_index] = 4 if random.randint(1, 10) == 1 else 2
        # 因为上一行代码已经占了该空位置，所以从空位置列表中移除当前位置．
        self.__list_empty_location.remove(loc)

    def is_game_over(self):
        """
            游戏是否结束
        :return:
        """
        # 1. 如果有空位置 游戏不能结束
        if len(self.__list_empty_location) >0:
            return False

        # # 2. 横向具有相同元素　游戏不能结束
        # for r in range(4):
        #     for c in range(3):
        #         if self.__map[r][c] == self.__map[r][c+1]:
        #             return False
        #
        # # 3. 竖向具有相同元素　游戏不能结束
        # for c in range(4):
        #     for r in range(3):
        #         if self.__map[r][c] == self.__map[r+1][c]:
        #             return False

        # (扩展)　2 + 3  横向同时竖向　比较是否具有相同元素
        for r in range(4):
            for c in range(3):
                if self.__map[r][c] == self.__map[r][c+1] or self.__map[c][r] == self.__map[c+1][r]:
                    return False

        return True # 如果以上条件都不满足，则游戏结束

# ------------------以下为测试代码---------------------------
def print_map(map):
    print("----------------")
    for r in range(len(map)):
        for c in range(len(map[r])):
            print(map[r][c], end=" ")
        print()


if __name__ == "__main__":
    core = GameCoreController()
    print_map(core.map)
    core.generate_new_number()
    core.generate_new_number()
    print_map(core.map)
