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
Donkey Kong 3 High Score Table
Super Mario Bros. High Score Table
**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!!
Or how about this one?
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...
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)
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
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
owww I see
Thank you
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
No problem.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
all of your post is always so informative,so i regularly follow your blog. love to read it...........
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
I appreciate that. Thanks.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
@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!!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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!!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
I'm happy to hear that they help in your development as a programmer! Have you written any little programs using this knowledge yet?
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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??
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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?
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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 !!!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
to maximize your curation rewards!
with SteemConnect
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
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
good informative
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Thank you very much. It was far longer than I had anticipated. Did you understand it?
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
@dbzfan4awhile cool post and informative thanks for sharing some new information
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
You're quite welcome! Are you interested in learning how to program?
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
this is os great. you got the great point here......
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Thank you so much.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Wow. Amazing . I just like the programming too much.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Once again, great work @dbzfan4awhile, keep it up. You are building a useful series here.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
That is definitely my hope.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
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.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
This post was resteemed by @steemvote and received a 7.57% Upvote
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit