コード例 #1
0
ファイル: Program.cs プロジェクト: analog-hors/MinoBot
        public static void DrawTetrisBoard(RenderTarget target, Vector2f pos, Tetris tetris, TetrisRNG rng, IEnumerable <TetriminoState> moves, TetriminoState move)
        {
            void DrawTetrimino(Tetrimino mino, int x, int y, int rot)
            {
                tetrisRect.FillColor = cellColors[(byte)mino.type];
                for (int i = mino.states.GetLength(1) - 1; i >= 0; i--)
                {
                    Pair <sbyte> block = mino.states[rot, i];
                    DrawCell(target, block.x + x, block.y + y, pos);
                }
            }

            for (int y = 0; y < 20; y++)
            {
                for (int x = 0; x < 10; x++)
                {
                    tetrisRect.FillColor = cellColors[(byte)tetris.GetCell(x, y + 20)];
                    if (tetrisRect.FillColor == Color.Black)
                    {
                        tetrisRect.OutlineThickness = 1;
                    }
                    DrawCell(target, x + 5, y, pos);
                    if (tetrisRect.FillColor == Color.Black)
                    {
                        tetrisRect.OutlineThickness = 0;
                    }
                }
            }
            if (moves != null)
            {
                Vector2f origScale     = tetrisRect.Scale;
                Vector2f fifthScale    = new Vector2f(0.20f, 0.20f);
                Vector2f twoFifthScale = fifthScale * 2;
                tetrisRect.Scale = fifthScale;
                foreach (TetriminoState m in moves)
                {
                    if (m.Equals(move))
                    {
                        tetrisRect.Scale = twoFifthScale;
                    }
                    DrawTetrimino(tetris.current, m.x + 5, m.y - 20, m.rot);
                    if (m.Equals(move))
                    {
                        tetrisRect.Scale = fifthScale;
                    }
                }
                tetrisRect.Scale = origScale;
            }
            //DrawTetrimino(tetris.current, move.x + 5, move.y - 20, move.rot);
            DrawTetrimino(tetris.current, tetris.pieceX + 5, tetris.pieceY - 20, tetris.pieceRotation);
            if (tetris.hold != null)
            {
                DrawTetrimino(tetris.hold, 1, 1, 0);
            }
            for (int x = 0; x < 5; x++)
            {
                DrawTetrimino(rng.GetPiece(x), 17, 1 + 4 * x, 0);
            }
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: analog-hors/MinoBot
        static void Main(string[] args)
        {
            window             = new RenderWindow(new VideoMode(300, 300), "MinoBot GUI", Styles.Close);
            window.Closed     += OnClose;
            window.KeyPressed += OnKeyPressed;
            window.SetActive();
            //window.SetFramerateLimit(60);
            //Thread.Sleep(5000);

            TetrisRNG tetRNG = new TetrisRNG(3);

            //while (tetRNG.GetPiece(0) != Tetrimino.T) tetRNG.NextPiece();
            tetris = new Tetris(tetRNG);
            TetrisDrawer.SetScale(new Vector2f(window.Size.X / 20, window.Size.Y / 20));
            pathfinder = new Pathfinder();
            TetrisBot bot = new TetrisBot(tetris);

            moves = pathfinder.FindAllMoves(tetris, 1, 1, 1);
            long   totalThinkMS     = 0;
            long   totalThinks      = 0;
            double totalNodeScore   = 0;
            int    totalSimulations = 0;
            int    totalDepth       = 0;
            int    totalNodes       = 0;
            int    movesMade        = 0;

            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();
            Random             rng     = new Random(2);
            IEnumerator <Move> path    = null;
            TetriminoState     move    = new TetriminoState(-1, -1, 0);
            TetriminoState     invalid = new TetriminoState();

            while (window.IsOpen)
            {
                window.DispatchEvents();
                if (stopWatch.ElapsedMilliseconds > 50)
                {
                    if (path != null)
                    {
                        if (path.MoveNext())
                        {
                            Pathfinder.DoMove(tetris, path.Current);
                        }
                        else
                        {
                            tetris.HardDrop();
                            path  = null;
                            moves = pathfinder.FindAllMoves(tetris, 1, 1, 1);
                            move  = invalid;
                        }
                        window.Clear();
                        TetrisDrawer.DrawTetrisBoard(window, new Vector2f(0, 0), tetris, tetRNG, moves, move);
                        window.Display();
                    }
                    else
                    {
                        if (move.x != -1)
                        {
                            bot.Update(tetris);
                        }
                        int       thinks    = 0;
                        Stopwatch stopwatch = new Stopwatch();
                        Task      thinkTask = Task.Run(() => {
                            stopwatch.Start();
                            while (stopwatch.ElapsedMilliseconds < 100)
                            {
                                bot.Think();
                                thinks += 1;
                            }
                            stopWatch.Stop();
                        });
                        while (!thinkTask.IsCompleted)
                        {
                            window.DispatchEvents();
                        }
                        if (thinkTask.Exception != null)
                        {
                            throw thinkTask.Exception;
                        }
                        MinoBot.MonteCarlo.Node node = bot.GetMove();
                        long elapsed = stopwatch.ElapsedMilliseconds;
                        totalThinkMS     += elapsed;
                        totalThinks      += thinks;
                        totalNodeScore   += node.score;
                        totalSimulations += node.simulations;
                        totalDepth       += bot.maxDepth;
                        int nodes = 0;

                        /*
                         * Queue<MinoBot.MonteCarlo.Node> nodeQueue = new Queue<MinoBot.MonteCarlo.Node>();
                         * nodeQueue.Enqueue(bot.tree.root);
                         * while (nodeQueue.TryDequeue(out MinoBot.MonteCarlo.Node n)) {
                         *  foreach (MinoBot.MonteCarlo.Node child in n.children) {
                         *      nodeQueue.Enqueue(child);
                         *  }
                         *  nodes += 1;
                         * }
                         */
                        totalNodes += nodes;
                        movesMade  += 1;

                        /*
                         * Console.Clear();
                         * Console.WriteLine($"Move {movesMade}.");
                         * Console.WriteLine($"Thought for {elapsed}ms (avg: {totalThinkMS / (double) movesMade})");
                         * Console.WriteLine($"{thinks} thinks (avg: {totalThinks / (double) movesMade})");
                         * Console.WriteLine($"{elapsed / (double) thinks } ms per think (avg: {totalThinkMS / (double) totalThinks})");
                         * Console.WriteLine($"Depth: {bot.maxDepth} (avg: {totalDepth / (double) movesMade}).");
                         * Console.WriteLine($"Nodes: {nodes} (avg: {totalNodes / (double )movesMade})");
                         * Console.WriteLine("Selected node has:");
                         * Console.WriteLine($"  score: {node.score} (avg: {totalNodeScore / movesMade})");
                         * Console.WriteLine($"  simulations: {node.simulations} (avg: {totalSimulations / (double) movesMade})");
                         */
                        move = node.move;
                        if (node.state.usesHeld)
                        {
                            tetris.Hold();
                            moves = pathfinder.FindAllMoves(tetris, 1, 1, 1);
                        }
                        pathfinder.FindAllMoves(tetris, 1, 1, 1);
                        List <Move> pathList = pathfinder.GetPath(move.x, move.y, move.rot);

                        /*
                         * Console.Clear();
                         * //Console.WriteLine(move.x + ", " + move.y + ", " + move.rot);
                         * foreach (Move mv in pathList) {
                         *  Console.WriteLine(Enum.GetName(mv.GetType(), mv));
                         * }
                         */
                        path = pathList.GetEnumerator();
                    }
                    stopWatch.Restart();
                }
            }
        }