Pascal:更新最近的得分数组

时间:2014-03-28 15:24:12

标签: pascal

我有一个程序存储游戏的最近三个分数。但是,我想只存储最好的分数。例如。最近的得分:汤姆 - 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分,而不是最近的分数。

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;