Esempio n. 1
0
    /// <summary>
    /// Метод проверяет наличие "матчей" после свапа для блоков, которые были свапнуты. Если есть, удаляем "матчи" и затем производим "осыпание" доски.
    /// </summary>
    /// <param name="prevBlock">Блок, на который кликнули ранее.</param>
    /// <param name="currentBlock">Блок, на который кликнули сейчас</param>
    /// <returns>Метод возвращает были "матчи" после свапа или нет</returns>
    public bool CheckMatchesForSwappedBlocks(BlockStruct prevBlock, BlockStruct currentBlock)
    {
        List <BlockStruct> matchingBlocks = new List <BlockStruct>();

        matchingBlocks.AddRange(CheckVerticalMatches(prevBlock.X, prevBlock.Y));
        matchingBlocks.AddRange(CheckHorizontalMatches(prevBlock.X, prevBlock.Y));
        if (matchingBlocks.Count > 0)
        {
            matchingBlocks.Add(prevBlock);
        }

        List <BlockStruct> verticalMatchingBlocks = new List <BlockStruct>();

        verticalMatchingBlocks.AddRange(CheckVerticalMatches(currentBlock.X, currentBlock.Y));
        verticalMatchingBlocks.AddRange(CheckHorizontalMatches(currentBlock.X, currentBlock.Y));
        if (verticalMatchingBlocks.Count > 0)
        {
            matchingBlocks.Add(currentBlock);
            matchingBlocks.AddRange(verticalMatchingBlocks);
        }

        if (matchingBlocks.Count > 0)
        {
            ClearMatches(matchingBlocks);
            FindNullBlocks();
            return(true);
        }
        else
        {
            return(false);
        }
    }
Esempio n. 2
0
    public void SwapColor(BlockStruct otherBlock)
    {
        Color tempColor = otherBlock.Color;

        otherBlock.Color = this.Color;
        this.Color       = tempColor;
    }
Esempio n. 3
0
 void Awake()
 {
     boardGeneration = GetComponent <BoardGeneration>();
     GameBoard       = new BlockStruct[xSize, ySize];
     boardGeneration.GenerateGameBoard(ref GameBoard, this);
     boardGeneration.VisualizeBlocks(GameBoard);
     prevSelected = null;
 }
Esempio n. 4
0
    /// <summary>
    /// См. описание метода для поиска по вертикали. Аналогично только по горизонтали
    /// </summary>
    /// <param name="block">Блок для которого ищем возможные ходы</param>
    /// <returns>Возвращает true, если есть возможные ходы, иначе false</returns>
    private bool CheckHorizontalPossible(BlockStruct block)
    {
        if (block.X < xSize - 1 && GameBoard[block.X + 1, block.Y].Color == block.Color)
        {
            if (block.X > 0)
            {
                if (block.Y > 0 && GameBoard[block.X - 1, block.Y - 1].Color == block.Color)
                {
                    return(true);
                }
                if (block.Y < ySize - 1 && GameBoard[block.X - 1, block.Y + 1].Color == block.Color)
                {
                    return(true);
                }
                if (block.X > 1 && GameBoard[block.X - 2, block.Y].Color == block.Color)
                {
                    return(true);
                }
            }
            if (block.X < xSize - 2)
            {
                if (block.Y > 0 && GameBoard[block.X + 2, block.Y - 1].Color == block.Color)
                {
                    return(true);
                }
                if (block.Y < ySize - 1 && GameBoard[block.X + 2, block.Y + 1].Color == block.Color)
                {
                    return(true);
                }
                if (block.X < xSize - 3 && GameBoard[block.X + 3, block.Y].Color == block.Color)
                {
                    return(true);
                }
            }
        }

        if (block.X < xSize - 2 && GameBoard[block.X + 2, block.Y].Color == block.Color)
        {
            if (block.Y > 0 && GameBoard[block.X + 1, block.Y - 1].Color == block.Color)
            {
                return(true);
            }
            if (block.Y < ySize - 1 && GameBoard[block.X + 1, block.Y + 1].Color == block.Color)
            {
                return(true);
            }
        }
        return(false);
    }
Esempio n. 5
0
    /// <summary>
    /// По вертикали возможны следующие ситуации:
    /// 1) Два блока подряд одного цвета, следующий блок другого цвета, а рядом с этим блоком другого цвета (сверху, справа или слева) есть блок с нужным цветом
    /// 2) Два блока подряд одного цвета, под ними блок другого цвета, а рядом с этим блоком другого цвета (снизу, справа или слева) есть блок с нужным цветом
    /// 3) Два блока одного цвета, а между ними блок другого цвета, и слева или справа от блока другого цвета есть блок с нужным цветом
    /// </summary>
    /// <param name="block">Блок для которого ищем возможные ходы</param>
    /// <returns>Возвращает true, если есть возможные ходы, иначе false</returns>
    private bool CheckVerticalPossible(BlockStruct block)
    {
        if (block.Y < ySize - 1 && GameBoard[block.X, block.Y + 1].Color == block.Color)
        {
            if (block.Y > 0)
            {
                if (block.X > 0 && GameBoard[block.X - 1, block.Y - 1].Color == block.Color)
                {
                    return(true);
                }
                if (block.X < xSize - 1 && GameBoard[block.X + 1, block.Y - 1].Color == block.Color)
                {
                    return(true);
                }
                if (block.Y > 1 && GameBoard[block.X, block.Y - 2].Color == block.Color)
                {
                    return(true);
                }
            }
            if (block.Y < ySize - 2)
            {
                if (block.X > 0 && GameBoard[block.X - 1, block.Y + 2].Color == block.Color)
                {
                    return(true);
                }
                if (block.X < xSize - 1 && GameBoard[block.X + 1, block.Y + 2].Color == block.Color)
                {
                    return(true);
                }
                if (block.Y < ySize - 3 && GameBoard[block.X, block.Y + 3].Color == block.Color)
                {
                    return(true);
                }
            }
        }

        if (block.Y < ySize - 2 && GameBoard[block.X, block.Y + 2].Color == block.Color)
        {
            if (block.X > 0 && GameBoard[block.X - 1, block.Y + 1].Color == block.Color)
            {
                return(true);
            }
            if (block.X < xSize - 1 && GameBoard[block.X + 1, block.Y + 1].Color == block.Color)
            {
                return(true);
            }
        }
        return(false);
    }
Esempio n. 6
0
    public void SwapForShift(BlockStruct otherBlock)
    {
        Color tempCol     = otherBlock.Color;
        bool  tempCleared = otherBlock.cleared;
        bool  tempDel     = otherBlock.deleted;

        otherBlock.Color = this.Color;
        this.Color       = tempCol;

        otherBlock.deleted = this.deleted;
        this.deleted       = tempDel;

        otherBlock.cleared = this.cleared;
        this.cleared       = tempCleared;
    }
Esempio n. 7
0
    /// <summary>
    /// Метод подбирает цвет для блока. Цвет не должен создать ситуацию "готовых матчей". Но также мы не должны выйти за границы массива.
    /// </summary>
    /// <param name="block">Блок, для которого подбираем цвет</param>
    /// <returns></returns>
    private List <Color> GetPossibleColors(BlockStruct block)
    {
        List <Color> possibleColors = new List <Color>();

        possibleColors.AddRange(boardGeneration.BlockColors);

        if (block.X > 1 && GameBoard[block.X - 2, block.Y].Color == GameBoard[block.X - 1, block.Y].Color)
        {
            possibleColors.Remove(GameBoard[block.X - 1, block.Y].Color);
        }
        if (block.X < xSize - 2 && GameBoard[block.X + 1, block.Y].Color == GameBoard[block.X + 2, block.Y].Color && !GameBoard[block.X + 1, block.Y].cleared && !GameBoard[block.X + 2, block.Y].cleared)
        {
            possibleColors.Remove(GameBoard[block.X + 1, block.Y].Color);
        }
        if (block.X > 0 && block.X < xSize - 1 && GameBoard[block.X + 1, block.Y].Color == GameBoard[block.X - 1, block.Y].Color && !GameBoard[block.X + 1, block.Y].cleared)
        {
            possibleColors.Remove(GameBoard[block.X + 1, block.Y].Color);
        }
        if (block.Y > 1 && GameBoard[block.X, block.Y - 1].Color == GameBoard[block.X, block.Y - 2].Color)
        {
            possibleColors.Remove(GameBoard[block.X, block.Y - 1].Color);
        }
        if (block.Y > 0 && block.Y < ySize - 1 && GameBoard[block.X, block.Y + 1].Color == GameBoard[block.X, block.Y - 1].Color && !GameBoard[block.X, block.Y + 1].cleared)
        {
            possibleColors.Remove(GameBoard[block.X, block.Y - 1].Color);
        }
        if (block.Y < ySize - 2 && GameBoard[block.X, block.Y + 1].Color == GameBoard[block.X, block.Y + 2].Color && !GameBoard[block.X, block.Y + 1].cleared && !GameBoard[block.X, block.Y + 2].cleared)
        {
            possibleColors.Remove(GameBoard[block.X, block.Y + 1].Color);
        }

        if (possibleColors.Count > 0)
        {
            return(possibleColors);
        }
        else
        {
            //такой ситуации быть с 6 цветами не может, но на всякий случай я её добавлю
            return(new List <Color> {
                Color.white
            });
        }
    }
Esempio n. 8
0
    public void SaveGameToJsonFile()
    {
        GameSave gameSave = new GameSave();
        // get player data and set to serializable structs
        PlayerStruct playerStruct = PlayerManager.instance.player.ToPlayerStruct();

        gameSave.SetPlayer(playerStruct);
        // get block data and set to serializable structs
        foreach (Block b in BlockManager.instance.GetBlocksAsList())
        {
            BlockStruct blockStruct = b.ToBlockStruct();
            gameSave.AddBlock(blockStruct);
        }
        // commit the save data
        string json = JsonUtility.ToJson(gameSave);

        // print("save game to file...");
        // print("json to save: " + json);
        // print("path to save: " + GetSavePath());
        File.WriteAllText(GetSavePath(), json, Encoding.UTF8);
    }
Esempio n. 9
0
    public void GenerateGameBoard(ref BlockStruct[,] GameBoard, BoardManager boardManager)
    {
        for (int x = 0; x < GameBoard.GetLength(0); x++)
        {
            for (int y = 0; y < GameBoard.GetLength(1); y++)
            {
                GameBoard[x, y] = new BlockStruct();

                #region "Без стартовых 'Матчей'";
                List <Color> possibleColors = new List <Color>();
                possibleColors.AddRange(BlockColors);
                if (x > 1 && GameBoard[x - 2, y].Color == GameBoard[x - 1, y].Color)
                {
                    possibleColors.Remove(GameBoard[x - 1, y].Color);
                }
                if (y > 1 && GameBoard[x, y - 1].Color == GameBoard[x, y - 2].Color)
                {
                    possibleColors.Remove(GameBoard[x, y - 1].Color);
                }
                Color blockColor = possibleColors[Random.Range(0, possibleColors.Count)];
                #endregion ;

                GameBoard[x, y].SetStartData(x, y, blockColor);
            }
        }

        int counter = 0;
        while (!boardManager.CheckPossibleMatches() || counter >= tryCount)
        {
            GameBoard = RegenerateBoard(GameBoard);
            counter++;
        }

        if (counter >= tryCount)
        {
            boardManager.EndGame();
            Debug.Log("Cant start the game 100 times!");
        }
    }
Esempio n. 10
0
    private void OnMouseDown()
    {
        if (!render.enabled)
        {
            return;
        }
        BlockStruct block = boardManager.GameBoard[_x, _y];

        if (block.selected)
        {
            boardManager.Deselect(_x, _y);
        }
        else
        {
            if (boardManager.prevSelected == null)
            {
                boardManager.Select(_x, _y);
            }
            else
            {
                if (boardManager.IsBlockNeighbour(_x, _y))
                {
                    boardManager.SwapBlocks(boardManager.GameBoard[_x, _y], boardManager.prevSelected);
                    if (!boardManager.CheckMatchesForSwappedBlocks(boardManager.prevSelected, boardManager.GameBoard[_x, _y]))
                    {
                        boardManager.SwapBlocks(boardManager.GameBoard[_x, _y], boardManager.prevSelected);
                    }
                    boardManager.Deselect(boardManager.prevSelected.X, boardManager.prevSelected.Y);
                }
                else
                {
                    boardManager.Deselect(boardManager.prevSelected.X, boardManager.prevSelected.Y);
                    boardManager.Select(_x, _y);
                }
            }
        }
    }
Esempio n. 11
0
    public static BlockArray CreateTestArray()
    {
        var blockArray = new BlockArray();

        blockArray.Values = new BlockStruct[100 * 100];
        var index = 0;

        for (var x = 0; x < 100; x++)
        {
            for (var y = 0; y < 100; y++)
            {
                var blockStruct = new BlockStruct
                {
                    Type     = (short)Random.Range(0, 5),
                    GroupId  = 0,
                    Position = new int2(x, y),
                    FrameCountLastUpdated = 0,
                };
                blockArray.Values[index++] = blockStruct;
            }
        }

        return(blockArray);
    }
Esempio n. 12
0
        private static void ProcessAbuseLog()
        {
            var currentTimestamp = Utilities.GetCurrentTimestamp();
            var expireTimestamp  = currentTimestamp - GlobalVars.Config.AbuseExpirationTime;
            var blockCounter     = 0;
            var itemsToRemove    = new List <string>();

            foreach (var(key, value) in AbuseDictionary)
            {
                if (GlobalVars.Data.BlockHashSet.Contains(value.IpAddress))
                {
                    itemsToRemove.Add(key);
                    continue;
                }

                while (true)
                {
                    if (value.Timestamps.TryPeek(out var timestamp))
                    {
                        if (timestamp < expireTimestamp)
                        {
                            value.Timestamps.Dequeue();
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                // remove expired timestamps
                if (value.Timestamps.Count == 0)
                {
                    itemsToRemove.Add(key);
                    continue;
                }

                // count & block abusing ips
                var abusesToBlock = _underAttack
                                        ? GlobalVars.Config.AbusesToBlockUnderAttack
                                        : GlobalVars.Config.AbusesToBlock;

                if (value.Timestamps.Count >= abusesToBlock)
                {
                    var blockStruct = new BlockStruct(value.IpAddress, currentTimestamp + GlobalVars.Config.BlockExpirationTime)
                    {
                        BlockId = CloudflareUtilities.Block(value.IpAddress)
                    };

                    Console.WriteLine($"Blocked abusing IP: {blockStruct.IpAddress} (Id = {blockStruct.BlockId})");

                    GlobalVars.Data.BlockQueue.Enqueue(blockStruct);
                    GlobalVars.Data.BlockHashSet.Add(value.IpAddress);
                    blockCounter++;

                    itemsToRemove.Add(key);
                    _dataChanged = true;
                }
            }

            foreach (var key in itemsToRemove)
            {
                AbuseDictionary.Remove(key);
            }

            if (!_underAttack && blockCounter >= GlobalVars.Config.BlocksToUnderAttack)
            {
                _underAttack = true;
                Console.WriteLine($"UAM is now enabled (blocked {blockCounter} IPs in one tick)");

                if (GlobalVars.Config.CloudflareUnderAttackMode)
                {
                    foreach (var id in GlobalVars.Config.CloudflareManageZones)
                    {
                        CloudflareUtilities.SecurityLevel(id, "under_attack");
                        Console.WriteLine($"SecurityLevel({id}) = under_attack");
                    }
                }
            }

            if (_underAttack)
            {
                if (blockCounter > 0)
                {
                    _underAttackExpirationTicks = GlobalVars.Config.UnderAttackExpirationTicks;
                }
                else
                {
                    _underAttackExpirationTicks--;

                    if (_underAttackExpirationTicks <= 0)
                    {
                        _underAttack = false;
                        Console.WriteLine("UAM is now disabled, no more abuses detected");

                        if (GlobalVars.Config.CloudflareUnderAttackMode)
                        {
                            foreach (var id in GlobalVars.Config.CloudflareManageZones)
                            {
                                CloudflareUtilities.SecurityLevel(id, GlobalVars.Config.CloudflareModeDefault);
                                Console.WriteLine($"SecurityLevel({id}) = {GlobalVars.Config.CloudflareModeDefault}");
                            }
                        }
                    }
                }
            }
        }
Esempio n. 13
0
 public void SwapBlocks(BlockStruct firstBlock, BlockStruct secondBlock)
 {
     firstBlock.SwapColor(secondBlock);
     secondBlock.VisualChangeColor?.Invoke(secondBlock.Color);
     firstBlock.VisualChangeColor?.Invoke(firstBlock.Color);
 }
Esempio n. 14
0
 public void Select(int x, int y)
 {
     GameBoard[x, y].selected = true;
     prevSelected             = GameBoard[x, y];
     GameBoard[x, y].VisualSelect?.Invoke();
 }
Esempio n. 15
0
 public void Deselect(int x, int y)
 {
     GameBoard[x, y].selected = false;
     GameBoard[x, y].VisualDeselect?.Invoke();
     prevSelected = null;
 }
Esempio n. 16
0
 public void AddBlock(BlockStruct block)
 {
     this.blocks.Add(block);
 }