データを保存して表示するには?


りか  2003-08-09 17:17:55  No: 108038

こんにちは、Visual Basic.Netですごろくゲームを作ってるのですが、毎回プレーヤーの点数の結果を保存して、後で成績優秀者や、最下位の点数などを表示するにはどういう方法があるでしょうか?MDIとかかな?


Say  2003-08-09 17:50:46  No: 108039

>MDIとかかな?
MDIは「画面の作り」の一種で、データの保存とは無関係です。

ファイルに保存します。保存については
Open , Print # , Input # , Close 各ステートメントについて
調べてみてください。

順位についてはソート(並び替え)して調べます。
ListBoxを使えば簡単にソートできますが、
数字順のソートのときはちょっと工夫がいるかも。


魔界の仮面弁士  2003-08-10 09:06:56  No: 108040

前回の実行結果を保存させておきたいなら、それらをファイルなどに
保存しておき、次回実行時には、それを読み込ませる必要がありますね。

ファイルへの保存と、ファイルからの復元を行う場合は、
「シリアライズ」という処理を行います。
(ヘルプの『基本的なシリアル化』という項を参照してください)

例えば、プレイヤー名と点数の一覧を保存させるために、
  <Serializable()> Public Structure ScoreInfo
      Public Name As String   'プレイヤー名
      Public Score As Integer '点数
      Public Sub New(ByVal Name As String)
          MyClass.Name = Name
          MyClass.Score = 0
      End Sub
      Public Sub New(ByVal Name As String, ByVal Score As Integer)
          MyClass.Name = Name
          MyClass.Score = Score
      End Sub
  End Structure
という構造体を作成しておくとします。

そして、プレイヤーは複数人になりますので、それらを
  Public ScoreBoard() As ScoreInfo
という配列に保存しておくことにします。

この時、構造体の先頭にある「Serializable」属性を忘れないで下さい。
これが無いと、シリアル化が自動的に行われないため、構造体の内容を、
一括して読み書きする事ができなくなります。
# シリアル化しない場合、各メンバごとに入出力処理を記述していかなくては
# いけないので、非常に面倒な事になってしまいます。(^^;

さて、実際の保存処理についてです。
まず、ScoreBoard() As ScoreInfo に、各プレイヤーの名前と得点を
格納してあきます。例えば、最初に作成する時は、
  ReDim ScoreBoard(2)
  ScoreBoard(0) = New ScoreInfo("Aさん", 153)
  ScoreBoard(1) = New ScoreInfo("Bさん", 180)
  ScoreBoard(2) = New ScoreInfo("Cさん", 221)
などとしておき、その点数を書き換えるときは、
  ScoreBoard(1).Score = 300
などとします。

そしてこの配列をファイル化するためには、FileStream を使います。
まず、FileStreamを使いやすくするために、コードの先頭で、
  Imports System.IO
  Imports System.Runtime.Serialization.Formatters.Binary
という宣言を行っておいて下さい。

実際に保存する際には、
  Dim Formatter As New BinaryFormatter()
  Dim FileStream As FileStream
  FileStream = New FileStream("C:\Test.dat", FileMode.Create)
  Formatter.Serialize(FileStream, ScoreBoard)
  FileStream.Close()
のように記述します。これで、"C:\Test.dat" というファイルが
新規に作成され、そこに ScoreBoard の内容が保存されます。

逆に、保存したファイルの内容を読み込むには、
  Dim Formatter As New BinaryFormatter()
  Dim FileStream As FileStream
  FileStream = New FileStream("C:\Test.dat", FileMode.Open)
  ScoreBoard = DirectCast(Formatter.Deserialize(FileStream), ScoreInfo())
  FileStream.Close()
のようになります。これで、"C:\Test.dat" というファイルが
読み込まれ、それを ScoreBoard へと復元させる事ができます。

実際には、「ファイルが存在しない」時などに発生するエラーを
処理するために、Tryステートメントを併用する必要があるでしょう。


魔界の仮面弁士  2003-08-10 09:21:53  No: 108041

次に、配列の内容を並び替える方法に付いてです。
これには、System.Arrayクラスの Sort メソッドを使います。

例えば、以下のようになります。

'==========================
    'これは、データの並び順を指定するための列挙値です。
    Public Enum SortOrder
        NameAscending   '名前順
        ScoreAscending  '点数の高い順
        ScoreDescending '点数の低い順
    End Enum

    'これは、並び替えを行うためのクラスです。
    Public Class ScoreInfoCollectionSorter
        Implements System.Collections.IComparer
        Private mSort As SortOrder
        Public Sub New(ByVal Sort As SortOrder)
            mSort = Sort
        End Sub

        'IComparer.Compareを実装する事で、データの並び順を定義します。
        '戻り値が <0 の時は、 x < y の意味 になります。
        '戻り値が =0 の時は、 x = y の意味 になります。
        '戻り値が >0 の時は、 x > y の意味 になります。
        Public Overloads Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
            Dim A, B As ScoreInfo
            A = DirectCast(x, ScoreInfo)
            B = DirectCast(y, ScoreInfo)
            Select Case mSort
                Case SortOrder.NameAscending
                    Return String.Compare(A.Name, B.Name)
                Case SortOrder.ScoreAscending
                    Return B.Score - A.Score
                Case SortOrder.ScoreDescending
                    Return A.Score - B.Score
                Case Else
                    Return 0
            End Select
        End Function
    End Class
'==========================

上記のようなクラスを定義しておいた上で、
   System.Array.Sort(ScoreBoard, New ScoreInfoCollectionSorter(SortOrder.NameAscending))
とすれば、ScoreBoard の内容が、『名前順』に並び替えられます。

同様に、
   System.Array.Sort(ScoreBoard, New ScoreInfoCollectionSorter(SortOrder.ScoreAscending))
とすれば、点数の高い順に並び替えられますし、
   System.Array.Sort(ScoreBoard, New ScoreInfoCollectionSorter(SortOrder.ScoreDescending))
とすれば、点数の低い順に並び替えられます。

これ以外にも、ソート処理の方法は幾つかあります。

例えば、元データをDataTableクラスに保存するようにしておき、
それを、DataViewクラスのSortメソッドで並べ替えるという事もできます。

あるいは、Sayさんの回答のように、Sortedプロパティを指定した
ListBoxを使って並び替える方法もありますね。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加