こんにちは、Visual Basic.Netですごろくゲームを作ってるのですが、毎回プレーヤーの点数の結果を保存して、後で成績優秀者や、最下位の点数などを表示するにはどういう方法があるでしょうか?MDIとかかな?
>MDIとかかな?
MDIは「画面の作り」の一種で、データの保存とは無関係です。
ファイルに保存します。保存については
Open , Print # , Input # , Close 各ステートメントについて
調べてみてください。
順位についてはソート(並び替え)して調べます。
ListBoxを使えば簡単にソートできますが、
数字順のソートのときはちょっと工夫がいるかも。
前回の実行結果を保存させておきたいなら、それらをファイルなどに
保存しておき、次回実行時には、それを読み込ませる必要がありますね。
ファイルへの保存と、ファイルからの復元を行う場合は、
「シリアライズ」という処理を行います。
(ヘルプの『基本的なシリアル化』という項を参照してください)
例えば、プレイヤー名と点数の一覧を保存させるために、
<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ステートメントを併用する必要があるでしょう。
次に、配列の内容を並び替える方法に付いてです。
これには、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を使って並び替える方法もありますね。
ツイート | ![]() |