Jump to content

C# memory game tutorial

- - - - -

  • Please log in to reply
41 replies to this topic

#1
gaylo565

gaylo565

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 268 posts
This is a simple C# memory game where the user selects tiles two at a time in order to come up with matches. It is made on a 7x6 grid with 7 different pictures. It has a high scores option but other than that it is very basic.

GUI design
*I started with a basic widows form and added a menu strip, 42 buttons in a grid pattern and 5 labels to display game information.

*Next we need to add a File and Help option to the main menu. Under the File option we need a New Game, Reset Scores, and Exit options. Under Help all we need is an About option to show information about the programmer.

*After all of the added options have been named appropriately we double click on the New Game, Reset Scores, Exit, and About options to add click handlers for our menu. Now we are ready to start coding. We also need to double click the form its self in order to create a form load event.

Coding
*First we need to add our references to the very top section of the code. Add the following:
using System.IO;
using System.Threading;
using Microsoft.VisualBasic;

*We need to add the Visual Basic reference manually. Select Add Reference under Project on the main menu. Scroll down until you find Microsoft.VisualBasic and select ok. This is so we can use a visual basic input box for a user name input when a user gets a high score.

*Now we can declare our class level arrays. We need one integer type array for storing random #’s from our random #’s function, one to store our 42 non-repeating #’s for randomizing pictures, and one to store our 3 high scores. We also need a string type array for the names that go with the high scores.

*Next we need to declare 2 booleen type class level variables. One for keeping track of which guess the user is on. One for keeping track of matches.

*We also need to declare 6 integer type class level variables. We will need 4 to hold values for checking matches and storing button value, one for keeping track of number of guesses left, and one for keeping track of users score.

*We also need to declare a random number object before we start coding our methods

*In our methods section we will need 5 methods plus the ones we already have for our menu and form load. First we need a new game method:
private void newGame()
		{
			intScore = 0;
			bln_isFirst = true; 
			bln_isMatch = false; 
			//create bln variable to check if random #'s exist in board array already
            bool bln_isSame = false;
            
            //display the score and guesses left
            lblGuess.Text = "Trys Left: " + intGuess.ToString();
            lblScore.Text = "Score: " + intScore.ToString();
			

			//set high scores arrays from high scores file and display on label
			try
			{
                StreamReader highScoresStreamReader = new StreamReader(Directory.GetCurrentDirectory() + @"\Pictures\HighScores.txt");
				while(highScoresStreamReader.Peek() !=-1)
				{
					for(int a=0; a < 3; a++)
					intHighScores[a] = int.Parse(highScoresStreamReader.ReadLine());
				}
				highScoresStreamReader.Close();
			}
			catch
			{
				MessageBox.Show("File Reading Error1");
			}

			//set user array from user file and display on label
			try
			{
                StreamReader userStreamReader = new StreamReader(Directory.GetCurrentDirectory() + @"\Pictures\User.txt");
				while(userStreamReader.Peek() !=-1)
				{
					for(int a=0; a < 3; a++)
						strUser[a] = userStreamReader.ReadLine();
				}
				userStreamReader.Close();
			}
			catch
			{
				MessageBox.Show("File Reading Error1");
			}	
            lblHighScore.Text = "HighScores:    "+ strUser[0]+"..."+intHighScores[0];
			lblHighScore2.Text = strUser[1]+"..."+intHighScores[1];
			lblHighScore3.Text = strUser[2]+"..."+intHighScores[2];

			//set number of guesses
			intGuess = 13;
			
            //seed the random number function
			DateTime dtmCurrent = DateTime.Now;
            generateRandom = new Random(dtmCurrent.Millisecond);
            _buttonArray = new Button[42] {
											  btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9,btn10, 
											  btn11, btn12, btn13, btn14, btn15, btn16, btn17, btn18, btn19,
											  btn20, btn21, btn22, btn23, btn24, btn25, btn26, btn27, btn28,
											  btn29,btn30, btn31, btn32, btn33, btn34, btn35, btn36, btn37,
											  btn38, btn39, btn40, btn41};
            for (int i = 0; i < 42; i++)
            {
                //ensure that the event only called once
                this._buttonArray[i].Click -= this.ClickHandler;
                
                //set new click handler
                this._buttonArray[i].Click += new System.EventHandler(this.ClickHandler);
                
                //enable all buttons and set images to null
                _buttonArray[i].Enabled = true;
                _buttonArray[i].Image = null;
            }
			//fill array with random #'s from 1 to 42
			int intAdd = 0, intCount1;
			for(int r=0; r < 200; r++)
			{
				intStorage[r] = generateRandom.Next(1,43);
			}
			for(intCount1=0; intCount1 < 250; intCount1++)
			{
				bln_isSame = false;
				if(intAdd < 43)
				{
					//check to see if array already contains generated #
					foreach(int intBoard1 in intBoard)
					{
						if(intStorage[intCount1] == intBoard1)
						{
							bln_isSame = true;
						}
					}
					//fill board array with random non matching #'s
					if(bln_isSame == false && intStorage[intCount1] != 0)
					{
						intBoard[intAdd] = intStorage[intCount1];
						intAdd++;
					}
				}
			}
		}

*next we need a click handler for our buttons and a button events method
private void ClickHandler(object sender, System.EventArgs e)
		{
            	        //button handler...temporarily set button to false visibility and not enabled
		        Button tempButton = (Button)sender;
            	        intCount4 = (tempButton.TabIndex - 42);
			
			//store last int Count2 for checking match and button use.
			intCount3 = intCount2;
			
            	        //set random number for passing to find file name
			intCount2 = intBoard[intCount4];
			ImgLocation = checkNumbers(intCount2);
			tempButton.Image = Image.FromFile(ImgLocation);
			tempButton.Enabled = false;
			buttonEvents(tempButton, intCount2, intCount3, intCount4);
            
            	        //set pause for second turn so player can see pictures
            	        for (int i = 0; i < 10; i++)
            	        {
                		System.Threading.Thread.Sleep(100);
            	        }
		}
private void buttonEvents(Button tempButton, int intCount2, int intCount3, int intCount4)
        	{
            	if(bln_isFirst == true)
				{
					bln_isFirst = false;
					intCount5 = intCount4;
				}
				else
				{
					bln_isFirst = true;				
					bln_isMatch = checkMatch(intCount2, intCount3);
					// if not a match refresh buttons
					if(bln_isMatch == false)
					{
						tempButton.Enabled = true;
						tempButton.Image = null;
						_buttonArray[intCount5].Enabled = true;
						_buttonArray[intCount5].Image = null;
						intGuess -= 1;
					}
					else
					{
						intScore += 10;
					}
				}
            	if (intGuess <= 0)
            	{
               		MessageBox.Show("game over");
                		for (int r = 0; r < 42; r++)
                		{
                    		_buttonArray[r].Enabled = false;
                		}
                		if (intScore > intHighScores[0])
                		{
                    		//move old high scores down one spot
                    		intHighScores[2] = intHighScores[1];
                    		intHighScores[1] = intHighScores[0];
                    		intHighScores[0] = intScore;
                    		//show the User Input Form
                    		strUser[0] = Interaction.InputBox("Congratulations", "New High Score", "Please enter your name:", 10, 10);
                    
                		}
                		else if (intScore > intHighScores[1] && intScore <=intHighScores[0])
                		{
                    		//move middle high score down one spot
                    		intHighScores[2] = intHighScores[1];
                    		intHighScores[1] = intScore;
                    		//show the User Input Form
                   		 strUser[1] = Interaction.InputBox("Congratulations", "New High Score", "Please enter your name:", 10, 10);
                		}
                		else if (intScore > intHighScores[2] && intScore <= intHighScores[1])
                		{
                    		intHighScores[2] = intScore;
                    		//show the User Input Form
                    		strUser[2] = Interaction.InputBox("Congratulations", "New High Score", "Please enter your name:", 10, 10);
                		}
                		//write new high scores strings to the highscores file
                		StreamWriter HighScoreStreamWriter = new StreamWriter(Directory.GetCurrentDirectory()+@"\Pictures\HighScores.txt", false);
                		for (int g = 0; g < 3; g++)
                		{
                    HighScoreStreamWriter.WriteLine(intHighScores[g]);
                		}
                		HighScoreStreamWriter.Close();
                		//write new names strings to the user file
                		StreamWriter NamesStreamWriter = new StreamWriter(Directory.GetCurrentDirectory() + @"\Pictures\User.txt", false);
                		for (int b = 0; b < 3; b++)
                		{
                    		NamesStreamWriter.WriteLine(strUser[b]);
                		}
                		NamesStreamWriter.Close();
            	}
            	else
            	{
                	//display the score and guesses left
                	lblGuess.Text = "Trys Left: " + intGuess.ToString();
                	lblScore.Text = "Score: " + intScore.ToString();
            	}
		}

*The final two user added methods will be a checkMatch method to check for matches and a checkNumbers method to translate our random #’s file paths for our pictures.
private void ClickHandler(object sender, System.EventArgs e)
		{
            //button handler...temporarily set button to false visibility and not enabled
			Button tempButton = (Button)sender;
            intCount4 = (tempButton.TabIndex - 42);
			
			//store last int Count2 for checking match and button use.
			intCount3 = intCount2;
			
            //set random number for passing to find file name
			intCount2 = intBoard[intCount4];
			ImgLocation = checkNumbers(intCount2);
			tempButton.Image = Image.FromFile(ImgLocation);
			tempButton.Enabled = false;
			buttonEvents(tempButton, intCount2, intCount3, intCount4);
            
            //set pause for second turn so player can see pictures
            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread.Sleep(100);
            }
		}
		private void buttonEvents(Button tempButton, int intCount2, int intCount3, int intCount4)
        {
            if(bln_isFirst == true)
			{
				bln_isFirst = false;
				intCount5 = intCount4;
			}
			else
			{
				bln_isFirst = true;				
				bln_isMatch = checkMatch(intCount2, intCount3);
				// if not a match refresh buttons
				if(bln_isMatch == false)
				{
					tempButton.Enabled = true;
					tempButton.Image = null;
					_buttonArray[intCount5].Enabled = true;
					_buttonArray[intCount5].Image = null;
					intGuess -= 1;
				}
				else
				{
					intScore += 10;
				}
			}
            if (intGuess <= 0)
            {
                MessageBox.Show("game over");
                for (int r = 0; r < 42; r++)
                {
                    _buttonArray[r].Enabled = false;
                }
                if (intScore > intHighScores[0])
                {
                    //move old high scores down one spot
                    intHighScores[2] = intHighScores[1];
                    intHighScores[1] = intHighScores[0];
                    intHighScores[0] = intScore;
                    //show the User Input Form
                    strUser[0] = Interaction.InputBox("Congratulations", "New High Score", "Please enter your name:", 10, 10);
                    
                }
                else if (intScore > intHighScores[1] && intScore <=intHighScores[0])
                {
                    //move middle high score down one spot
                    intHighScores[2] = intHighScores[1];
                    intHighScores[1] = intScore;
                    //show the User Input Form
                    strUser[1] = Interaction.InputBox("Congratulations", "New High Score", "Please enter your name:", 10, 10);
                }
                else if (intScore > intHighScores[2] && intScore <= intHighScores[1])
                {
                    intHighScores[2] = intScore;
                    //show the User Input Form
                    strUser[2] = Interaction.InputBox("Congratulations", "New High Score", "Please enter your name:", 10, 10);
                }
                //write new high scores strings to the highscores file
                StreamWriter HighScoreStreamWriter = new StreamWriter(Directory.GetCurrentDirectory()+@"\Pictures\HighScores.txt", false);
                for (int g = 0; g < 3; g++)
                {
                    HighScoreStreamWriter.WriteLine(intHighScores[g]);
                }
                HighScoreStreamWriter.Close();
                //write new names strings to the user file
                StreamWriter NamesStreamWriter = new StreamWriter(Directory.GetCurrentDirectory() + @"\Pictures\User.txt", false);
                for (int b = 0; b < 3; b++)
                {
                    NamesStreamWriter.WriteLine(strUser[b]);
                }
                NamesStreamWriter.Close();
            }
            else
            {
                //display the score and guesses left
                lblGuess.Text = "Trys Left: " + intGuess.ToString();
                lblScore.Text = "Score: " + intScore.ToString();
            }
		}

*finally we will need to define our methods for the menu bar and our form load event
private void mnuNewGame_Click_1(object sender, System.EventArgs e)
		{
			//call newGame method
            	newGame();
		}
		
private void mnuResetScore_Click(object sender, System.EventArgs e)
		{
			//write name string to the user file
            	StreamWriter NameStreamWriter = new StreamWriter(Directory.GetCurrentDirectory() + @"\Pictures\User.txt", false);
			for(int p=0; p<3; p++)
			{
				NameStreamWriter.WriteLine("NAME");
			}
			NameStreamWriter.Close();
			
			//write 0 strings to the highscores file
			StreamWriter hScoreStreamWriter = new StreamWriter(Directory.GetCurrentDirectory() + @"\Pictures\HighScores.txt",false);
			for(int p=0; p<3; p++)
			{
				hScoreStreamWriter.WriteLine("0");
			}
			hScoreStreamWriter.Close();
		}

private void mnuExit_Click_1(object sender, System.EventArgs e)
		{
			//close this application
			this.Close();
		}

private void mnuAbout_Click(object sender, System.EventArgs e)
		{
			//display 'programmed by' message
			MessageBox.Show("Programmed by: Galen Goforth");
		}
private void frmMain_Load(object sender, System.EventArgs e)
		{
			newGame();
		}

*and there it is You will need to add the pictures to your /bin/debug folder for your project as well as a high scores and user text file to hold high score information. I have attached a working copy(hopefully). This is my first tutorial so suggestions and criticism are more than welcome. I know I didn't explain everything here but my comments are fairly explanatory.

Attached Files


Edited by gaylo565, 16 June 2008 - 05:54 AM.


#2
gaylo565

gaylo565

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 268 posts
Just some thoughts now that I posted this.
First I got a little happy with the if else statements. I probably should have used a couple of switch statements for the checkNumbers method and the checkMatch method. Also I think I declared a couple of the variables with the private modifier for no real reason. I was gonna make my own input form for the high scores name, but the visual basic form seemed an easier way to go.

#3
Guest_Jordan_*

Guest_Jordan_*
  • Guests
Nice tutorial! +rep

#4
gaylo565

gaylo565

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 268 posts
Thank-You. Hope this helps all the folks out there with memory questions. Was also hoping for some suggestions...anybody?

#5
gimmo

gimmo

    Newbie

  • Members
  • Pip
  • 1 posts
Thanks alot!

#6
Healncrush

Healncrush

    Newbie

  • Members
  • PipPip
  • 12 posts
you lost me at:
*In our methods section we will need 5 methods plus the ones we already have for our menu and form load. First we need a new game method:

Code:

Where should i put the following code at?

#7
Xav

Xav

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 13,118 posts
Somewhere inside the code file, outside another method. In short, open the form, double click on it. The code window will appear and there will be some code that says "Form1_Load" or whatever you called it. As a guide, you can put the code just above this.
Jordan said:

Good members, like yourself, stick around and post for ages to come!
Mr. Xav | Blog | Forums

#8
bennysachdev

bennysachdev

    Newbie

  • Members
  • Pip
  • 1 posts
thnx for the code

#9
walshi2k8

walshi2k8

    Newbie

  • Members
  • Pip
  • 1 posts
Great tutorial!

#10
switchoff

switchoff

    Newbie

  • Members
  • Pip
  • 1 posts
Extremely helpful, thanks!

#11
TenTonApe

TenTonApe

    Newbie

  • Members
  • Pip
  • 1 posts
good tutorial

#12
haffi89

haffi89

    Newbie

  • Members
  • Pip
  • 1 posts
Nice Tutorials




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users