Example #1
0
 void GenerateNextTetris()
 {
     nextTetrisType = randGen.Next(7); //选择类型
     nextChangeType = randGen.Next(4); //选择变体
     nextChangeType = nextChangeType % changeNum[nextTetrisType];
     nextOffset     = tetrisOffset[nextTetrisType][nextChangeType];
 }
Example #2
0
        bool RunGridMove(Direction dir)
        {
            Grid[] nextGrids = null;
            switch (dir)
            {
            case Direction.DOWN:
                nextGrids = GetRunGridsAtPos(currentRunGridX, currentRunGridY + 1, currentOffset);
                if (!CheckNextGridValid(nextGrids))
                {
                    return(false);
                }
                currentRunGridY++;
                break;

            case Direction.LEFT:
                nextGrids = GetRunGridsAtPos(currentRunGridX - 1, currentRunGridY, currentOffset);
                if (!CheckNextGridValid(nextGrids))
                {
                    return(false);
                }
                currentRunGridX--;
                break;

            case Direction.RIGHT:
                nextGrids = GetRunGridsAtPos(currentRunGridX + 1, currentRunGridY, currentOffset);
                if (!CheckNextGridValid(nextGrids))
                {
                    return(false);
                }
                currentRunGridX++;
                break;

            case Direction.UP:
            {
                int         changType = (curChangeType + 1) % changeNum[curTetrisType];
                SceneOffset offset    = tetrisOffset[curTetrisType][changType];
                nextGrids = GetRunGridsAtPos(currentRunGridX, currentRunGridY, offset);
                if (!CheckNextGridValid(nextGrids))
                {
                    return(false);
                }
                currentOffset = offset;
                curChangeType = changType;
            }
            break;
            }

            foreach (Grid g in runGrids)
            {
                g.show    = false;
                g.running = false;
            }
            runGrids = nextGrids;
            foreach (Grid g in runGrids)
            {
                g.show    = true;
                g.running = true;
            }
            return(true);
        }
Example #3
0
 //在某个坐标位置生成掉落方块
 Grid[] GetRunGridsAtPos(int x, int y, SceneOffset offset)
 {
     Grid[] grids = new Grid[4];
     grids[0] = GetGridByPos(x + offset.X1, y + offset.Y1);
     grids[1] = GetGridByPos(x + offset.X2, y + offset.Y2);
     grids[2] = GetGridByPos(x + offset.X3, y + offset.Y3);
     grids[3] = GetGridByPos(x + offset.X4, y + offset.Y4);
     return(grids);
 }
Example #4
0
        //预览区初始化
        void CalcPreGrids()
        {
            SceneOffset offset = nextOffset;

            foreach (Grid g in nextPreGrids)
            {
                if (g != null)
                {
                    g.show = false;
                }
            }

            nextPreGrids[0] = preGrids[kPreBornX + offset.X1, kPreBornY + offset.Y1];
            nextPreGrids[1] = preGrids[kPreBornX + offset.X2, kPreBornY + offset.Y2];
            nextPreGrids[2] = preGrids[kPreBornX + offset.X3, kPreBornY + offset.Y3];
            nextPreGrids[3] = preGrids[kPreBornX + offset.X4, kPreBornY + offset.Y4];
            foreach (Grid g in nextPreGrids)
            {
                g.show = true;
            }
        }
Example #5
0
        //一轮下落的开始
        void OnNextRound()
        {
            currentRunGridX = kRunGridBirthX;
            currentRunGridY = kRunGridBirthY;

            if (nextOffset == null)
            {
                GenerateNextTetris();
            }
            currentOffset = nextOffset;
            curChangeType = nextChangeType;
            curTetrisType = nextTetrisType;

            //把预览区的offset移到游戏区
            runGrids = GetRunGridsAtPos(currentRunGridX, currentRunGridY, currentOffset);
            if (!CheckNextGridValid(runGrids))
            {
                gameState = GameState.GameOver;
                return;
            }
            foreach (Grid g in runGrids)
            {
                g.running = true;
                g.show    = true;
            }
            //生成预览区的offset
            GenerateNextTetris();
            //计算预览区网格
            CalcPreGrids();
            gameState = GameState.NormalDrop;

            if (IsAiControl)
            {
                CalcAICtrl();
            }
        }
Example #6
0
        //Pierre Dellacherie算法
        void CalcAI2()
        {
            //先把正在下落的格子显示状态抹除
            foreach (var g in runGrids)
            {
                g.show = false;
            }

            int R_X          = 0;     //最优坐标
            int R_Change     = 0;     //最优变换次数
            int R_ChangeType = 0;
            int R_Value      = -9999; //最优评估值
            int changeType   = curChangeType;

            for (int change = 0; change < changeNum[curTetrisType]; change++)
            {
                SceneOffset local_offset = localOffset[curTetrisType][changeType];
                for (int x = 0; x < kSceneWidth; x++)
                {
                    Grid[] lastValidGrids = null;
                    for (int y = 0; y < kSceneHeight; y++)
                    {
                        var showGrids = GetRunGridsAtPos(x, y, local_offset);
                        if (!CheckAIGridValid(showGrids))
                        {
                            break;
                        }
                        lastValidGrids = showGrids;
                    }
                    if (lastValidGrids != null)
                    {
                        int landingHeight       = aiCalcLandingHeight(lastValidGrids);
                        int eraseLine           = aiCalcEraseLine(lastValidGrids);
                        var finalGrids          = aiCalcFinalGrids(lastValidGrids);
                        int boardRowTransitions = aiCalcRow(finalGrids);
                        int boardColTransitions = aiCalcColumn(finalGrids);
                        int boardBuriedHoles    = aiCalcHoles(finalGrids);
                        int wells = aiCalcWell(finalGrids);
                        int value = -45 * landingHeight + 34 * eraseLine - 32 * boardRowTransitions - 93 * boardColTransitions - (79 * boardBuriedHoles) - 34 * wells;
                        if (value > R_Value)
                        {
                            R_Value      = value;
                            R_X          = x;
                            R_Change     = change;
                            R_ChangeType = changeType;
                        }
                    }
                }

                //遍历所有变形
                changeType = (changeType + 1) % changeNum[curTetrisType];
            }


            var offset = tetrisOffset[curTetrisType][R_ChangeType];
            int moveX  = R_X - offset.X1 - currentRunGridX;

            foreach (var g in runGrids)//还原显示状态
            {
                g.show = true;
            }
            RunAISteps(moveX, R_Change);
        }
Example #7
0
        //计算一个结果最好的X坐标落下去
        //1.选形状完全匹配的,如果有多个匹配进入2;
        //2.选消除行数最多的,如果有多个匹配进入3;
        //3.选高度最低的,如果有多个匹配选第一个;
        void CalcAI1()
        {
            //先把正在下落的格子显示状态抹除
            foreach (var g in runGrids)
            {
                g.show = false;
            }
            List <CheckResult> results = new List <CheckResult>();
            int changeType             = curChangeType;

            for (int change = 0; change < changeNum[curTetrisType]; change++)
            {
                SceneOffset local_offset = localOffset[curTetrisType][changeType];

                for (int x = 0; x < kSceneWidth; x++)
                {
                    Grid[] lastValidGrids = null;
                    for (int y = 0; y < kSceneHeight; y++)
                    {
                        var showGrids = GetRunGridsAtPos(x, y, local_offset);
                        if (!CheckAIGridValid(showGrids))
                        {
                            break;
                        }
                        lastValidGrids = showGrids;
                    }
                    if (lastValidGrids != null)
                    {
                        CheckResult result = new CheckResult();
                        result.Change     = change;
                        result.ChangeType = changeType;
                        result.X          = x;
                        int  minY       = kSceneHeight - 1;
                        bool matchShape = true;
                        Dictionary <int, bool> lineY = new Dictionary <int, bool>();

                        foreach (var g in lastValidGrids)
                        {
                            //计算高度
                            if (g.sceneY < minY)
                            {
                                minY = g.sceneY;
                            }
                            //匹配形状
                            if (g.sceneY + 1 < kSceneHeight)
                            {
                                Grid nextGrid = allGrids[g.sceneX, g.sceneY + 1];
                                if (!GridsContainsGrid(lastValidGrids, nextGrid) && !nextGrid.show)
                                {
                                    matchShape = false;
                                }
                            }
                            //计算消除行数
                            if (!lineY.ContainsKey(g.sceneY))
                            {
                                lineY.Add(g.sceneY, true);
                                if (CheckLineYFinished(g.sceneY, lastValidGrids))
                                {
                                    result.EraseLine++;
                                }
                            }
                        }
                        result.Height     = kSceneHeight - minY;
                        result.MatchShape = matchShape ? 1 : 2;

                        results.Add(result);
                    }
                }

                //遍历所有变形
                changeType = (changeType + 1) % changeNum[curTetrisType];
            }

            results.Sort((a, b) =>
            {
                int minH = Math.Min(a.Height, b.Height);
                if (minH > 10)
                {
                    if (a.EraseLine == b.EraseLine)
                    {
                        if (a.Height == b.Height)
                        {
                            return(a.MatchShape - b.MatchShape);
                        }
                        return(a.Height - b.Height);
                    }
                    return(b.EraseLine - a.EraseLine);
                }
                if (a.MatchShape == b.MatchShape)
                {
                    if (a.EraseLine == b.EraseLine)
                    {
                        return(a.Height - b.Height);
                    }
                    return(b.EraseLine - a.EraseLine);
                }
                else
                {
                    return(a.MatchShape - b.MatchShape);
                }
            });

            var finalResult = results[0];
            var offset      = tetrisOffset[curTetrisType][finalResult.ChangeType];
            int moveX       = finalResult.X - offset.X1 - currentRunGridX;

            foreach (var g in runGrids)//还原显示状态
            {
                g.show = true;
            }
            RunAISteps(moveX, finalResult.Change);
        }
Example #8
0
        void InitTetrisType()
        {
            //O
            tetrisOffset[3] = new List <SceneOffset>();
            tetrisOffset[3].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 1, X2 = 1, Y2 = 2, X3 = 2, Y3 = 1, X4 = 2, Y4 = 2
            });
            changeNum[3] = 1;

            //I
            tetrisOffset[0] = new List <SceneOffset>();
            tetrisOffset[0].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 0, X2 = 1, Y2 = 1, X3 = 1, Y3 = 2, X4 = 1, Y4 = 3
            });
            tetrisOffset[0].Add(new SceneOffset()
            {
                X1 = 0, Y1 = 1, X2 = 1, Y2 = 1, X3 = 2, Y3 = 1, X4 = 3, Y4 = 1
            });
            changeNum[0] = 2;

            //S
            tetrisOffset[4] = new List <SceneOffset>();
            tetrisOffset[4].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 0, X2 = 1, Y2 = 1, X3 = 2, Y3 = 1, X4 = 2, Y4 = 2
            });
            tetrisOffset[4].Add(new SceneOffset()
            {
                X1 = 2, Y1 = 1, X2 = 3, Y2 = 1, X3 = 1, Y3 = 2, X4 = 2, Y4 = 2
            });
            changeNum[4] = 2;
            //Z
            tetrisOffset[6] = new List <SceneOffset>();
            tetrisOffset[6].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 1, X2 = 2, Y2 = 1, X3 = 2, Y3 = 2, X4 = 3, Y4 = 2
            });
            tetrisOffset[6].Add(new SceneOffset()
            {
                X1 = 2, Y1 = 0, X2 = 2, Y2 = 1, X3 = 1, Y3 = 1, X4 = 1, Y4 = 2
            });
            changeNum[6] = 2;
            //L
            tetrisOffset[2] = new List <SceneOffset>();
            tetrisOffset[2].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 0, X2 = 1, Y2 = 1, X3 = 1, Y3 = 2, X4 = 2, Y4 = 2
            });
            tetrisOffset[2].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 1, X2 = 2, Y2 = 1, X3 = 3, Y3 = 1, X4 = 1, Y4 = 2
            });
            tetrisOffset[2].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 0, X2 = 2, Y2 = 0, X3 = 2, Y3 = 1, X4 = 2, Y4 = 2
            });
            tetrisOffset[2].Add(new SceneOffset()
            {
                X1 = 3, Y1 = 1, X2 = 3, Y2 = 2, X3 = 2, Y3 = 2, X4 = 1, Y4 = 2
            });
            changeNum[2] = 4;
            //J
            tetrisOffset[1] = new List <SceneOffset>();
            tetrisOffset[1].Add(new SceneOffset()
            {
                X1 = 2, Y1 = 0, X2 = 2, Y2 = 1, X3 = 2, Y3 = 2, X4 = 1, Y4 = 2
            });
            tetrisOffset[1].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 1, X2 = 1, Y2 = 2, X3 = 2, Y3 = 2, X4 = 3, Y4 = 2
            });
            tetrisOffset[1].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 0, X2 = 2, Y2 = 0, X3 = 1, Y3 = 1, X4 = 1, Y4 = 2
            });
            tetrisOffset[1].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 1, X2 = 2, Y2 = 1, X3 = 3, Y3 = 1, X4 = 3, Y4 = 2
            });
            changeNum[1] = 4;
            //T
            tetrisOffset[5] = new List <SceneOffset>();
            tetrisOffset[5].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 1, X2 = 2, Y2 = 1, X3 = 3, Y3 = 1, X4 = 2, Y4 = 2
            });
            tetrisOffset[5].Add(new SceneOffset()
            {
                X1 = 2, Y1 = 0, X2 = 1, Y2 = 1, X3 = 2, Y3 = 1, X4 = 2, Y4 = 2
            });
            tetrisOffset[5].Add(new SceneOffset()
            {
                X1 = 2, Y1 = 1, X2 = 1, Y2 = 2, X3 = 2, Y3 = 2, X4 = 3, Y4 = 2
            });
            tetrisOffset[5].Add(new SceneOffset()
            {
                X1 = 1, Y1 = 0, X2 = 1, Y2 = 1, X3 = 1, Y3 = 2, X4 = 2, Y4 = 1
            });
            changeNum[5] = 4;

            for (int i = 0; i < tetrisOffset.Length; i++)
            {
                localOffset[i] = new List <SceneOffset>();
                for (int j = 0; j < tetrisOffset[i].Count; j++)
                {
                    SceneOffset offset = tetrisOffset[i][j];
                    localOffset[i].Add(new SceneOffset()
                    {
                        X1 = 0, Y1 = 0, X2 = offset.X2 - offset.X1, Y2 = offset.Y2 - offset.Y1, X3 = offset.X3 - offset.X1, Y3 = offset.Y3 - offset.Y1, X4 = offset.X4 - offset.X1, Y4 = offset.Y4 - offset.Y1
                    });
                }
            }
        }