上一篇本人已经写了一个控制台小游戏,这次使用Winform来生成可连通的地图,并测试运行游戏

迷宫小游戏控制台

一、先更改控制台游戏的一点点代码,用于测试迷宫是否连通的【即:从起点可以到达终点】。只用更改 MazeUtil.cs的查找路径方法FindPath()。用于返回是否连通。

整体更改后的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MazeDemo
{
    /// <summary>
    /// 迷宫可以认为是一个N*M的行列式,也可以认为是一个二维数组,每个元素都是一个单元格MazeGrid
    /// </summary>
    public class MazeUtil
    {
        /// <summary>
        /// 使用一个障碍墙的二维数组来初始化迷宫地图
        /// </summary>
        /// <param name="wallArray">数组元素的值为1时,代表障碍墙,否则是可通过的</param>
        public MazeUtil(int[,] wallArray)
        {
            if (wallArray == null || wallArray.Length == 0)
            {
                throw new Exception("初始化数组不能为空");
            }
            Width = wallArray.GetLength(0);
            Height = wallArray.GetLength(1);
            //初始化地图
            MazeArray = new MazeGrid[Width, Height];
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    MazeArray[i, j] = new MazeGrid(i, j, wallArray[i, j] == 1);
                }
            }
            CurrentGrid = MazeArray[0, 0];
            TargetGrid = MazeArray[Width - 1, Height - 1];
        }
        /// <summary>
        /// 迷宫的宽度,也就是二维数组的行数【注意:行数对应纵坐标Y】
        /// </summary>
        public int Width { get; set; }
        /// <summary>
        /// 迷宫的高度,也就是二维数组的列数【注意:列数对应横坐标X】
        /// </summary>
        public int Height { get; set; }
        /// <summary>
        /// 迷宫行列式,由 Width*Height 个网格组成
        /// </summary>
        public MazeGrid[,] MazeArray { get; set; }

/// <summary>
        /// 当前网格,起点默认为左上角,即 MazeGrid[0,0]
        /// </summary>
        public MazeGrid CurrentGrid { get; set; }

/// <summary>
        /// 终点:目标网格,默认为右下角,即 MazeGrid[Width-1,Height-1]
        /// </summary>
        public MazeGrid TargetGrid { get; set; }

/// <summary>
        /// 栈,用于存储移动的路径:找到一个 未访问的 并且 不是障碍,就Push()入栈
        /// </summary>
        public Stack<MazeGrid> stack = new Stack<MazeGrid>();

/// <summary>
        /// 以此遍历当前网格的上、右、下、左四个方向。
        /// 如果遇到障碍 或者 已访问过,就尝试其他方向。否则就把 无障碍 并且 未访问的网格作为新的网格
        /// </summary>
        /// <param name="mazeGrid"></param>
        public void MoveNext(MazeGrid mazeGrid)
        {
            Direction direction = Direction.All;
            //按照上、右、下、左【顺时针】顺序以此遍历,当遍历完左Left后,则全部遍历完成,此时置方向为All
            switch (mazeGrid.Direction)
            {
                case Direction.None://当是None时,默认向上Up遍历
                    mazeGrid.Direction = Direction.Up;
                    direction = Direction.Up;
                    break;
                case Direction.Up://当是Up时,接着向右Right遍历
                    mazeGrid.Direction = Direction.Right;
                    direction = Direction.Right;
                    break;
                case Direction.Right://当是Right时,接着向下Down遍历
                    mazeGrid.Direction = Direction.Down;
                    direction = Direction.Down;
                    break;
                case Direction.Down://当是Down时,接着向左Left遍历
                    mazeGrid.Direction = Direction.Left;
                    direction = Direction.Left;
                    break;
                case Direction.Left://当是Left时,说明四个方向全部遍历完了,置为All
                    mazeGrid.Direction = Direction.All;
                    direction = Direction.All;
                    break;
            }

//对上、右、下、左四个方向进行处理【None 和 All不做处理】
            switch (direction)
            {
                case Direction.Up:
                    if (mazeGrid.RowIndex - 1 >= 0)
                    {
                        MazeGrid upGrid = MazeArray[mazeGrid.RowIndex - 1, mazeGrid.ColumnIndex];
                        if (!upGrid.IsWall && !upGrid.IsVisited)
                        {
                            //如果不是障碍 并且 没有访问过
                            CurrentGrid = upGrid;
                        }
                        else
                        {
                            //尝试其他方向
                            MoveNext(CurrentGrid);
                        }
                    }
                    break;
                case Direction.Right:
                    if (mazeGrid.ColumnIndex + 1 < Height)
                    {
                        MazeGrid rightGrid = MazeArray[mazeGrid.RowIndex, mazeGrid.ColumnIndex + 1];
                        if (!rightGrid.IsWall && !rightGrid.IsVisited)
                        {
                            //如果不是障碍 并且 没有访问过
                            CurrentGrid = rightGrid;
                        }
                        else
                        {
                            //尝试其他方向
                            MoveNext(CurrentGrid);
                        }
                    }
                    break;
                case Direction.Down:
                    if (mazeGrid.RowIndex + 1 < Width)
                    {
                        MazeGrid downGrid = MazeArray[mazeGrid.RowIndex + 1, mazeGrid.ColumnIndex];
                        if (!downGrid.IsWall && !downGrid.IsVisited)
                        {
                            //如果不是障碍 并且 没有访问过
                            CurrentGrid = downGrid;
                        }
                        else
                        {
                            //尝试其他方向
                            MoveNext(CurrentGrid);
                        }
                    }
                    break;
                case Direction.Left:
                    if (mazeGrid.ColumnIndex - 1 >= 0)
                    {
                        MazeGrid leftGrid = MazeArray[mazeGrid.RowIndex, mazeGrid.ColumnIndex - 1];
                        if (!leftGrid.IsWall && !leftGrid.IsVisited)
                        {
                            //如果不是障碍 并且 没有访问过
                            CurrentGrid = leftGrid;
                        }
                        else
                        {
                            //尝试其他方向
                            MoveNext(CurrentGrid);
                        }
                    }
                    break;
            }
        }

/// <summary>
        /// 查找路径,返回起点到终点是否是可连通的
        /// </summary>
        /// <returns>true:可以到达终点,false:无法到达终点</returns>
        public bool FindPath()
        {
            //如果当前网格没有移动到目标网格。
            bool existPath = true;
            //这里如果遇到无法到达目标网格的障碍地图时,需要终止
            while (CurrentGrid != TargetGrid)
            {
                if (CurrentGrid.IsVisited)
                {
                    //如果当前网格全部访问完成,则出栈
                    if (CurrentGrid.Direction == Direction.All)
                    {
                        if (stack.Count > 0)
                        {
                            stack.Pop();//移除最后一次添加的
                        }
                        if (stack.Count > 0)
                        {
                            //获取倒数第二次添加的
                            CurrentGrid = stack.Peek();
                        }
                        else
                        {
                            Console.WriteLine("无路可走,请检查迷宫障碍设置...");
                            existPath = false;
                            break;
                        }
                    }
                    else
                    {
                        //没有遍历完,继续遍历
                        MoveNext(CurrentGrid);
                    }
                }
                else
                {
                    //如果未访问,则设置为已访问,同时添加入栈
                    CurrentGrid.IsVisited = true;
                    stack.Push(MazeArray[CurrentGrid.RowIndex, CurrentGrid.ColumnIndex]);     
                }
            }
            //将目标网格添加到顶部
            if (stack.Count > 0)
            {
                stack.Push(TargetGrid);
            }
            return existPath;
        }

/// <summary>
        /// 打印路径
        /// </summary>
        public void PrintPath()
        {
            if (stack.Count == 0)
            {
                Console.WriteLine("无法到达目的网格,请检查迷宫地图设置...");
                return;
            }
            //因第一个插入的元素是入口,栈是先进后出,入口反而成为最后元素。这里进行反转
            IEnumerable<MazeGrid> grids = stack.Reverse();
            foreach (MazeGrid item in grids)
            {
                Console.WriteLine(item);
            }
        }
    }
}
二、新建Windows窗体应用程序MazeTest,添加对MazeDemo控制台程序的引用。将MazeTest设为启动项目。然后将默认的Form1窗体重命名为FormMaze。窗体设置宽度为1054, 高度为606。操作面板panel1的位置Location

窗体设计如下图:

为窗体的重绘Paint绑定事件方法FormMaze_Paint(),Init按钮绑定事件btnInit_Click(),上、下、左、右绑定事件btnDirection_Click。同时重写键盘事件ProcessCmdKey,对上下左右方向键进行相应处理。

三、FormMaze.cs整体代码如下(忽略设计器自动生成的代码):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MazeDemo;

namespace MazeTest
{
    public partial class FormMaze : Form
    {
        /// <summary>
        /// 初始化设置障碍墙
        /// </summary>
        static int[,] wallArray = new int[5, 6] { { 0, 0, 1, 0, 0, 0 }, { 0, 1, 0, 1, 0, 0 }, { 0, 1, 0, 0, 0, 1 }, { 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 1, 0, 0 } };
        MazeUtil mazeUtil = new MazeUtil(wallArray);
        public FormMaze()
        {
            InitializeComponent();

//使用双缓冲来减少图形闪烁(当绘制图片时出现闪烁时,使用双缓冲)
            this.DoubleBuffered = true;//设置本窗体启用双缓冲
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); //禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); //双缓冲
        }

/// <summary>
        /// 处理windows消息:禁掉清除背景消息
        /// 主要是处理部分控件使用双缓冲也会闪烁的现象
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0014) // 禁掉清除背景消息
                return;
            base.WndProc(ref m);
        }

/// <summary>
        /// 重写键盘事件,对上下左右方向键进行相应处理
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Up:
                    btnDirection_Click(btnUp, null);
                    break;
                case Keys.Right:
                    btnDirection_Click(btnRight, null);
                    break;
                case Keys.Down:
                    btnDirection_Click(btnDown, null);
                    break;
                case Keys.Left:
                    btnDirection_Click(btnLeft, null);
                    break;
            }
            return false;//如果要调用KeyDown,这里一定要返回false才行,否则只响应重写方法里的按键.
            //这里调用一下父类方向,相当于调用普通的KeyDown事件.如果按空格会弹出两个对话框
            //return base.ProcessCmdKey(ref msg, keyData);
            //return true;//这里return true 否则控件焦点会跟着方向键改变
        }
        private void FormMaze_Load(object sender, EventArgs e)
        {
            this.AutoScroll = true;
            rtxbDisplay.ReadOnly = true;
        }

/// <summary>
        /// 上下左右方向移动事件【四个方向按钮都绑定该事件】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDirection_Click(object sender, EventArgs e)
        {
            Button button = sender as Button;
            //MessageBox.Show(mazeUtil.CurrentGrid+",行数:"+ mazeUtil.Width+",列数:"+ mazeUtil.Height);
            switch (button.Name)
            {
                case "btnUp":
                    if (mazeUtil.CurrentGrid.RowIndex - 1 < 0)
                    {
                        //使用系统声音报警
                        System.Media.SystemSounds.Beep.Play();
                        //Asterisk:星号,引起注意,重要的声音
                        //Beep:操作无效的声音
                        //Exclamation:感叹声 打开某个文件的声音
                        //Hand:手动处理的声音
                        //Question
                    }
                    else
                    {
                        MazeGrid nextGrid = mazeUtil.MazeArray[mazeUtil.CurrentGrid.RowIndex - 1, mazeUtil.CurrentGrid.ColumnIndex];
                        if (nextGrid.IsWall)
                        {
                            //障碍,报警
                            System.Media.SystemSounds.Asterisk.Play();
                        }
                        else
                        {
                            mazeUtil.CurrentGrid = nextGrid;
                            this.Invalidate();//触发paint事件
                            //update,repaint,invalid
                        }
                    }
                    break;
                case "btnRight":
                    if (mazeUtil.CurrentGrid.ColumnIndex + 1 >= mazeUtil.Height)
                    {
                        //使用系统声音报警
                        System.Media.SystemSounds.Beep.Play();
                    }
                    else
                    {
                        MazeGrid nextGrid = mazeUtil.MazeArray[mazeUtil.CurrentGrid.RowIndex, mazeUtil.CurrentGrid.ColumnIndex + 1];
                        if (nextGrid.IsWall)
                        {
                            //障碍,报警
                            System.Media.SystemSounds.Asterisk.Play();
                        }
                        else
                        {
                            mazeUtil.CurrentGrid = nextGrid;
                            this.Invalidate();//触发paint事件
                        }
                    }
                    break;
                case "btnDown":
                    if (mazeUtil.CurrentGrid.RowIndex + 1 >= mazeUtil.Width)
                    {
                        //使用系统声音报警
                        System.Media.SystemSounds.Beep.Play();
                    }
                    else
                    {
                        MazeGrid nextGrid = mazeUtil.MazeArray[mazeUtil.CurrentGrid.RowIndex + 1, mazeUtil.CurrentGrid.ColumnIndex];
                        if (nextGrid.IsWall)
                        {
                            //障碍,报警
                            System.Media.SystemSounds.Asterisk.Play();
                        }
                        else
                        {
                            mazeUtil.CurrentGrid = nextGrid;
                            this.Invalidate();//触发paint事件
                        }
                    }
                    break;
                case "btnLeft":
                    if (mazeUtil.CurrentGrid.ColumnIndex - 1 < 0)
                    {
                        //使用系统声音报警
                        System.Media.SystemSounds.Beep.Play();
                    }
                    else
                    {
                        MazeGrid nextGrid = mazeUtil.MazeArray[mazeUtil.CurrentGrid.RowIndex, mazeUtil.CurrentGrid.ColumnIndex - 1];
                        if (nextGrid.IsWall)
                        {
                            //障碍,报警
                            System.Media.SystemSounds.Asterisk.Play();
                        }
                        else
                        {
                            mazeUtil.CurrentGrid = nextGrid;
                            this.Invalidate();//触发paint事件
                        }
                    }
                    break;
            }
            if (mazeUtil.CurrentGrid == mazeUtil.TargetGrid)
            {
                DisplayContent("已到达迷宫终点,真棒!");
                mazeUtil.CurrentGrid = mazeUtil.MazeArray[0, 0];
                MessageBox.Show("已到达迷宫终点,真棒!", "成功");
            }
        }

private void btnInit_Click(object sender, EventArgs e)
        {
            int rowCount;//行数
            int columnCount;//列数
            if (!CheckInputCount(txbRowCount, "行数", out rowCount))
            {
                return;
            }
            if (!CheckInputCount(txbColumnCount, "列数", out columnCount))
            {
                return;
            }
            wallArray = new int[rowCount, columnCount];
            DisplayContent("正在生成随机地图,请稍候...");

//异步生成地图
            GenerateConnectableMap(rowCount, columnCount);
            //重绘迷宫,新的开始
            mazeUtil.CurrentGrid = mazeUtil.MazeArray[0, 0];
            mazeUtil.stack.Clear();
            this.Invalidate();
        }

/// <summary>
        /// 生成可连通的地图【从起点可以到达终点】。因行数、列数较大时。寻找出可连通地图的耗时较长。
        /// 会造成界面假死,这里增加异步处理耗时任务
        /// </summary>
        /// <param name="rowCount"></param>
        /// <param name="columnCount"></param>
        public void GenerateConnectableMap(int rowCount, int columnCount)
        {
            TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
            Task<bool> task = tcs.Task;
            //这里进行耗时操作
            System.Threading.ThreadPool.QueueUserWorkItem(waitCallback => 
            {
                //这里执行耗时任务:寻找到一个可连通的地图
                System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();
                bool existPath = false;
                do
                {
                    //注意:起始点、终点一定不是墙。定义 随机0或1的随机数
                    for (int i = 0; i < rowCount; i++)
                    {
                        for (int j = 0; j < columnCount; j++)
                        {
                            if ((i == 0 && j == 0) || (i == rowCount - 1 && j == columnCount - 1))
                            {
                                //起点、终点一定为0,不考虑随机数。其他点随机
                                continue;
                            }
                            wallArray[i, j] = new Random(Guid.NewGuid().GetHashCode()).Next(0, 2);
                        }
                    }
                    mazeUtil = new MazeUtil(wallArray);
                    existPath = mazeUtil.FindPath();
                    //如果起点、终点不是连通的,则重新随机设计地图
                } while (!existPath);
                stopwatch.Stop();
                DisplayContent($"生成随机地图成功,用时【{stopwatch.ElapsedMilliseconds}】ms.新的一局开始");
                //一旦对 TaskCompletionSource 调用 SetResult 方法,相关联的 Task 便会结束,返回 Task 的结果值
                tcs.SetResult(existPath);
            });
            task.Wait(10000);
            DisplayContent($"耗时任务结果:【{task.Result}】.");
        }

/// <summary>
        /// 显示文本框内容
        /// </summary>
        /// <param name="message"></param>
        private void DisplayContent(string message)
        {
            this.BeginInvoke(new Action(() => 
            {
                if (rtxbDisplay.TextLength > 10240)
                {
                    rtxbDisplay.Clear();
                }
                rtxbDisplay.AppendText(message + "\n");
                rtxbDisplay.ScrollToCaret();
            }));
        }

/// <summary>
        /// 检查输入
        /// </summary>
        /// <param name="txb"></param>
        /// <param name="commentStr"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        private bool CheckInputCount(TextBox txb, string commentStr, out int count)
        {
            if (!int.TryParse(txb.Text, out count))
            {
                MessageBox.Show($"[{commentStr}]请输入正整数", "错误");
                txb.Focus();
                return false;
            }
            if (count <= 0 || count >= 100)
            {
                MessageBox.Show($"[{commentStr}]范围是【1~99】,请重新输入", "错误");
                txb.Focus();
                return false;
            }
            return true;
        }

/// <summary>
        /// 窗体的重绘事件,调用Invalidate()会触发重绘事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormMaze_Paint(object sender, PaintEventArgs e)
        {
            int sideLength = 50;//正方形【迷宫的一个网格MazeGrid】的边长。
            float fontSize = 13;//打印的起点、终点文字的字体大小
            //以边长为50为例:因当前窗体的高度为606,去除窗体顶部和底部的高度【约56】,只能正常显示11行。因Panel控件的横坐标为705,因此只能显示14列。
            if (mazeUtil.Width <= 11 && mazeUtil.Height <= 14)
            {
                sideLength = 50;
                fontSize = 13;
            }
            else if (mazeUtil.Width <= 22 && mazeUtil.Height <= 28)
            {
                //如果行数在22行之内,列数在28列之内,则将网格的边长设置25
                sideLength = 25;
                fontSize = 8;
            }
            else
            {
                //如果行数、列数过大(行数大于22,列数大于28)。则应该将界面变大,并增加滚动条
                sideLength = 25;
                fontSize = 8;
                if (mazeUtil.Width > 22)
                {
                    this.Height = this.Height + (mazeUtil.Width - 22) * sideLength;
                }
                if (mazeUtil.Height > 28)
                {
                    this.Width = this.Width + (mazeUtil.Height - 28) * sideLength;
                    //Panel操作面板要整体向右移动,即X坐标增加
                    panel1.Location = new Point(panel1.Location.X + (mazeUtil.Height - 28) * sideLength, panel1.Location.Y);
                }
            }
            Graphics graphics = e.Graphics;
            for (int i = 0; i < mazeUtil.Width; i++)
            {
                for (int j = 0; j < mazeUtil.Height; j++)
                {
                    //注意:第一行是Y坐标没变,X坐标在变化。因此i是纵坐标 j是横坐标
                    Rectangle rect = new Rectangle(sideLength * j, sideLength * i, sideLength, sideLength);
                    graphics.DrawRectangle(new Pen(Color.Red), rect);
                    if (mazeUtil.MazeArray[i, j].IsWall)
                    {
                        graphics.FillRectangle(new SolidBrush(Color.Black), rect);
                    }
                    //如果不是起点,也不是终点,并且是当前移动到节点
                    else if ((i != 0 || j != 0) && (i != mazeUtil.Width - 1 || j != mazeUtil.Height - 1)
                        && mazeUtil.MazeArray[i, j] == mazeUtil.CurrentGrid)
                    {
                        graphics.FillRectangle(new SolidBrush(Color.Yellow), rect);
                    }
                }
            }
            //起点设置为蓝色
            Rectangle rectStart = new Rectangle(0, 0, sideLength, sideLength);
            graphics.FillRectangle(new SolidBrush(Color.Blue), rectStart);            
            AddTextAlignCenter(graphics, "起点", new Font("宋体", fontSize), rectStart);
            //终点设置为红色
            Rectangle rectEnd = new Rectangle(sideLength * (mazeUtil.Height - 1), sideLength * (mazeUtil.Width - 1), sideLength, sideLength);
            graphics.FillRectangle(new SolidBrush(Color.Red), rectEnd);
            AddTextAlignCenter(graphics, "终点", new Font("宋体", fontSize), rectEnd);
        }

/// <summary>
        /// 将显示的文字放在矩形的中间
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="text"></param>
        /// <param name="font"></param>
        /// <param name="rect"></param>
        private void AddTextAlignCenter(Graphics graphics, string text, Font font, Rectangle rect)
        {
            SizeF sizeF = graphics.MeasureString(text, font);
            float destX = rect.X + (rect.Width - sizeF.Width) / 2;
            float destY = rect.Y + (rect.Height - sizeF.Height) / 2;
            graphics.DrawString(text, font, Brushes.Black, destX, destY);
        }        
    }
}

四:程序运行如下图

设置10行12列,点击初始化Init

可以点击按钮上下左右,也可以按键盘的方向键上下左右。到边界或障碍墙将会有警告提示音。

成功如图:

C#迷宫Winform小游戏,生成可连通的迷宫地图相关推荐

  1. python迷宫小游戏代码_C++课程设计迷宫小游戏

    温馨提示 程序语言: C . C++ . C# . Python ( 红色字体 表示本课设使用的 程序设计语言 ) 图形功能选项: Win32 控制台程序(黑框.文本界面) . Win32 程序. M ...

  2. python迷宫小游戏大全_C课程设计迷宫小游戏

    DOC 格式 . 温馨提示 程序语言: C . C++ . C# . Python ( 红色字体 表示本课设使用的 程序设计语言 ) 图形功能选项: Win32 控制台程序 (黑框. 文本界面) . ...

  3. 【Pygame小游戏】Python版有迷宫嘛?原来藏在个地方呀~

  4. 基于Java的迷宫小游戏

    一.实验内容: 1)迷宫游戏是非常经典的游戏,在该题中要求随机生成一个迷宫,并求解迷宫: 2) 要求查找并理解迷宫生成的算法,并尝试用两种不同的算法来生成随机的迷宫. 要求迷宫游戏支持玩家走迷宫,和系 ...

  5. 【C语言小游戏】——老鼠走迷宫

    一.效果图展示 我们来实现一个小游戏,就是老鼠走迷宫,效果图如下所示: 二.数据结构分析 首先,我们先来分析一下数据结构. 1.迷宫地图--它是有一个字符型二维数组并初始化构成的,障碍显示为'#',道 ...

  6. 【神奇的Turtle库】海龟在手—天下我有:这款秘制“海龟闯关”小游戏值得拥有,强烈推荐哦~

    导语 哈喽!大家好!我是木木子~ 纵观之前的文章--我发现了一个特点,很多小伙伴儿都喜欢学习Turtle或游戏代码,没错吧~ 那今天这篇文章就是为这2方面的小伙伴儿精心准备滴!Turtle+游戏一起安 ...

  7. 小游戏 Untrusted 推荐及攻略

    Untrusted 是 Berkeley 的Alex Nisnevich 和 Greg Shuflin 开发的一款改代码走迷宫的小游戏,需要玩家利用超凡的想象力,在阅读相关API和给出的部分代码之后在 ...

  8. python小游戏之三

    猜拳游戏 Python代码实现猜拳小游戏 Python代码实现猜拳小游戏_zhangtongyuan0909的博客-CSDN博客_python猜拳游戏代码 用python中类与对象写一个猜拳游戏 用p ...

  9. C++ 小游戏-球球飞车

    C++ 小游戏-球球飞车 功能实现 地图随机生成 彩色界面打印 按键检测 存档 商店 运行截图 核心代码展示 地图生成: void rand_map(int a,int pd) {srand(time ...

  10. 基于C++控制台(Windows平台)的一个吃豆人小游戏

    PacManX --南京大学2019秋季学期 "高级程序设计 "课程设计一 基于C++控制台(Windows平台)的一个吃豆人小游戏 已实现的目标: 地图支持自定义编辑(可编辑地图 ...

最新文章

  1. 中国式姥姥上热搜感动无数人:有妈妈在,我才敢生娃
  2. [JLOI2011]飞行路线
  3. format 转化时间格式不起作用
  4. 提高调试.net cf程序效率一些技巧
  5. exec函数族实例解析
  6. springboot 实现接口灰度发布
  7. requests获取响应时间(elapsed)与超时(timeout)
  8. 1009 C语言 SUM problem
  9. python统计各分数段人数并可根据选择绘制不同的图形_python习题整理
  10. IC卡读写器VB.NET源代码
  11. Spring全家桶+分布式微服务(十次方)
  12. acs510使用技巧_ABBACS510系列变频器通用接线图和参数表【借鉴实操】
  13. 油管youtube第三方客户端 去广告-TubeMax
  14. php 微信推送提醒,php实现微信模板消息推送
  15. 埃默里大学有计算机专业吗,埃默里大学计算机专业申请需要满足哪些条件?
  16. elastic-job监控平台ElasticJob-UI的使用
  17. 【面试题】深复制与浅复制的区别
  18. 今晚直播 |不诉离殇,图像分割打卡营正式毕业啦!
  19. K-Means聚类算法的实现(C语言)
  20. unity接入声网音频sdk

热门文章

  1. SQL 语句单引号、双引号的用法
  2. hdu-5064(dp)
  3. 到底游戏中有什么是让你沉迷游戏的呢
  4. Pr_cc 学习笔记(二)鬼畜剪辑
  5. 多重共线性的产生原因、判别、检验、解决方法
  6. 数据库中间件DBLE学习(一) 基本介绍和快速搭建
  7. 网络安全知识竞赛(国家信息安全水平考试NISP)模拟题1
  8. Chrome V8让你更懂JavaScript
  9. 第一次参加本校大学生创新创业训练项目答辩的反思与总结
  10. 更改已生成的exe文件的ico图标