C-Sharp Programming Beginner Tutorial: No-Frills Dungeon Crawler (Part 5)

in csharp-forbeginners •  7 years ago  (edited)

CSharp-ForBeginners_FristImage.JPG

Hey everyone, welcome back! So the last lesson showed us some pretty complex items dealing with File Access and pulling data from those files. They were files that stored information regarding Monsters and High Scores for the game. Now, with this Lesson, I'm going to run through the High Score Screen and the programming behind-the-scenes.

So, with no further delays...


The Scoring Show

To get to the High Score screen as is shown above, you need but get to the main game screen (image below, circled in red) and click the High Scores button. That will bring up the screen in the image above, which is populated by the data from the "C:\hi_scores.txt" file that stores all of the scores that have been saved (or in this instance, manually loaded). These are all fake names that I made up.

It's basically just a label component at the top, then a DataGridView component, and then a Button component at the bottom. Let's take a quick look at these components.

  • Label - A .Net component that allows for text to be stored and displayed on a Form.
  • DataGridView - A .Net component that shows a table of data split into columns and rows (like an Excel Spreadsheet of sorts).
  • Button - A .Net component that allows "clickable" events that can produce results.

That, in essence, is what the components do; however, there's much more to each component that can be modified dynamically through the code or prior to generation through the Properties of the component in the IDE (Integrated Development Environment). This allows for defaulted values and attributes as well as code-based interactions.

Let's take a break to look at some High Score screens through the years.


High Score History

Here is a history of some High Score tables from Arcade Classics and Gaming Platforms through History.


Space Invaders High Score Table


Frogger High Score Table


Centipede High Score Table


PacMan High Score Table


Donkey Kong 3 High Score Table


Doom High Score Table


Super Mario Bros. High Score Table


Halo High Score Screen

**Disclaimer: These are all images that may or may not be the actual game. These were labeled as I searched for them, but the images themselves may not be accurate.

What you can see is that the High Score table/screen has evolved, but generally still contains the same type of "Name" and "Score" list. Some in the modern era of games relies more on Achievements and Levels than pure scores, but there's always some sort of screen to use as bragging rights to friends and other competitors.


The Code Behind-the-Scenes

Follows you will see the entire file for the High Scores Class that shows the list of Top 10 Scores:

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;

namespace SimpleDungeonCrawlerGame
{
    public partial class HighScores : Form
    {
        DataTable scores = new DataTable();
        List<KeyValuePair<int, string>> all_scores = new List<KeyValuePair<int, string>>();
        List<KeyValuePair<int, string>> sorted_scores = new List<KeyValuePair<int, string>>();

        public HighScores(DataTable scores)
        {
            InitializeComponent();

            this.scores = scores;
            this.DialogResult = DialogResult.Abort;
        }

        private void HighScores_Load(object sender, EventArgs e)
        {
            SetScores();
        }

        private void SetScores()
        {
            int score = 0;
            foreach (DataRow score_row in this.scores.Rows)
            {
                int.TryParse(score_row["score"]?.ToString(), out score);

                if (score > 0 && score_row["name"]?.ToString() != string.Empty)
                {
                    all_scores.Add(new KeyValuePair<int, string>(score, score_row["name"]?.ToString()));
                }
            }

            sorted_scores = all_scores.OrderBy(x => x.Key).ToList();

            for (int counter = 0; counter <= 9; counter++)
            {
                ScoreGrid.Rows.Add((counter + 1).ToString(), sorted_scores[counter].Key.ToString(), sorted_scores[counter].Value.ToString());
            }
        }

        private void Done_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }
    }
}

To start, as normal, I set up the using statements which tells us what framework components that the program will use. I won't really go over those because, for the most part, they are commonly-used and pre-generated. The only 1 that I manually added was using System.Windows.Forms; which allows me to pop up a MessageBox component (a small pre-designed Form template).

After that, the system auto-generated the namespace and initial class lines. These are auto-generated as well when the Class File is created. The file is called HighScores.cs (.cs is the C# Class extension) and, as you can see, the class declaration is for HighScores. The namespace declaration relates to the game/program itself... in this case it is "SimpleDungeonCrawlerGame" which is the name of my game project. The namespace is like the Foundation Container for all functionality that goes into it. I will try to go more in-depth into namespace components in more advanced Lessons.

Let's take a short break to see kitties, because kitties make some people happy.


Heeeeeeeere's Kitties!!


Cute Kitties?

Or how about this one?


Kitty Shrimp?


The Function of Scoring

So, I'm now going to go backwards in the code, starting with the last Functions that is executed when the Done button is clicked.

        private void Done_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

This function is the same as you've seen before. It says to adjust the DialogResult Property of the Form to reflect OK. There are other statuses: Cancel, Abort, etc. These different statuses can be used to show how the Form was closed. Then, it runs the .Close() Function to close the High Score Form.

Now we'll jump to the front side where the Form is initialized (created) and loaded up. Basically, the following code executes when the Form object is created and the .ShowDialog() function is executed to show the High Score screen.

        DataTable scores = new DataTable();
        List<KeyValuePair<int, string>> all_scores = new List<KeyValuePair<int, string>>();
        List<KeyValuePair<int, string>> sorted_scores = new List<KeyValuePair<int, string>>();

        public HighScores(DataTable scores)
        {
            InitializeComponent();

            this.scores = scores;
            this.DialogResult = DialogResult.Abort;
        }

        private void HighScores_Load(object sender, EventArgs e)
        {
            SetScores();
        }

First, we will see the variables:

_DataTable_ called "scores"
a _List<KeyValuePair<int, string>>_ called "all_scores"
a _List<KeyValuePair<int, string>>_ called "sorted_scores"

The DataTable will be a table of scores and names and is easily understandable, but the others are a bit more difficult to understand, so I'll try to explain them as such:

a _List<KeyValuePair<int, string>>_ is a _List_ (we all know what a list is) of _KeyValuePair_ objects. A _KeyValuePair_ is an object that contains 2 items: a _Key_ and a _Value_ that allow you to store a related pair of information... in this case, the _Key_ is the score and the _Value_ is the name. To create a KeyValuePair, you define the _data types_ for the _Key_ and _Value_ as <int, string> (in this case) where it means <_Key_, _Value_> . I hope this makes sense.

On to the rest...

When the Form is created, it starts with the Constructor code. This is the code that is a reflection of the Class itself. As this example, the class object is called "HighScores" as I mentioned earlier, so the Constructor code is the line of code that says "public HighScores(DataTable scores)"

The HighScores_Load Function defines the logic that happens when the Form actually becomes visible/activated from the parent code. Here, it just does 1 thing: it calls the SetScores(); Function.

Speaking of...



Sorting Things Out

Sorted, Sordid Scores

The only thing left is the logic that actual sorts and stores and shows the scores. Yes, that rhymed and I had a good time doing so.

        private void SetScores()
        {
            int score = 0;
            foreach (DataRow score_row in this.scores.Rows)
            {
                int.TryParse(score_row["score"]?.ToString(), out score);

                if (score > 0 && score_row["name"]?.ToString() != string.Empty)
                {
                    all_scores.Add(new KeyValuePair<int, string>(score, score_row["name"]?.ToString()));
                }
            }

            sorted_scores = all_scores.OrderBy(x => x.Key).ToList();

            for (int counter = 0; counter <= 9; counter++)
            {
                ScoreGrid.Rows.Add((counter + 1).ToString(), sorted_scores[counter].Key.ToString(), sorted_scores[counter].Value.ToString());
            }
        }

Ok, so get your brains wound up and your Logic Centers in order, for here's the way we go. I do a List-to-List sort using something new that is called a Lambda operation. This is going to get very confusing and I doubt most of you will truly understand it, but trust me that the logic works and makes the sorting far easier.

So we will start with this:

            int score = 0;
            foreach (DataRow score_row in this.scores.Rows)
            {
                int.TryParse(score_row["score"]?.ToString(), out score);

                if (score > 0 && score_row["name"]?.ToString() != string.Empty)
                {
                    all_scores.Add(new KeyValuePair<int, string>(score, score_row["name"]?.ToString()));
                }
            }

We begin this Function by setting an int type variable called "score" to a zero value. Then, using a foreach loop, we loop through each DataRow within the scores object (this is the DataTable object that we created initially to store all of the scores from the Main game logic). So, essentially, we're going through each individual score. "this.scores.Rows" identifies the entire Collection of Rows of values.

Within that loop (contained within the curly braces below it) we try to parse the score to an int data type in order to set it into the "score" variable. _int.TryParse(...) basically takes a string of text and tries to convert it to an integer-based number, then it sends it out to the "score" variable. If the text to convert is not a number it will fail and the "score" value will remain 0.

Afterwards, I check that result in the subsequent if statement for this logic: is "score" greater than 0? and the value of the "name" field in the DataRow is not empty? If so, perform the action inside the following curly braces. What it does if that logic resolves to true is to take the "all_scores" variable and adds (.Add(...) function) the new KeyValuePair for the corresponding "score" and "name".

I hope that makes sense... so you now should understand that you have a complete list of score-name pairs.

sorted_scores = all_scores.OrderBy(x => x.Key).ToList(); is the next line. It uses a Lambda expression to perform a task. What this does is sorts the "all_scores" List by using the .OrderBy(...) extension and the .ToList() extension.

So, more in-depth, this shows the concept of chaining extensions. This means using the period to add an extension Function/Property and chaining subsequent extensions in a linear fashion. You don't want to go too crazy with this because it can make it harder to read, but if you only have 2 or perhaps 3 extensions you can do this without worry.

Now, to the "Lambda" expression. This expression is within the .OrderBy(...) extension Function: x=>x.Key. What this says, and it's one of the simplest Lambda expressions you can use, is that the program will use "x" as the entire group and will perform the containing Function (the OrderBy Function to Order the item by the component) against the Key of "x" (x.Key). So it Orders the List by the score (the Key) and then it uses this sorted results and sends the results .ToList() to convert it to a List of it's own. Then that result is set to the "sorted_scores" variable so that this is now a sorted list of scores with corresponding names.

Whew!! You made it through that! Well Done!

Now, to finish this off!

            for (int counter = 0; counter <= 9; counter++)
            {
                ScoreGrid.Rows.Add((counter + 1).ToString(), sorted_scores[counter].Key.ToString(), sorted_scores[counter].Value.ToString());
            }

The for statement is a basic loop using a counter (which I've named "counter" for readability). What it tells the program is this: create an int variable named "counter" and set it to zero. Loop while it's less than or equal to the number 9. Increment by 1. "counter++" is a short-cut way to say "increment by 1" and is the usage within a for statement. Outside of the for statement, you could also use "counter=counter+1;" in the same way.

Now, as the loop iterates through (cycles through), it adds a new DataGridViewRow (.Rows) of the "ScoreGrid" DataGridView table that is on the Form's front screen. This is where the scores will show up. It sets the first column to "counter + 1" which will go from 1 to 10 (our Top 10 spots). Then, it finds the Key to the "sorted_scores" List that represents the score, using [counter] to identify the numeric component of the List item (ie. the "counter"th item in the list, zero-indexed... so when "counter" is "0" then it's using the first item in the list of items). Lastly, it does the same thing but using the Value of the "sorted_scores" List.

Sigh

I didn't realize this would be quite this lengthy, but there it is. Now we have it fully detailed as to how we can create and show our own High Score Table. I may have some minor logic errors, so if you see any please let me know. I'm not perfect and neither is anybody else.

I very much appreciate your readership and look forward to the next part. I believe the next part will be setting up some functions to actually show monsters and treasures. I may also set up the Form to save the score into the "HighScores.txt" file to pull up in this table.

See you all next time!!!


Lessons Learned

Here are the links to your lessons learned (or not learned, if you need to go back and learn them):

C# Programming Beginner Tutorial: Basic Concepts and Ideas

C# Programming Beginner Tutorial: A First look at actual code using D&D as the Project

C# Programming Beginner Tutorial: Variables & Data Types to Fuel the Gaming Engine!

C# Programming Beginner Tutorial: Designing the Game with Programming Logic in Mind (Part 1)

C# Programming Beginner Tutorial: Designing the Game with Programming Logic in Mind (Part 2)

C# Programming Beginner Tutorial: Designing the Game with Programming Logic in Mind (Part 3)

C-Sharp Programming Beginner Tutorial: Designing the Game with Programming Logic in Mind (Part 4)

C-Sharp Programming Beginner Tutorial: Rock! Paper! Scissors!

C-Sharp Programming Beginner Tutorial: No-Frills Dungeon Crawler (Part 1)

C-Sharp Programming Beginner Tutorial: No-Frills Dungeon Crawler (Part 2)

C-Sharp Programming Beginner Tutorial: No-Frills Dungeon Crawler (Part 3)

C-Sharp Programming Beginner Tutorial: No-Frills Dungeon Crawler (Part 4)

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Woah, you never fail me to learn every time you post some tutorials in the C# language.

I never thought of using List<> with a Key and Value data type. I also use the same concept and behavior on how you use the List<>, however, I tend to use Dictionary<> for that one.
Thank you for the tutorial, I might use the List<> with the Key data type as I see it more professional Hahahahahaha

I think I started using Dictionary, but I believe I found something that made it tough to use... unfortunately I cannot, for the life of me, recall why. Dictionary is one of those that I had very little exposure to until I had my last job and one of the developers suggested I use it. The problem, though, was that they didn't want to explain it at all so I had to try and research it myself. That's why I prefer using List.

owww I see
Thank you

No problem.

all of your post is always so informative,so i regularly follow your blog. love to read it...........

I appreciate that. Thanks.

@dbzfan4awhile is there a bit of computer graphics in this because I found a few lines of code like .drawing etc which I had in cg .I really appreciate your writing and as always you write articles that are important and will surely help everyone who reads your article ...keep it up bro!!

using System.Drawing; is probably what you are referring to, but that's not new to my programs as that's an auto-generated using statement. It basically gets loaded up standard to allow programmers to draw to different .Net components.

I like that you are looking for those little things that are new. It really tells me that you are reading the Lesson thoroughly.

Thanks.

Welcome bro I consider you as my virtual sir who really helps me in every thing being it guiding me for my future or knowledge you always help me a lot.... Blessed really your articles help me a lot keep it up bro!!

I'm happy to hear that they help in your development as a programmer! Have you written any little programs using this knowledge yet?

Basically I am a mechanical engineer but learning is a lifelong process maybe i can use it somewhere else. By looking at the lines of code it can be seen that it is based on logic. Which step should come after which. And simple explanation.

In addition to what you say, the previous posts (links at the bottom) are "stackable learning". So you can go back through those earlier posts and build on them until you clearly understand those. I hope it helps you in your learning. Thanks for reading.

I admire your enthusiasm. And i am going through all your earlier articles. You should create video tutorials on udemy and other learning apps. I would love to connect with you on LinkedIn. Are you on LinkedIn??

I am on LinkedIn, although I rarely if ever use it or look at it, lol. I had thought of video Demos but I don't know if they'd be easier to follow or not... I'll definitely think more about it though.

i have learned html but not css. now i am learning c++. is it suitable for me. if i want to expert in web designing what should i learn first.

C++ is different from this. This is C Sharp, which is based on the .Net framework, while C++ is not. Purely for Web Design you can use C Sharp and use it with ASP for Web Functionality. I've also heard people touting Python and Ruby as excellent Web Design Scripting Languages, but I have not worked with them in more than a cursory form.

If you know HTML, learn CSS next. It's the foundation that will tie your HTML together and make it easier to use.

Wow, I feel so relieved to find these tutorials. I was dead scared to start learning the language until reading your tutorial. I totally understand everything you teach and more importantly increased my confidence.

Thank you so much for that. I can foresee about 5-10 more Lessons from this game's perspective, but I do need ideas for afterwards. Are there any beginner materials that you're still confused about that I should go back and cover in more depth? Any specific components or statements or even some logic that you might like to understand better?

I love the subject of programming, someday I would like to be a great programmer, I will study your post to learn how you can do it! You are a genius !!!

I'm no genius, just someone that worked hard on getting to the point in my understanding of programming and had a very hard time getting there. I now feel it's kind of my duty to pass on how I learned the nuance (almost purely self-taught b/c of a lack of mentors) and syntax that goes with it. I do appreciate your words, though, because without these great comments and insights I would have stopped posting these Tutorials long ago I believe.

wow
you again provide information that is very important again to kimi about beginner tutorial C- I became curious about this application. I want to try.
very good @dbzfsn4awhile

If you have not had the chance to read the Previous Lessons, please feel free to go back and read those as well and begin your journey. I highly suggest using Microsoft Visual Studio's free version (Community or whatever it's called) to start.

This post has been resteemed from MSP3K courtesy of @aggroed from the Minnow Support Project ( @minnowsupport ).

Bots Information:

Join the P.A.L. Discord | Check out MSPSteem | Listen to MSP-Waves

Upvoted on behalf of the dropahead Curation Team!

Thanks for following the rules.

DISCLAIMER: dropahead Curation Team does not necessarily share opinions expressed in this article, but find author's effort and/or contribution deserves better reward and visibility.

Help us giving you bigger upvotes by:

Upvote this comment!
Upvote & Resteem the latest dropahead Curation Reports!
Join the dropahead Curation Trail
to maximize your curation rewards!
Vote dropahead Witness with SteemConnect
Proxy vote dropahead Witness
with SteemConnect
Donate STEEM POWER to @dropahead
12.5SP, 25SP, 50SP, 100SP, 250SP, 500SP, 1000SP
Do the above and we'll have more STEEM POWER to give YOU bigger rewards next time!

News from dropahead: How to give back to the dropahead Project in 15 seconds or less

Quality review by the dropahead Curation Team

According to our quality standards(1), your publication has reached an score of 85%.

Well said Gabriel García Marquez: "You learn to write by writing" Keep trying, you will soon achieve excellence!


(1) dropahead Witness' quality standards:

- Graphic relation to the text (Choice of images according to the text)
- Order and coherence
- Style and uniqueness (Personal touch, logic, complexity, what makes it interesting and easy to understand for the reader)
- Images source and their usage license

good informative

Thank you very much. It was far longer than I had anticipated. Did you understand it?

@dbzfan4awhile cool post and informative thanks for sharing some new information

You're quite welcome! Are you interested in learning how to program?

this is os great. you got the great point here......

Thank you so much.

Wow. Amazing . I just like the programming too much.

Like the programming too much. I like that. I think I must as well, then, as it's one of the things I do for my job and I do it outside of work as well.

Once again, great work @dbzfan4awhile, keep it up. You are building a useful series here.

That is definitely my hope.

Congratulations! This post has been upvoted from the communal account, @minnowsupport, by dbzfan4awhile from the Minnow Support Project. It's a witness project run by aggroed, ausbitbank, teamsteem, theprophet0, someguy123, neoxian, followbtcnews, and netuoso. The goal is to help Steemit grow by supporting Minnows. Please find us at the Peace, Abundance, and Liberty Network (PALnet) Discord Channel. It's a completely public and open space to all members of the Steemit community who voluntarily choose to be there.

If you would like to delegate to the Minnow Support Project you can do so by clicking on the following links: 50SP, 100SP, 250SP, 500SP, 1000SP, 5000SP.
Be sure to leave at least 50SP undelegated on your account.

This post was resteemed by @steemvote and received a 7.57% Upvote

  ·  7 years ago Reveal Comment