예제 #1
0
        //Runs a simulation with a given piece of scoring data, and board width and height, and runs one simulated game using that scoring for AI determination and
        //returns a valuation of the resulting gameplay using the scoring algorithm with those weights.
        public static double RunSimulation(StoredBoardState.TetrisScoringRuleData scoredata, int BoardWidth = 10, int BoardHeight = 22)
        {
            Debug.Print($"--------Running Simulation " + scoredata.ToString() + "-----");

            //create the chooser.
            BlockGroupChooser bgc           = new BagChooser(Tetromino.StandardTetrominoFunctions);
            List <Nomino>     ChosenNominos = new List <Nomino>();


            NominoBlock[][] Contents = new NominoBlock[TetrisField.DEFAULT_ROWCOUNT][];
            for (int row = 0; row < TetrisField.DEFAULT_ROWCOUNT; row++)
            {
                Contents[row] = new NominoBlock[TetrisField.DEFAULT_COLCOUNT];
            }
            int  Placedpieces = 0;
            int  rowsFinished = 9;
            bool GameEnded    = false;
            int  nominoCount  = 0;

            while (!GameEnded)
            {
                //get the next Nomino.
                var nextNomino = bgc.RetrieveNext();
                ChosenNominos.Add(nextNomino);
                //Debug.Print("Processing new Nomino:" + nextNomino.SpecialName);
                var PossibleBoardResults = StandardNominoAI.GetPossibleResults(Contents, nextNomino, scoredata);
                //score each one based on the scoring rules.
                var BestScore = (from p in PossibleBoardResults orderby p.GetScore(typeof(GameStates.GameHandlers.StandardTetrisHandler), scoredata) descending select p).FirstOrDefault();
                if (BestScore != null)
                {
                    // we go with the best scoring value of course.
                    Contents = BestScore.State;

                    String NewStateString = BestScore.GetBoardString();
                    //Debug.Print("Found best score location for new Nomino. Board State:");
                    //Debug.Print("\n\n" + NewStateString);
                    Placedpieces++;
                }

                int RemoveLines = RemoveFinishedRows(ref Contents);
                rowsFinished += (RemoveLines * RemoveLines); //square it, reason is to give higher scores for AI that manages to land more multi-line clears.
                //if the top line has a block than we will consider it Game Ended.
                if (Contents[0].Any((r) => r != null))
                {
                    GameEnded = true;
                }
            }
            //Debug.Print("Final Score:" +rowsFinished + Placedpieces);
            //Debug.Print($"----------------Completed Simulation Bumpiness:{scoredata.BumpinessScore}, Height:{scoredata.AggregateHeightScore}, Hole:{scoredata.HoleScore}, Row:{scoredata.RowScore} --------");
            return(rowsFinished + Placedpieces); //return score for this simulation.
        }
예제 #2
0
        public StoredBoardState(NominoBlock[][] InitialState, Nomino pGroup, int pXOffset, int pRotationCount)
        {
            RowCount      = InitialState.GetUpperBound(0);
            ColCount      = InitialState[0].GetUpperBound(0);
            _BoardState   = StandardNominoAI.DuplicateField(InitialState);
            _SourceGroup  = new Nomino(pGroup);
            XOffset       = pXOffset;
            RotationCount = pRotationCount;
            foreach (var resetblock in _SourceGroup)
            {
                resetblock.Block = new StandardColouredBlock();
            }


            for (int i = 0; i < RotationCount; i++)
            {
                _SourceGroup.Rotate(false);
            }
            //move the Nomino by the specified offset...

            _SourceGroup.RecalcExtents();

            /*
             * if(_SourceGroup.GroupExtents.Left+_SourceGroup.X+XOffset < 0 || _SourceGroup.GroupExtents.Right+XOffset+_SourceGroup.X > _BoardState[0].Length)
             * {
             *  InvalidState = true; //nothing else to do- this is an invalid state as the move puts us "off" the board.
             * }
             * else*/
            {
                //get our board state...
                try
                {
                    DropBlock(_SourceGroup, ref _BoardState, pXOffset);
                }
                catch (Exception exx)
                {
                    InvalidState = true;
                    return;
                }
            }
        }