Hello everyone,

I'm trying to make a kind of log in system for an application. It's pretty simple. There are 6 picture boxes which display images. Of these 6 picture boxes one of the images is a recognizable to the user. When the user clicks on the 'correct' image the process basically repeats two more times. After the third time the user successfully gets to use the application.

So overall there will be 18 images, 3 will be 'important' and 15 will be stub images. So one of these important images needs to show up once and only once on each form attempt. The images that show up on each form should show up only once as well.

I've got a decent implementation in which I scramble my pictures but can't seem to figure out:

1) How do I make sure one of these important images shows up randomly between picture boxes 0-5, 6-11, and 12-17?
2) When I accomplish this how do I distinguish/identify the recognizable images in my form? I want to use the PictureBox.Tag property but not sure I would give a tag based on these. I was thinking I could use the image name..but that would probably be bad security.

public class randomImage
	{
		int[] indexArray;
		string[] stubImages; 
		string[] specialImages;
		
		public randomImage()
		{	
			//holds indexes..shuffled in shuffleArray()
			indexArray = new int[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
			//Holds the stub images
			stubImages = new string[] 
{"Image1.jpg","Image2.jpg",								  "Image3.jpg","Image4.jpg","Image5.jpg",			                      "Image6.jpg","Image7.jpg","Image8.jpg",			                      "Image9.jpg","Image10.jpg","Image11.jpg",			                      "Image12.jpg","Image13.jpg","Image14.jpg",
			                      "Image15.jpg"};
			//these are the 'special images'
			specialImages = new string[]{"Special1.jpg","Special2.jpg","Special3.jpg"};
			shuffleArray();
			
		}
		private void shuffleArray()
		{
  			Random rnd = new Random();
			
  			//scrambles array
  			for (int inx = indexArray.Length-1; inx > 0; inx--)
  			{
  		                int position = rnd.Next(inx+1);
    			        int temp = indexArray[inx];
    			        indexArray[inx] = indexArray[position];
                               indexArray[position] = temp;
  			}
		}
		public string returnImage(int index)
		{
			return stubImages[indexArray[index]];
		}
		
	}

I'd appreciate any suggestions or improvements.

Here's my form code:

protected void drawPicBoxes()
{
			
	int xStart = 50,
	     yStart = 25, 
             nextLine = 0;
			
	    for(int i = 0; i < 6; i++)
	   {
		   picBox = new PictureBox();
		  this.picBox.Size = new Size(175,175);
		  this.picBox.Location = new Point(xStart,yStart);
		  this.picBox.Click += new 
                 System.EventHandler(this.picBox_Click );
		
                 try
		{
			this.picBox.Image = 
                        Image.FromFile(getImage.returnImage(i));
		}
		catch(Exception e)
		{
			 System.Windows.Forms.MessageBox.Show(e.ToString());
		}
		this.Controls.Add(picBox);
		xStart += 225;
		nextLine++;
				
		if(nextLine == 2)
		{
			xStart = 50;
			yStart += 220;
			nextLine = 0;
		}
	}
 }
		private void picBox_Click(object sender, System.EventArgs e )
        {
			//redraw the pictureboxes with new images
        }

This should do the trick:

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;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;

namespace daniweb.images
{
  public partial class Form1 : Form
  {
    private List<Bitmap> special;
    private List<Bitmap> stub;
    private List<LoginImage[]> sets;
    private int currentSet;

    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      LoadSet(0);
      //int i1 = GetRandom(5);
      //MessageBox.Show(i1.ToString());
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      special = new List<Bitmap>();
      stub = new List<Bitmap>();
      sets = new List<LoginImage[]>();

      for (int repeat = 0; repeat < 3; repeat++)
      {
        for (int i1 = 0; i1 < 6; i1++)
        {
          if (i1 == 0)
          {
            string name = string.Format("Special {0:F0}", (repeat + 1));
            special.Add(ConvertTextToBitmap(name, Color.Green, Brushes.White));
          }
          else
          {
            stub.Add(ConvertTextToBitmap(Guid.NewGuid().ToString(), Color.Black, Brushes.White));
          }
        }
      }
      //You now have 3 special and 15 stubs
      RunScrambler();
      currentSet = 0;
      LoadSet(currentSet);
    }

    private void RunScrambler()
    {
      //Generate 3 sets
      sets.Clear();
      List<int> specialIndexList = new List<int>();
      List<int> stubIndexList = new List<int>();
      specialIndexList.AddRange(GetRange(0, special.Count - 1));
      stubIndexList.AddRange(GetRange(0, stub.Count - 1));
      for (int i1 = 0; i1 < 3; i1++)
      {
        List<LoginImage> set = new List<LoginImage>();
        int specialIdx = GetRandom(specialIndexList.Count - 1);
        set.Add(new LoginImage(special[specialIndexList[specialIdx]], true));
        specialIndexList.RemoveAt(specialIdx);

        for (int i2 = 0; i2 < 5; i2++)
        {
          int stubIdx = GetRandom(stubIndexList.Count - 1);
          set.Add(new LoginImage(stub[stubIndexList[stubIdx]], false));
          stubIndexList.RemoveAt(stubIdx);
        }
        sets.Add(set.ToArray());
      }
    }

    private void LoadSet(int set)
    {
      if ((set < 0) || (set > 2))
        throw new ArgumentOutOfRangeException("set", "Must be between 0 and 2");
      
      List<LoginImage> images = sets[set].ToList();
      for (int i1 = 1; i1 <= 6; i1++)
      {
        PictureBox pb = (this.Controls.Find("pictureBox" + i1.ToString(), true)[0] as PictureBox);
        int idx = GetRandom(images.Count - 1);
        Bitmap bmp = images[idx].Image;
        pb.Image = bmp;
        pb.Tag = images[idx];
        images.RemoveAt(idx);
      }
    }

    public Bitmap ConvertTextToBitmap(string str, Color textColor, Brush recColor)
    {
      const int height = 50;
      const int width = 50;

      Bitmap bmp = new Bitmap(width, height);
      {
        using (Graphics gfx = Graphics.FromImage((Image)bmp))
        {
          gfx.SmoothingMode = SmoothingMode.AntiAlias;
          Font font = new Font(this.Font.Name, 11, FontStyle.Regular, GraphicsUnit.Pixel);
          gfx.FillRectangle(Brushes.Transparent, new Rectangle(0, 0, bmp.Width, bmp.Height));
          gfx.FillRectangle(recColor, 0, 0, width, height);
          gfx.DrawString(str, font, new SolidBrush(textColor), 2, 3);
          return bmp;
        }
      }
    }

    public static int GetRandom(int Maxvalue)
    {
      if (Maxvalue == 0)
        return 0;
      byte[] randomNumber = new byte[1];
      System.Security.Cryptography.RNGCryptoServiceProvider Gen = new System.Security.Cryptography.RNGCryptoServiceProvider();
      Gen.GetBytes(randomNumber);
      int rand = Convert.ToInt32(randomNumber[0]);
      return rand % Maxvalue;
    }
    private static int[] GetRange(int min, int max)
    {
      List<int> result = new List<int>();
      for (int i1 = min; i1 <= max; i1++)
      {
        result.Add(i1);
      }
      return result.ToArray();
    }

    private void pictureBox1_Click(object sender, EventArgs e)
    {
      LoginImage img = (LoginImage)((sender as PictureBox).Tag);
      if (img.Correct)
      {
        if (currentSet == 2)
        {
          MessageBox.Show("Login complete");
        }
        else
        {
          LoadSet(++currentSet);
        }
      }
      else
      {
        MessageBox.Show("Login failed. Try again");
        currentSet = 0;
        LoadSet(currentSet);
      }
    }
  }

  public class LoginImage
  {
    public Bitmap Image { get; set; }
    public bool Correct { get; set; }
    public LoginImage()
    {
    }
    public LoginImage(Bitmap img, bool Correct)
      : this()
    {
      this.Image = img;
      this.Correct = Correct;
    }
  }
}
This question has already been answered. Start a new discussion instead.