我有一个程序存储游戏的最近三个分数。但是,我想只存储最好的分数。例如。最近的得分:汤姆 - 12,萨姆 - 14,苏 - 16.如果我玩游戏并得到20的新分数,我希望它存储新的20分(带名字)和其他两个分数的萨姆和苏......从而失去了汤姆。 (我不担心订单)。
Const NoOfRecentScores = 3;
TRecentScore = Record
Name : String;
Score : Integer;
End;
TRecentScores = Array[1..NoOfRecentScores] of TRecentScore;
Var
RecentScores : TRecentScores;
当我玩游戏时,我调用了一个名为UpdateRecentScores的程序。这是:
Procedure UpdateRecentScores(Var RecentScores : TRecentScores; Score : Integer);
Var
PlayerName : String;
Count,count2 : Integer;
FoundSpace : Boolean;
MinMark,position: Integer;
ScorePresent:boolean = false;
Begin
PlayerName := GetPlayerName;
FoundSpace := False;
Count :=1;
While Not FoundSpace And (Count <= NoOfRecentScores)
Do If RecentScores[Count].Name = ''
Then FoundSpace := True
Else Count := Count + 1;
这是我正在努力的部分。如果之前没有输入分数,那么我必须接受第一个输入的分数将是最小分数:
If ScorePresent = False then
begin
MinMark:=Score;
ScorePresent:=True;
RecentScores[Count].Name := PlayerName;
RecentScores[Count].Score := Score;
writeln('Minimum Mark is: ',MinMark);
end
...上面的问题是,如果第一个得分是一个非常高的分数,这将成为我的最低分数!
下面,我简单地说,如果达到的分数大于MinMark(即最低分数),那么分数应该存储在数组中。
else if Score> MinMark then
begin
For count:= 1 to NoOfRecentScores do
begin
if RecentScores[count].score<Score then
position:=count;
RecentScores[position].Name := PlayerName;
RecentScores[position].Score := Score;
end;
End;
end;
正如您所看到的,我正在尝试检查MinMark首先是什么。然后,将我刚刚得到的分数与MinMarker进行比较,看看是否应该存储它。
因此,为了澄清,我想保存最佳 3分,而不是最近的分数。
答案 0 :(得分:1)
要存储n
最佳分数,可以方便地从高到低排序。
首先让我们举一个例子。假设您有以下四个记录:Tim - 14,Susan - 7,Don - 5和Derek - 12.然后数组看起来像[('Tim', 14), ('Derek', 12), ('Susan', 7), ('Don', 5)]
。
现在,当伯特达到9分时会发生什么?事实证明,我们只想在排序数组中插入一对,以便它变为[('Tim', 14), ('Derek', 12), ('Bert', 9), ('Susan', 7), ('Don', 5)]
。之后,我们删除最后一个元素。
如果我们必须修改数组,我们会找到位置pos
在哪里插入Bert(位置3
),然后将位置pos..(n-1)
中的所有内容移动到位置{ {1}}之后,将Ben和他的分数写入(pos+1)..n
的位置。
答案 1 :(得分:1)
由于您使用的是如此小的阵列(3条记录),因此相对简单。 (如果你的阵列相当大,你想要保持它的排序并使用更快的方法找到它的正确位置,但你的阵列非常小。)
让我们假设您现在有三个RecentScore记录,包含Tim - 14,Susan - 7,Derek - 12.
你需要找出是否有一个得分低于用户刚刚通过CurrentScore
记录(类型TRecentScore
)中的Gemma(9)获得的得分,如果是的话用Gemma的名字和分数代替它。
这是一个工作的控制台项目(在XE5中编译和运行):
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
TRecentScore = record
Name: string;
Score: Integer;
end;
TRecentScores = array of TRecentScore;
// Function to find lower score than the one we're trying to add.
// Returns the index of the next lower item if there is one, or
// -1 if there isn't one.
function FindLowerScore(Scores: TRecentScores; CheckScore: Integer): Integer;
var
i: Integer;
MinScore: Integer; // Lowest score found
begin
Result := -1; // No index found
MinScore := CheckScore; // Lowest score so far
for i := Low(Scores) to High(Scores) do
if Scores[i].Score < MinScore then // Lower than CheckScore?
begin
MinScore := Scores[i].Score; // Yep. Store it (new lowest)
Result := i; // and where it was found
end;
end;
// Utility procedure to display list of scores
procedure PrintScores(const Prelude: string; Scores: TRecentScores);
var
Score: TRecentScore;
begin
WriteLn(Prelude);
for Score in Scores do
Writeln(' ' + Score.Name + ' = ' + IntToStr(Score.Score));
end;
var
RecentScores: TRecentScores;
CurrentScore: TRecentScore;
i: Integer;
begin
SetLength(RecentScores, 3);
RecentScores[0].Name := 'Tim';
RecentScores[0].Score := 14;
RecentScores[1].Name := 'Susan';
RecentScores[1].Score := 7;
RecentScores[2].Name := 'Derek';
RecentScores[2].Score := 12;
// Show scores where we begin
PrintScores('Before', RecentScores);
CurrentScore.Name := 'Gemma'; CurrentScore.Score := 9;
// Check for lower score than Gemma's
i := FindLowerScore(RecentScores, CurrentScore.Score);
if i = -1 then
WriteLn('No lower score found!')
else
begin
// We have a lower score in the array. Update that one
// with our new score.
RecentScores[i].Name := CurrentScore.Name;
RecentScores[i].Score := CurrentScore.Score;
PrintScores('After', RecentScores);
end;
ReadLn;
end.
答案 2 :(得分:0)
这是我用过的,遵循你的建议......
Procedure UpdateRecentScores(Var RecentScores : TRecentScores; Score : Integer);
Var
PlayerName : String;
Count : Integer;
FoundSpace : Boolean;
Begin
PlayerName := GetPlayerName;
FoundSpace := False;
Count := 1;
While Not FoundSpace And (Count <= NoOfRecentScores)
Do If RecentScores[Count].Name = ''
Then
begin
FoundSpace := True;
RecentScores[Count].Name := PlayerName;
RecentScores[Count].Score := Score;
end
Else Count := Count + 1;
If Not FoundSpace
Then
Begin
SortRecentScores(RecentScores); // sort them into order of score
if score > RecentScores[NoOfRecentScores].Score then
begin
RecentScores[NoOfRecentScores].Name:= PlayerName;
RecentScores[NoOfRecentScores].Score:= Score;
end;
End;
End;