コード例 #1
0
 private bool CanReachInOneOrTwoCWRotations(Tetrimino tetrimino, Tetrimino target)
 {
     for (int i = 0; i < 2; i++)
     {
         tetrimino = tetrimino.RotateCW();
         if (tetrimino.Equals(target))
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #2
0
 private bool WrongTetrimino(Tetrimino tetrimino, Tetrimino target)
 {
     for (int i = 0; i < 4; i++)
     {
         if (tetrimino.Equals(target))
         {
             return(false);
         }
         tetrimino = tetrimino.RotateCW();
     }
     return(true);
 }
コード例 #3
0
        public DropResult drop(Tetrimino tetrimino, int leftCol)
        {
            int minNewTopTetriminoRow = 999;

            for (int x = 0; x < tetrimino.Width; x++)
            {
                int tetriminoBottomRow = 0;
                for (int y = tetrimino.Height - 1; y >= 0; y--)
                {
                    if (tetrimino.TetriminoArray[y, x])
                    {
                        tetriminoBottomRow = y;
                        break;
                    }
                }
                int curCol = leftCol + x;

                int boardTopRow        = GetTopRowInColumn(curCol);
                int newTopTetriminoRow = boardTopRow - tetriminoBottomRow - 1;
                minNewTopTetriminoRow = Math.Min(minNewTopTetriminoRow, newTopTetriminoRow);
            }

            Board r = new Board(this);

            for (int i = 0; i < tetrimino.Height; i++)
            {
                for (int j = 0; j < tetrimino.Width; j++)
                {
                    if (tetrimino.TetriminoArray[i, j])
                    {
                        if (minNewTopTetriminoRow + i < 0)
                        {
                            return(null);
                        }
                        r.BoardArray[minNewTopTetriminoRow + i, leftCol + j] = true;
                    }
                }
            }
            r.Penalty = Penalty;
            int linesCleared = r.ClearFullRows();

            return(new DropResult(r, linesCleared));
        }
コード例 #4
0
ファイル: GameState.cs プロジェクト: devedse/DeveTetris99Bot
 public GameState(Board board, TetriminoWithPosition fallingTetrimino, List <Tetrimino> nextTetriminoes, Tetrimino tetriminoInStash, bool thereIsDanger)
 {
     Board            = board;
     NextTetriminoes  = nextTetriminoes;
     FallingTetrimino = fallingTetrimino;
     TetriminoInStash = tetriminoInStash;
     ThereIsDanger    = thereIsDanger;
 }
コード例 #5
0
        public void MakeMove(List <Move> moves)
        {
            foreach (var move in moves)
            {
                switch (move)
                {
                case Move.Left:
                    curBlockWithPos.LeftCol--;
                    break;

                case Move.Right:
                    curBlockWithPos.LeftCol++;
                    break;

                case Move.Drop:
                    var previousBord = board;
                    var result       = board.drop(curBlockWithPos.Tetrimino, curBlockWithPos.LeftCol);

                    board         = result.Board;
                    linesCleared += result.LinesCleared;

                    linesClearedLabel.Invoke(new Action(() =>
                    {
                        linesClearedLabel.Text = linesCleared.ToString();
                    }));

                    if (result.LinesCleared != 0)
                    {
                        RedrawComplete();
                        //DrawDifferences(result.Board, previousBord);
                    }
                    else
                    {
                        //RedrawComplete();
                        DrawDifferences(result.Board, previousBord);
                    }

                    cur++;
                    RedetectBlocks();
                    break;

                case Move.Stash:
                    var tmp = inStash;
                    inStash = curBlockWithPos.Tetrimino;
                    if (tmp == null)
                    {
                        cur++;
                        RedetectBlocks();
                    }
                    else
                    {
                        curBlockWithPos = new TetriminoWithPosition(tmp, 0, 4);
                    }
                    break;

                case Move.Rotate_CW:
                    curBlockWithPos.Tetrimino = curBlockWithPos.Tetrimino.RotateCW();
                    break;

                case Move.Rotate_CWW:
                    curBlockWithPos.Tetrimino = curBlockWithPos.Tetrimino.RotateCW();
                    curBlockWithPos.Tetrimino = curBlockWithPos.Tetrimino.RotateCW();
                    curBlockWithPos.Tetrimino = curBlockWithPos.Tetrimino.RotateCW();
                    break;

                case Move.Enter:
                    break;

                default:
                    break;
                }
            }
        }
コード例 #6
0
        public void Play()
        {
            gameStateReader.Starting();

            while (true)
            {
                var gameState = gameStateReader.ReadGameState();

                if (Broken(gameState))
                {
                    Thread.Sleep(500);
                    continue;
                }

                if (gameState.ThereIsDanger)
                {
                    Evaluator.MaxHeight = 19;
                }
                else
                {
                    Evaluator.MaxHeight = 4;
                }

                //Console.WriteLine(gameState.Board);
                //Console.WriteLine(string.Join(";", gameState.NextTetriminoes));
                var twp = gameState.FallingTetrimino;
                if (twp == null)
                {
                    continue;
                }

                Tetrimino tetrimino = twp.Tetrimino;
                if (target == null || WrongTetrimino(target.Tetrimino, tetrimino))
                {
                    target = bestMoveFinder.FindBestMove(gameState, twp, stashAllowed);
                    if (target == null)
                    {
                        continue;
                    }
                }

                var moves = new List <Move>();
                if (target.Stash)
                {
                    moves.Add(Move.Stash);
                    target       = null;
                    stashAllowed = false;
                }
                else
                {
                    if (!tetrimino.Equals(target.Tetrimino))
                    {
                        if (CanReachInOneOrTwoCWRotations(tetrimino, target.Tetrimino))
                        {
                            moves.Add(Move.Rotate_CW);
                        }
                        else
                        {
                            moves.Add(Move.Rotate_CWW);
                        }
                    }
                    if (target.Column > twp.LeftCol)
                    {
                        moves.Add(Move.Right);
                    }
                    else if (target.Column < twp.LeftCol)
                    {
                        moves.Add(Move.Left);
                    }
                    if (moves.Count == 0)
                    {
                        moves.Add(Move.Drop);
                        target       = null;
                        stashAllowed = true;
                    }
                }

                //foreach (var move in moves)
                //{
                //    Console.WriteLine($"Making move: {move}");
                //}
                keyPresser.MakeMove(moves);

                //Console.WriteLine(target);
                //Console.WriteLine("------");
            }
        }
コード例 #7
0
        public void MakeMove(List <Move> moves)
        {
            foreach (var move in moves.Take(1))
            {
                int    linesClearedNow = 0;
                string keyToPress      = null;

                switch (move)
                {
                case Move.Left:
                    //tetris99Form.CurrentSerialConnection.SendButtonPress("LH");
                    keyToPress = "LH";
                    curBlockWithPos.LeftCol--;
                    break;

                case Move.Right:
                    //tetris99Form.CurrentSerialConnection.SendButtonPress("RH");
                    keyToPress = "RH";
                    curBlockWithPos.LeftCol++;
                    break;

                case Move.Drop:
                    var previousBord = board;
                    var result       = board.drop(curBlockWithPos.Tetrimino, curBlockWithPos.LeftCol);

                    board           = result.Board;
                    linesCleared   += result.LinesCleared;
                    linesClearedNow = result.LinesCleared;

                    linesClearedLabel.Invoke(new Action(() =>
                    {
                        linesClearedLabel.Text = linesCleared.ToString();
                    }));

                    if (result.LinesCleared != 0)
                    {
                        //RedrawComplete();
                        //DrawDifferences(result.Board, previousBord);
                    }
                    else
                    {
                        //RedrawComplete();
                        //DrawDifferences(result.Board, previousBord);
                    }

                    keyToPress = "UH";
                    //tetris99Form.CurrentSerialConnection.SendButtonPress("UH");

                    cur++;
                    RedetectBlocks();

                    //DrawCurrentBlock();


                    //Thread.Sleep(500);
                    break;

                case Move.Stash:
                    var tmp = inStash;
                    inStash    = curBlockWithPos.Tetrimino;
                    keyToPress = "7";
                    //tetris99Form.CurrentSerialConnection.SendButtonPress("7");
                    if (tmp == null)
                    {
                        cur++;
                        RedetectBlocks();
                        //Thread.Sleep(500);
                    }
                    else
                    {
                        curBlockWithPos = new TetriminoWithPosition(tmp, 2, 3 + (tmp.Width == 2 ? 1 : 0));
                    }
                    break;

                case Move.Rotate_CW:
                    keyToPress = "2";
                    //tetris99Form.CurrentSerialConnection.SendButtonPress("2");
                    Rotate();
                    break;

                case Move.Rotate_CWW:
                    keyToPress = "1";
                    //tetris99Form.CurrentSerialConnection.SendButtonPress("1");
                    Rotate();
                    Rotate();
                    Rotate();
                    break;

                case Move.Enter:
                    break;

                default:
                    break;
                }



                RedrawComplete();
                DrawCurrentBlock();
                DrawNextBlocks();

                bool thereWasDanger = DetectIfThereIsDanger();

                if (thereWasDanger)
                {
                    gDanger.Clear(Color.Red);
                    dangerCountLabel.Invoke(new Action(() =>
                    {
                        dangerCountLabel.Text = _lastDetectedDanger.ToString();
                    }));
                }
                else
                {
                    gDanger.Clear(Color.Green);
                }

                if (!string.IsNullOrWhiteSpace(keyToPress))
                {
                    var timeToWait = (int)Math.Max(0, minTimeToWait - _timeSinceLastKeyPress.Elapsed.TotalMilliseconds);
                    if (timeToWait > 0)
                    {
                        Thread.Sleep(timeToWait);
                    }

                    minTimeToWait = FrameDurationHelper.ToFrameDuration(3);

                    tetris99Form.CurrentSerialConnection.SendButtonPress(keyToPress, false);
                    _timeSinceLastKeyPress.Restart();
                    if (keyToPress == "UH")
                    {
                        //If other players spawn shit, we need to wait for the animation
                        if (thereWasDanger)
                        {
                            minTimeToWait = FrameDurationHelper.ToFrameDuration(33 + _lastDetectedDanger * 4);
                        }
                        else
                        {
                            minTimeToWait = FrameDurationHelper.ToFrameDuration(8);
                        }
                    }
                    if (linesClearedNow > 0)
                    {
                        //Theres no more danger now
                        _lastDanger   = DateTime.MinValue;
                        _lastNoDanger = DateTime.Now;

                        minTimeToWait = FrameDurationHelper.ToFrameDuration(48);
                    }
                }
            }
        }