コード例 #1
0
ファイル: TetrisAI.cs プロジェクト: BCProgramming/BASeTris
        public static IEnumerable <StoredBoardState> GetPossibleResults(NominoBlock[][] Source, Nomino bg, StoredBoardState.BoardScoringRuleData rules)
        {
            //Debug.Print("Calculating possible results:" + Source.Sum((u)=>u.Count((y)=>y!=null)) + " Non null entries.");
            for (int useRotation = 0; useRotation < 4; useRotation++)
            {
                for (int x = -5; x < Source[0].Length + 5; x++)
                {
                    if (rules.StupidFactor < 1)
                    {
                        if (TetrisGame.rgen.NextDouble() < rules.StupidFactor)
                        {
                            continue;
                        }
                    }
                    Nomino cloneFor = new Nomino(bg);
                    foreach (var resetblock in cloneFor)
                    {
                        resetblock.Block = new StandardColouredBlock();
                    }

                    int XOffset = x - bg.X;
                    StoredBoardState BuildState = new StoredBoardState(Source, cloneFor, XOffset, useRotation);
                    if (!BuildState.InvalidState)
                    {
                        yield return(BuildState);
                    }
                }
            }
        }
コード例 #2
0
ファイル: TetrisAI.cs プロジェクト: BCProgramming/BASeTris
        private void PushButtonInputs(StoredBoardState sbs)
        {
            for (int i = 0; i < sbs.RotationCount; i++)
            {
                PressKeyQueue.Enqueue(GameState.GameKeys.GameKey_RotateCW);
            }

            if (sbs.XOffset < 0)
            {
                for (int i = 0; i < Math.Abs(sbs.XOffset); i++)
                {
                    PressKeyQueue.Enqueue(GameState.GameKeys.GameKey_Left);
                }
            }
            else if (sbs.XOffset > 0)
            {
                for (int i = 0; i < Math.Abs(sbs.XOffset); i++)
                {
                    PressKeyQueue.Enqueue(GameState.GameKeys.GameKey_Right);
                }
            }

            for (int i = 0; i < 5; i++)
            {
                PressKeyQueue.Enqueue(GameState.GameKeys.GameKey_Null);
            }
            PressKeyQueue.Enqueue(GameState.GameKeys.GameKey_Drop);
        }
コード例 #3
0
ファイル: TetrisAI.cs プロジェクト: BCProgramming/BASeTris
        public override void AIActionFrame()
        {
            //do our hard thinking here.
            //first we only do stuff with the standard game state.
            if (_Owner == null)
            {
                return;
            }
            if (_Owner.CurrentState is GameplayGameState)
            {
                GameplayGameState stdState = _Owner.CurrentState as GameplayGameState;
                //next, we only want to do stuff if there is one active blockgroup...
                if (stdState.PlayField.GetActiveBlockGroups().Count == 1)
                {
                    //todo: we want to copy the playfield for our inspection here... we'll want to see what happens based on moving the blockgroup left or right up to each side and dropping it and evaluate the result to select the ideal
                    //then slap those keys into the queue.
                    Nomino ActiveGroup    = stdState.PlayField.BlockGroups[0];
                    var    PossibleStates = GetPossibleResults(stdState.PlayField.Contents, ActiveGroup, ScoringRules).ToList();

                    Debug.Print("Found " + PossibleStates.Count + " possible states...");
                    var Sorted = (ScoringRules.Moronic?PossibleStates.OrderByDescending((w) => TetrisGame.rgen.Next()):  PossibleStates.OrderByDescending((w) => w.GetScore(stdState.GameHandler.GetType(), ScoringRules))).ToList();

                    //var Scores = (from p in PossibleStates orderby p.GetScore(ScoringRules) descending select new Tuple<StoredBoardState, double>(p, p.GetScore(ScoringRules))).ToArray();

                    /*foreach (var writedebug in Scores)
                     * {
                     *  Debug.Print("Possible State: Move " + writedebug.Item1.XOffset + ", Rotate " + writedebug.Item1.RotationCount + " To get score " + writedebug.Item1.GetScore(ScoringRules));
                     *  Debug.Print("What it will look like\n" + writedebug.Item1.GetBoardString());
                     *  Debug.Print("------");
                     * }*/

                    var maximumValue = Sorted.FirstOrDefault();
                    Debug.Print("Best Move: Move " + maximumValue.XOffset + ", Rotate " + maximumValue.RotationCount + " To get score " + maximumValue.GetScore(stdState.GameHandler.GetType(), ScoringRules));
                    Debug.Print("What it will look like\n" + maximumValue.GetBoardString());
                    Debug.Print("------");

                    //int randomint = TetrisGame.rgen.Next(Scores.Length);
                    //int randomint2 = TetrisGame.rgen.Next(Scores.Length);
                    //StoredBoardState FirstState = Scores[randomint2].Item1;
                    StoredBoardState IdealState = maximumValue;
                    PushButtonInputs(IdealState);
                    //if(maximumValue!=null)
                    //{
                    //    PushButtonInputs(maximumValue);
                    //}
                }
            }
        }
コード例 #4
0
        public double CalculateScore(StoredBoardState.BoardScoringRuleData data, StoredBoardState state)
        {
            StoredBoardState.DrMarioScoringRuleData dat = data as StoredBoardState.DrMarioScoringRuleData;

            var FieldColumnScore = GetFieldColumnScore(dat, state);

            Debug.Print("Field Column Score:" + FieldColumnScore);
            double MassScore = 0;

            foreach (var iterate in FindMasses(dat, state))
            {
                int    VirusCount = (from c in iterate.MassContents where c is LineSeriesPrimaryBlock select c).Count();
                double AddScore   = ((double)VirusCount) * dat.MasterBlockMassValue + iterate.MassSize;
                MassScore += AddScore;
            }
            return(FieldColumnScore + MassScore); //basically random, I think.
            //throw new NotImplementedException();
        }
コード例 #5
0
        public double CalculateScore(BoardScoringRuleData Data, StoredBoardState state)
        {
            var Rules     = Data as TetrisScoringRuleData;
            int Rows      = GetCompletedLines(state.State);
            int Aggregate = GetAggregateHeight(state.State);
            int Holes     = GetHoles(state.State);
            int Bumpy     = GetBumpiness(state.State);
            int Crevice   = GetCrevasses(state.State);
            //Debug.Print("Rows=" + Rows + " Aggregate=" + Aggregate + " Holes=" + Holes + " Bumps=" + Bumpy);
            //double a = -0.610066f;
            //double b = 0.760666;
            //double c = -0.55663;
            ////double d = -.184483;
            //double d = -.384483;
            double CreviceScore = (Rules.CrevasseScore * (double)Crevice);

            return((Rules.AggregateHeightScore * (double)Aggregate) +
                   (Rules.RowScore * (double)Rows) +
                   (Rules.HoleScore * (double)Holes) +
                   (Rules.BumpinessScore * (double)Bumpy) +
                   CreviceScore);
        }
コード例 #6
0
        private IEnumerable <LineSeriesBlock> FindHorizontalMass(StoredBoardState.DrMarioScoringRuleData data, StoredBoardState state, int pRow, int pCol, LineSeriesBlock.CombiningTypes MatchingIndex, List <LineSeriesBlock> InConsiderables)
        {
            int CurrR = pRow, CurrC = pCol;

            //look to the left
            while (state.State[CurrR][CurrC] is LineSeriesBlock lsb && lsb.CombiningIndex == MatchingIndex && CurrC > 0)
            {
                CurrC--;
            }
            int FirstC = CurrC;
            int CheckC = FirstC;

            if (CurrC != FirstC)
            {
                //we have a horizontal group. let's grab the blocks.
                while (state.State[CurrR][CheckC] is LineSeriesBlock lsb && lsb.CombiningIndex == MatchingIndex && CurrC < state.ColCount - 1)
                {
                    if (InConsiderables.Contains(lsb))
                    {
                        break;
                    }
                    CheckC++;
                    yield return(lsb);
                }
            }
        }
コード例 #7
0
        public double GetFieldColumnScore(StoredBoardState.DrMarioScoringRuleData data, StoredBoardState state)
        {
            List <List <double> > AllColumnRuns = new List <List <double> >();

            for (int c = 0; c < state.ColCount; c++)
            {
                List <double> ColumnRuns     = new List <double>();
                int           CurrentRun     = 0;
                int           MasterCount    = 0;
                int           Interfacecount = 0; //number of changes.
                bool          ResetHandled   = false;
                LineSeriesBlock.CombiningTypes?currentType = null;
                for (int r = 0; r < state.RowCount; r++)
                {
                    ResetHandled = false;
                    if (state.State[r][c] is LineSeriesBlock lsb)
                    {
                        if (state.State[r][c] is LineSeriesPrimaryBlock)
                        {
                            MasterCount++;
                        }
                        if (currentType == null)
                        {
                            currentType = lsb.CombiningIndex;
                        }
                        if (currentType == lsb.CombiningIndex)
                        {
                            CurrentRun++;
                        }
                        else if (currentType != lsb.CombiningIndex)
                        {
                            Interfacecount++;
                            ResetHandled = true;
                            ColumnRuns.Add(CurrentRun * ((MasterCount + 1) * data.MasterBlockColumnMultiplier));
                            CurrentRun  = 1;
                            MasterCount = 0;
                            currentType = lsb.CombiningIndex;
                        }
                    }
                }
                if (!ResetHandled)
                {
                    ColumnRuns.Add(CurrentRun * ((MasterCount + 1) * data.MasterBlockColumnMultiplier));
                }

                AllColumnRuns.Add(ColumnRuns);
            }
            //want longer runs, but, we also want to avoid stacking colours on top of unmatched colours, so we give weight to
            //the number of scores we accumulated in the row.
            return((from co in AllColumnRuns select(co.Sum() - (co.Count * co.Count))).Sum());
        }
コード例 #8
0
        //DrMario Scoring:
        //Lines are worthless, obviously
        //Critical Masses add lots of value
        //groups of the same colour add value
        //additionally, columns of a colour with only air in-between as well as possible colour drops
        //(if the bottom colour of a stuck stack fell as far as it could would line up with other of the same colour

        public IEnumerable <MassItem> FindMasses(StoredBoardState.DrMarioScoringRuleData data, StoredBoardState state)
        {
            List <LineSeriesBlock> ConsideredResults = new List <LineSeriesBlock>();


            for (int r = 0; r < state.RowCount; r++)
            {
                for (int c = 0; c < state.ColCount; c++)
                {
                    if (state.State[r][c] is LineSeriesBlock lsb)
                    {
                        //check for a mass here.
                        var HorizontalMass = FindHorizontalMass(data, state, r, c, lsb.CombiningIndex, ConsideredResults).ToList();
                        var VerticalMass   = FindVerticalMass(data, state, r, c, lsb.CombiningIndex, ConsideredResults).ToList();
                        ConsideredResults.Add(lsb);
                        if (HorizontalMass.Count > 1)
                        {
                            MassItem HorzMass = new MassItem(HorizontalMass);
                            yield return(HorzMass);
                        }
                        if (VerticalMass.Count > 1)
                        {
                            MassItem VertMass = new MassItem(VerticalMass);
                            yield return(VertMass);
                        }
                    }
                }
            }
        }
コード例 #9
0
        private IEnumerable <LineSeriesBlock> FindVerticalMass(StoredBoardState.DrMarioScoringRuleData data, StoredBoardState state, int pRow, int pCol, LineSeriesBlock.CombiningTypes MatchingIndex, List <LineSeriesBlock> InConsiderables)
        {
            int CurrR = pRow, CurrC = pCol;

            //look above.
            while (state.State[CurrR][CurrC] is LineSeriesBlock lsb && lsb.CombiningIndex == MatchingIndex && CurrR > 0)
            {
                CurrR--;
            }
            int FirstR = CurrR;
            int CheckR = FirstR;

            if (CurrR != FirstR)
            {
                //we have a vertical group. Lets see what blocks. So from the starting point,
                //check each block until air, or until we see a different coloured block OR we reach the other side of the stage.
                while (state.State[CheckR][CurrC] is LineSeriesBlock lsb && lsb.CombiningIndex == MatchingIndex && CurrC < state.ColCount - 1)
                {
                    if (InConsiderables.Contains(lsb))
                    {
                        break;
                    }
                    CheckR++;
                    yield return(lsb);
                }
            }
        }