0

我必须在我的 A-Level 程序中演示 Lambdas/Actions/Delegates 的使用,以使其更加复杂。我知道如何制作它们以及(某种)它们做什么,但不知道何时使用它们。

任何人都可以让我知道在我的代码中我可以使用其中一个、两个或所有这些吗?我不确定这是否是合适的地方,如果不是,请告诉我。

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

//Command-Line Arguements for SizeX and SizeY

namespace prjT02L08_Predator_Prey
{
    public partial class frmSim : Form
    {
        Point GridSize; //Creates a pair of X and Y co-ordinates
        Random r = new Random(); //Used for any random number needed in the program
        float FoodSpawnChance = 50; //The chance that food has of spawning
        int SimTick = 0; //How long the program has been running for
        int ImageScale = 7; //How much to scale the bitmap grid up for displaying
        int SizeX = 60; //The number of pixels on the X axis
        int SizeY = 60; //The number of pixels on the Y axis

    bool StepDone = true; //Has one update of the simulation happened?

    public frmSim() //Main constructor method
    {
        InitializeComponent();

        GridSize = new Point(SizeX, SizeY); //Sets the size of the grid using the size of the X and Y axis
        AStar.Grid = Node.MakeGrid(GridSize.X, GridSize.Y, 10);

        for (int i = 0; i < 10; i++)
            new Mitosis(r.Next(0, SizeX) /*Produces a random number between 0 and the size of the X axis*/,
                r.Next(0, SizeY)/*Random number between 0 and the size of the Y axis*/); //Adds new Mitosis bacteria for the first time

        for (int i = 0; i < 8; i++)
            new Meiosis(r.Next(0, SizeX), r.Next(0, SizeY)); //Adds new Meiosis bacteria for the first time
        chkNaturalSpawn.Checked = true; //Sets the food's natural spawn to true, so it randomly spawns
    }

    private void UpdateSim() //Updates the whole simulation
    {
        UpdateVars(); //Updates all the variables in the simulation

        if (SimTick == 20) //If the simulation has run for 20 ticks,
            for (int i = 0; i < 10; i++)
                new VirusP(1, 1); //Creates a new virus at the X position 1, and Y position 1

        if (chkNaturalSpawn.Checked == true) //If natural spawning has been selected
            SpawnFood(); //then try to spawn food

        Entity.UpdateAll(SimTick); //Updates all entities
    }

    private void UpdateVars() //Updates all the variables in the simulation
    {
        SimTick++; //Each timer tick, this variable is incremented
        tmrSimClock.Interval = trcInterval.Value; //The gap between ticks is set based of the trackbar (Which has been reversed right-to-left)

        if (chkNaturalSpawn.Checked == true) //Checks if natural food spawning is enabled
            FoodSpawnChance = trcFoodSpawn.Value; //then if true, sets the chance of food spawning to the value of the trackbar

        VirusP.DoubleStepChance = trcPred2Step.Value; //The chance of the Virus moving two places instead of one is set of the trackbar
    }

    private void SpawnFood() //Attempts to spawn food at a random location
    {
        //Chance to spawn based on FoodSpawnChance variable
        if (r.Next(0, 1000) < (FoodSpawnChance * 100)) //Uses a random number to determine whether food can spawn or not
        {
            int x = r.Next(0, GridSize.X); //Sets the value of x to a random number between 0 and the value of the Gridsize.X
            int y = r.Next(0, GridSize.Y); //Sets the value of y to a random number between 0 and the value of the Gridsize.Y

            if (!AStar.Grid[x, y].IsWall) //Checks if the random position chosen isn't a wall
                new Food(x, y); //then if true, food is spawned at that position

        }
    }

    private void frmSim_Load(object sender, EventArgs e)
    {

    }

    private void btnStep_Click(object sender, EventArgs e)
    {
        if (StepDone == true) //Checks if the previous update from this button has already been completed or not - Prevents slow down
        {
            StepDone = false;
            UpdateSim(); //Updates the simulation once
            DrawSim(); //Redraws the bitmap image to show a visual update
            StepDone = true;
        }
    }

    private void DrawSim() //Creates the bitmap of the grid which is dispalyed on the screen and scales it up
    {
        Bitmap bmp = new Bitmap(GridSize.X, GridSize.Y); //Creates the bitmap specifying the width and height of it
        //These two for loops loop through every part of the grid:
        for (int x = 0; x < GridSize.X; x++) //For every value in the height of the grid
        {
            for (int y = 0; y < GridSize.Y; y++)//and every value in the width of the grid
            {
                Color Colour = Color.Black; //Creates a new color used to set the pixel colour on the bitmap (Empty space is black)

                foreach (Entity e in Entity.GetEntitiesAt(x, y)) //For every entity a the current location...
                {
                    if ((e as Food) != null) //If it is Food, set the colour to green
                        Colour = Color.FromArgb(Colour.R, 255, Colour.B);
                    else if ((e as Mitosis) != null) //If it is bacteria Mitosis, set the colour to blue
                        Colour = Color.FromArgb(Colour.R, Colour.G, 255);
                    else if ((e as Meiosis) != null) //If it is bacteria Meiosis, set the colour to gold
                        Colour = Color.Gold;
                    else //If it's none of these, the only entity left is the Virus, set the colour to red
                        Colour = Color.FromArgb(255, Colour.G, Colour.B);
                }

                if (AStar.Grid[x, y].IsWall) //If that location is a wall, set the colour to white
                    Colour = Color.White;

                bmp.SetPixel(x, y, Colour); //Set the pixel at position x and y to the colour chosen above
            }
        }

        //Scales up the bitmap into a new bitmap
        Bitmap bmpscale = new Bitmap(GridSize.X * ImageScale, GridSize.Y * ImageScale);
        for (int x = 0; x < GridSize.X; x++)
        {
            for (int y = 0; y < GridSize.Y; y++)
            {
                for (int sx = 0; sx < ImageScale; sx++)
                {
                    for (int sy = 0; sy < ImageScale; sy++)
                    {
                        bmpscale.SetPixel(((x * ImageScale) + sx), ((y * ImageScale) + sy), bmp.GetPixel(x, y));
                    }
                }
            }
        }

        this.CreateGraphics().DrawImage(bmpscale, new Point(10, 10)); //Draws the bitmap image at set co-ordinates on the form
    }

    private void tmrSimClock_Tick(object sender, EventArgs e) //Every time the timer updates
    {
        UpdateSim(); //Updates the simulation
        DrawSim(); //Redraws the simulation
    }

    private void btnRun_Click(object sender, EventArgs e)
    {
        tmrSimClock.Enabled = !tmrSimClock.Enabled; //Put timer in opposite state
        btnStep.Enabled = !btnStep.Enabled; //Put button in opposite state

        if (tmrSimClock.Enabled)
            btnRun.Text = "Running...";
        else
            btnRun.Text = "Run";
    }

    private void btnReset_Click(object sender, EventArgs e)
    {
        Entity.Entities = new List<Entity>(); //Recreates the list of entitites
        SimTick = 0; //Restarts the simulation timer
        tmrSimClock.Enabled = false; //Turns the timer off
        for (int i = 0; i < 10; i++)//Recreates entities Mitosis and Meiosis
        {
            new Mitosis(r.Next(0, SizeX), r.Next(0, SizeY));
            new Meiosis(r.Next(0, SizeX), r.Next(0, SizeY));
        }
        btnRun.Text = "Run";
    }

    private void chkNaturalSpawn_CheckedChanged(object sender, EventArgs e)
    {
        lblFood.Enabled = chkNaturalSpawn.Checked == true ? true : false; //Turnery Statement
        trcFoodSpawn.Enabled = chkNaturalSpawn.Checked == true ? true : false; //If checked is true, return true, else return false
    }
}
}
4

1 回答 1

1

首先,我必须同意乔恩的观点:先把它整理好。这是通过将操作用作匿名委托/lambda 函数来使用 lambda 的示例。你可能不得不摆弄它才能让它工作

private void traverseBmp(Action<int, int> doIt)
    {
        for (int x = 0; x < GridSize.X; x++) //For every value in the height of the grid
        {
            for (int y = 0; y < GridSize.Y; y++)//and every value in the width of the grid
            {
                doIt(x, y);
            }
        }

    private void DrawSim() //Creates the bitmap of the grid which is dispalyed on the screen and scales it up
    {
        Bitmap bmp = new Bitmap(GridSize.X, GridSize.Y); //Creates the bitmap specifying the width and height of it
        //These two for loops loop through every part of the grid:
        traverseBmp((x, y) =>
            {
                Color Colour = Color.Black;
                    //Creates a new color used to set the pixel colour on the bitmap (Empty space is black)

                foreach (Entity e in Entity.GetEntitiesAt(x, y)) //For every entity a the current location...
                {
                    if ((e as Food) != null) //If it is Food, set the colour to green
                        Colour = Color.FromArgb(Colour.R, 255, Colour.B);
                    else if ((e as Mitosis) != null) //If it is bacteria Mitosis, set the colour to blue
                        Colour = Color.FromArgb(Colour.R, Colour.G, 255);
                    else if ((e as Meiosis) != null) //If it is bacteria Meiosis, set the colour to gold
                        Colour = Color.Gold;
                    else //If it's none of these, the only entity left is the Virus, set the colour to red
                        Colour = Color.FromArgb(255, Colour.G, Colour.B);
                }

                if (AStar.Grid[x, y].IsWall) //If that location is a wall, set the colour to white
                    Colour = Color.White;

                bmp.SetPixel(x, y, Colour); //Set the pixel at position x and y to the colour chosen above
            });

        //Scales up the bitmap into a new bitmap
        Bitmap bmpscale = new Bitmap(GridSize.X * ImageScale, GridSize.Y * ImageScale);
        traverseBmp((x,y) =>
            {
                for (int sx = 0; sx < ImageScale; sx++)
                {
                    for (int sy = 0; sy < ImageScale; sy++)
                    {
                        bmpscale.SetPixel(((x*ImageScale) + sx), ((y*ImageScale) + sy), bmp.GetPixel(x, y));
                    }
                }
            });

        this.CreateGraphics().DrawImage(bmpscale, new Point(10, 10)); //Draws the bitmap image at set co-ordinates on the form
    }
于 2013-08-30T15:23:16.667 回答