📄 programming a memory game in delphi - part 2 - starting to code.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><!-- InstanceBegin template="../Templates/DCBase.dwt" codeOutsideHTMLIsLocked="false" -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- InstanceBeginEditable name="doctitle" -->
<title>Programming a Memory Game in Delphi - Part 2 - Starting to Code</title>
<META NAME="keywords" CONTENT="Delphi, Tutorials, Delphi Game, game tutorial, memory game, DrawGrid, TDrawGrid, Delphi game source code, game code, learn">
<META NAME="description" CONTENT="This is the second part of our step by step Delphi programming tutorial that demonstrates how to program a memory game using a TDrawGrid with Borland Delphi here we now get into writing the actual code">
<!-- InstanceEndEditable --><!-- InstanceBeginEditable name="head" --><!-- InstanceEndEditable -->
<style type="text/css" media="all">
@import url(/CSS/main.css);
</style>
</head>
<body>
<div id="container">
<div id="middle">
<h1><!-- InstanceBeginEditable name="PageTitle" -->Programming a Memory Game in Delphi - Part 2 - Starting to Code<!-- InstanceEndEditable --></h1>
<script type="text/javascript"><!--
google_ad_client = "pub-8027051536030207";
google_ad_width = 468;
google_ad_height = 15;
google_ad_format = "468x15_0ads_al";
google_ad_channel ="7185671694";
google_color_border = "F9EFDD";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_url = "000066";
google_color_text = "000066";
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- InstanceBeginEditable name="Main" -->
<div class="AdvertLeftBox">
<script type="text/javascript"><!--
google_ad_client = "pub-8027051536030207";
google_ad_width = 250;
google_ad_height = 250;
google_ad_format = "250x250_as";
google_ad_channel ="7532447427";
google_color_border = "FFFFFF";
google_color_bg = "FFFFFF";
google_color_link = "0000FE";
google_color_url = "000000";
google_color_text = "000000";
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<h2>Recap</h2>
<p>In part 1 of <a href="memory_game.aspx">Programming a Memory Game</a> we explained how to create the form and drawgrid at design time. Now we will move onto writing the actual code.</p>
<h2>Keeping the Images to be Drawn</h2>
<p>Since we have 20 cells on our grid, we need 10 distinct images.</p>
<ul>
<li>We can keep all of them in the executable file itself, but if we do this, the .exe file becomes bigger,</li>
<li>We can save the images under a directory at installation and can load them automatically when the application is started, but keeping all of the images in memory may use unnecessary memory space,</li>
<li>We can load an image at each time for drawing and then free it, but this time there's a loading overhead at each click on a cell.</li>
</ul>
<p>As an application developer, it's up to you to consider this trade off and to make the best choice. But for simplicity, I will use the second one. That is, I will automatically load the images at the beginning and keep all of the images in memory till the end of the application. This is reasonable when your application uses a small number of images with reasonable sizes.</p>
<p>For this purpose, we will need two global arrays:</p>
<ul>
<li>One for the images,</li>
<li>And one for the image paths.</li>
</ul>
<pre>
var
ImagePaths : array [0..9] of string;
Images : array [0..9] of TImage;
</pre>
<p>The following procedure will help us load the images:</p>
<pre>
procedure LoadImages;
var
i : integer;
begin
for i := 0 to 9 do
begin
Images[i] := TImage.Create(nil);
Images[i].Picture.LoadFromFile(ImagePaths[i])
end
end;
</pre>
<p>We will call this procedure only once, just on the creation of the main form.</p>
<p><strong>NOTE</strong>: You have to assign the image paths before calling this procedure. And you'd better handle exceptions such as non-existent files, etc. Furthermore, your images should have one of the supported image extensions, such as .bmp. But for the sake of simplicity, I skip such kind of details and assume that all of the images will exist in the same directory with the application and all of them will be bitmap images.</p>
<p>Thus, I will change my ImagePaths array variable declaration as follows:</p>
<pre>
ImagePaths : array [0..9] of string
= ('img0.bmp', 'img1.bmp', 'img2.bmp', 'img3.bmp', 'img4.bmp', 'img5.bmp',
'img6.bmp', 'img7.bmp', 'img8.bmp', 'img9.bmp');
</pre>
<p>Make sure that these images exist under your application directory.</p>
<p>Once we ensure that the images exist and have appropriate extensions, we can call the LoadImages procedure on creation:</p>
<pre>
procedure TfrmMain.FormCreate(Sender: TObject);
begin
LoadImages
end;
</pre>
<h2>Coupling the Cells Randomly</h2>
<p>The easiest way to randomize the couples is to randomize a permutation array.</p>
<p>Since we have 20 cells, we will have an array of integers, where each integer value keeps the index of a cell. But wait a minute... Our cells are indexed by 2 integers, namely one row and one column value. How can we represent them with a single index? It is easy. We can think of our double-indexed cell array as a single-indexed linear array. For this purpose, we will use the following function:</p>
<pre>
function LinearIndexOf (Row, Column : integer) : integer;
begin
Result := 5 * Row + Column // Returns the index of the given cell
end;
</pre>
<p>Here, we multiply by 5 because there are 5 cells on each row.</p>
<p>Now, we will declare our random permutation array (globally):</p>
<pre>
var
RandomPermutationArray : array [0..19] of integer;
</pre>
<p>We have to initialize this array once, in the creation of the application. Thus, OnCreate event of our main form will be as follows:</p>
<pre>
procedure TfrmMain.FormCreate(Sender: TObject);
var
i : integer;
begin
LoadImages;
for i := 0 to 19 do
RandomPermutationArray[i] := i
end;
</pre>
<p>And the following procedure will randomize this array at each call to this procedure:</p>
<pre>
procedure RandomizeThePermutationArray;
var
i, RandomPosition, Temp : integer;
begin
for i := 0 to 18 do
begin
RandomPosition := i + Random(19 - i) + 1;
Temp := RandomPermutationArray[i];
RandomPermutationArray[i] := RandomPermutationArray[RandomPosition];
RandomPermutationArray[RandomPosition] := Temp
end;
end;
</pre>
<p>This procedure is an easy-to-understand and a good way of randomizing a permutation array. </p>
<p>It just does the following:</p>
<p>For each element in the array except the last one, it selects randomly one of the elements to the right of this element and swaps them.</p>
<p><strong>NOTE: You can use this nice method in your other applications whenever you need randomization.</strong></p>
<p>How will we make use of this array in our application?</p>
<p>Suppose that after a call for randomization, our array became as follows:</p>
<pre>
19 - 6 - 7 -10 - 0 - 12 - 5 - 1 - 11 - 8 - 2 - 3 - 16 - 15 - 17 - 18 - 4 - 9 - 14 - 13
</pre>
<p>This will mean in our application that the cells with linear indexes 19 & 6 are couples and they share the first image, 7 & 10 are couples and they share the second image, 0 & 12 are couples and they share the third image, etc.</p>
<p>Now, we also need to keep the information of which cell constitutes a couple with which cell. For this purpose, we will use the following array:</p>
<pre>
var
PartnerOf : array [0..19] of integer;
</pre>
<p>And the following procedure will assign the partnerships:</p>
<pre>
procedure AssignPartnerships;
var
i : integer;
begin
for i := 0 to 19 do
if i mod 2 = 0 then
PartnerOf[RandomPermutationArray[i]] := RandomPermutationArray[i + 1]
else
PartnerOf[RandomPermutationArray[i]] := RandomPermutationArray[i - 1]
end;
</pre>
<p>This procedure couples two elements next to each other at each time.</p>
<p>We also need to keep the information of which cell will display which image. Therefore, we need to declare the following variable:</p>
<pre>
var
ImageOfCell : array [0..19] of integer;
</pre>
<p>And the following procedure assigns the images to the cells, using the random permutation array:</p>
<pre>
procedure AssignImagesToCells;
var
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -