Visual Studio 2008 でゲームを作ろう - 気軽に始めるプログラミング - 第 1 回 Visual Studio 2008 でゲームを作る - 数独 を作ってみよう 1 - はじめに本シリーズは全 3 回で ソフトウェゕを開発するツール Visual Studio 2008 を使って 数独 パズルゲームをプログラミングする方法を紹介します 学生の皆様が Visual Studio 2008 を無償で入手しンストールする方法をご紹介し ステップバステップでのプログラミング手順に従って実際に 数独 パズルを作成する方法を説明します ぜひこの機会に 手軽にプログラミングができることを体験してください ソフトウェアを作る 開発ツール とは? ソフトウェゕを作成するには コンピュータが理解できる言語 ( プログラミング言語 ) を利用してソフトウェゕを動作させるためのコード ( 命令の記述 ) を書いていきます これを プログラミングする あるいは コーデゖングする といいます パソコンの性能が向上し 現在は コードを書く手間をなるべく省き ビジュゕルなツールを使いマウスを使ってドラッグ & ドロップなどの方法で 比較的楽に作成できる方法も増えています また 動作テスト用のツールやメンテナンスに役立つツールなども充実しています これらのソフトウェゕ開発に必要なツールをすべてひっくるめて 開発ツール と呼びます Visual Studio 2008 は Windows 専用の開発ツール本シリーズでは Visual Studio 2008 という開発ツールを使用します Visual Studio 2008 は マクロソフトが提供している開発ツールで Windows 上で動作するソフトウェゕを効率よく開発するための専用ツール群 Visual Studio の最新バージョンです Visual C++ や Visual Basic をはじめとした 複数のプログラミング言語に対応した開発ツール群で Windows 上で安全な実行環境を提供する.NET Framework に対応しています DreamSpark に登録して Visual Studio 2008 をインストールしよう DreamSpark は 学生の方を対象にしたソフトウェゕ開発製品 ゕプリケーションデザン製品などの無償提供プログラムです この DreamSpark を利用して Visual Studio 2008 Professional Edition をダウンロードできます 早速 DreamSpark に登録して Visual Studio 2008 をンストールしてみましょう DreamSpark にゕクセスする
ダウンロードしたフゔルを実行し 下記の Visual Studio 2008 セットゕップ画面が表示すれば 次へ ボタンを押します 同意する を選択し DreamSpark から発行されたプロダクトキーと名前を入力します そして 次へ のボタンを押します ンストールする機能 は 既定 を選択し ンストール ボタンを押します
ンストールが終わったら 完了 ボタンを押す前に Visual Studio 2008 の更新プログラムを確 認することをお勧めします セキュリテゖメモ の Windows Update Web サトにゕクセスして ください DreamSpark では Visual Studio の他にも Windows Server Expression などの製品を無償でダ ウンロードできます Dream Spark の提供製品
数独 パズルのルール 本シリーズでは 実際に 数独 パズルを作ってみますが 数独 というパズルゲームをご存じな い方のために 今回はまずこの 数独 についてご説明しておきましょう 数独 ルール 上記のような 9 行 9 列のマス目の空欄のすべてを 下記の 3 つの条件に沿って 1 ~ 9 の数字で埋めていきます < 条件 > 同じ横一行には同じ数字は入りません 同じ縦一列にも同じ数字は入りません 赤線で囲まれた 3 3 の各ミニブロックにも同じ数字は入りません 数独 ゲームを作ってみようでは実際に Visual Studio 2008 を使って 数独 を作ってみましょう ひとつひとつの工程を完璧に理解できなくても ひととおり手順に従って作成してみてください 何をすれば どのようになるのかを体感してみることで プログラミングの流れを理解できるようになります 第 1 章 数独 を作ってみよう 1 イントロダクション 今回は Visual Basic (VB) を使って下記のような 数独 ゲームを作成してみましょう
プロジェクトを作成する Visual Studio 2008 を起動したら 以下の手順に従って プロジェクトを新規作成します 1. フゔ ル 新規作成 プロジェクト を選択します あるいは ツールバーの をクリックします 2. 新しいプロジェクト ウゖンドウの右上で.NET Framework のバージョンを設定できます ( Visual Studio 2008 の新しい機能です ) 今回は.NET Framework 3.5 をそのまま選択し ておきます 3. プロジェクト名 の欄を MySudoku と変更し OK をクリックします 4. Form1.vb が自働的に作成されます フォームは ユーザー ンターフェースになる部分です フ ォ ー ム の 名 前 を わ か り や す く す る た め に FrmSudoku.vb に変更します ソリューションエクスプローラー ウゖンドウの Form1.vb を選択して F2 キーを押し FrmSudoku.vb へ変更します
5. フォームのサズを丁度良い大きさに変更します プロパテゖ ウゖンドウが表示されていない 場合は 表示 メニューの プロパテゖウゖンドウ をクリックして開きます そして 下記のプ ロパテゖを編集します ShowIcon False Size Width Height Text 600 500 数独 コントロールを追加する 6. DataGridView ボタンなどのコントロールを FrmSudoku.vb[ デザン ] に追加します マウスを ツールボックス に近づけるとツールボックスの内容が表示されます を押すと ツール ボックスの内容がそのまま表示されます 7. ツールボックス - データ - DataGridView を選択してドラッグし FrmSudoku.vb[ デザン ] にドロップします そして DataGridView のプロパテゖを変更します dgvplayarea は 数独 のゲーム画面の表示( と入力 ) 部分です (Name) AllowUserToAddRows AllowUserToDeleteRows AllowUserToResizeColumns AllowUserToResizeRows EditMode ScrollBars dgvplayarea False False False False EditOnKeystroke None Size 364,363
BorderStyle ColumnHeadersVisible DefaultCellStyle ( をクリックして CellStyle ビルダを開 None False Alignment: MiddleCenter Font:MS UI Gothic, 24pt きます 下記の図を参照 ) RowHeadersVisible False RowTemplate Height 40 8. DataGridView に列を追加します [ デザン ] ウゖンドウの dgvplayarea を選択し をクリッ クして DataGridView タスク を開きます
9. 列の編集 ウゖンドウが表示されたら 追加 ボタンをクリックすると 列の追加 ウゖンド ウが表示されます 10. 列の追加 ウゖンドウで 列を追加します 今回は 名前と型はデフォルト値のまま利用します ( デフォルトの型 : DataGridViewTextColumn ) 9つの列を作成するので 追加 ボタンを 9 回押します 列の追加が終わったら キャンセル ボタンを押します 11. 列の編集 ウゖンドウで 各列のプロパテゖを下記のように設定します MaxInputLength 1 Width 40 12. これで dgvplayarea の設定が完了しました 解答のエリゕのためにもうひとつ DataGridView を用意する必要があります この作業を楽にするために 先ほど作成した dgvplayarea をコピー ゕンドペーストして プロパテゖを必要な箇所だけ変更します
(Name) ReadOnly dgvanswer true Size 182,182 DefaultCellStyle Font:MS UI Gothic, 12pt RowTemplate Height 20 13. dgvanswer の DataGridView タスク から 列の Width を編集します Width 20 14. TextBox コントロールを追加して プロパテゖを編集します (Name) Multiline ReadOnly tbmessage True True Size 364,60 ([ デザン ] の TextBox を選択し 角をドラッグするとリ サズできます ) 15. Button コントロールを 5 つ追加し プロパテゖを編集します (Name) btnnewgame Width 100 Text ニューゲーム (Name) btnopengame Width 100 Text ゲームを開く (Name) btnsavegame Width 100 Text ゲームを保存 (Name) btnhint Width 100 Text ヒント (Name) btnanswer
Width 100 Text 解答 16. 最後に 各コントロールの TabIndex プロパテゖを設定します btnnewgame 0 btnopengame 1 btnsavegame 2 btnhint 3 btnanswer 4 dgvplayarea 5 tbmessage 6 dgvanswer 7 実行する 17. デバッグ メニューの デバッグ開始 を選択して ゲームを実行します ( あるいは F5 キー を押して実行します ) ここでは 数独 はまだ表示されません プロジェクトファイルのダウンロードここで使用したプロジェクトフゔルは こちらからダウンロードできます プロジェクトフゔルのダウンロード 環境によって FrmSudoku の表示が多少異なります サズなど微調整してください
まとめ第 1 章では 数独 パズルを表示するフォームを作成し 各コントロールのプロパテゖの設定を学習しました 次回は 何かの事象が起こったら特定の処理を実行する ベントハンドラ について学習し また パズル中のデータを保管する XML フゔルの作成方法を学びます
第 2 回 Visual Studio 2008 でゲームを作る - 数独 を作ってみよう 2 - 数独 パズルを作ってみよう第 2 章 はじめに第 1 章では 数独 パズルを表示するフォームを作成しました この章では ニューゲーム ボタンをクリックしてゲームを開始する パズルに問題となる数字を表示させるようにします そのために 次の 3 つのことを行います (a) btnnewgame にベントハンドラを追加する (b) 数独 パズルのデータを保管するために XML フゔルを作成する (c) XMLフゔルを読んで dgvplayarea と dgvanswer にデータを入力します イベントハンドラの追加 1. ボタンの Click ベントの処理を作成するには 二つの方法があります ボタンのデフォルトベントは Click なので FrmSudoku.vb[ デザン ] にあるボタンをダブルクリックすると ベントハンドラーが自働作成されます ( FrmSudoku.vb[ デザン ] が表示されていない場合は ソリューションエクスプローラー の FrmSudoku.vb をダブルクリックしてください ) 2. 各ボタンの Click ベントに処理を追加します
XMLファイルの新規作成 3. ゲームの情報は XML フゔルとして保存します 4. ソリューションエクスプローラー - MySudoku プロジェクトを選択し 右クリックし 追加 - 新しい項目 を選択します 5. 新しい項目の追加 ウゖンドウで XML フゔル のテンプレートを選択し フゔル名 に PuzzleData と入力し 追加 ボタンを押します 6. PuzzleData.xml のプロパテゖを設定します 出力デゖレクトリにコピー 新しい場合はコピーする 7. PuzzleData.xml に記述する内容は下記のようになります <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE sudoku [ <!ELEMENT sudoku (puzzle*)> <!ELEMENT puzzle (question, answer)> <!ELEMENT question (row*)> <!ELEMENT answer (row*)> <!ATTLIST puzzle id ID #REQUIRED> ]> <sudoku> <puzzle id="0"> <question> <row>,4,,,5,,,,</row> <row>5,,,9,2,,4,,8</row> <row>7,,2,6,,,1,,5</row> <row>,,,,,,,2,1</row> <row>,7,9,,,,,8,</row> <row>,6,5,,,,9,7,</row> <row>,8,1,,3,,,,9</row>
<row>,2,,,,8,3,,7</row> <row>3,5,,4,9,2,8,,6</row> </question> <answer> <row>8,4,6,3,5,1,7,9,2</row> <row>5,1,3,9,2,7,4,6,8</row> <row>7,9,2,6,8,4,1,3,5</row> <row>4,3,8,5,7,9,6,2,1</row> <row>1,7,9,2,4,6,5,8,3</row> <row>2,6,5,8,1,3,9,7,4</row> <row>6,8,1,7,3,5,2,4,9</row> <row>9,2,4,1,6,8,3,5,7</row> <row>3,5,7,4,9,2,8,1,6</row> </answer> </puzzle> <puzzle id="1"> <question> <row>,1,8,,,2,,,</row> <row>,5,3,,6,8,9,,</row> <row>,,,7,,,6,8,1</row> <row>,,,,7,,,,8</row> <row>,,,,4,,1,,9</row> <row>,,,8,1,,2,,5</row> <row>,9,,,5,1,,,6</row> <row>8,6,,9,2,,5,,</row> <row>5,,1,,,4,7,9,2</row> </question> <answer> <row>6,1,8,4,9,2,3,5,7</row> <row>7,5,3,1,6,8,9,2,4</row> <row>9,4,2,7,3,5,6,8,1</row> <row>1,2,6,5,7,9,4,3,8</row> <row>3,8,5,2,4,6,1,7,9</row> <row>4,7,9,8,1,3,2,6,5</row> <row>2,9,7,3,5,1,8,4,6</row> <row>8,6,4,9,2,7,5,1,3</row> <row>5,3,1,6,8,4,7,9,2</row> </answer> </puzzle> <puzzle id="2"> <question> <row>,,,,,6,,,</row> <row>,,,,1,,9,,7</row> <row>,,,7,9,,6,,4</row> <row>,,,,3,,,,9</row> <row>,7,4,2,6,,8,,3</row>
<row>5,,3,1,,,,4,6</row> <row>,1,6,,5,7,,,2</row> <row>,,7,9,2,,,6,8</row> <row>2,,9,,,1,,3,5</row> </question> <answer> <row>7,9,2,8,4,6,3,5,1</row> <row>4,6,8,5,1,3,9,2,7</row> <row>1,3,5,7,9,2,6,8,4</row> <row>6,2,1,4,3,8,5,7,9</row> <row>9,7,4,2,6,5,8,1,3</row> <row>5,8,3,1,7,9,2,4,6</row> <row>8,1,6,3,5,7,4,9,2</row> <row>3,5,7,9,2,4,1,6,8</row> <row>2,4,9,6,8,1,7,3,5</row> </answer> </puzzle> </sudoku> コンストラクター Subプロシージャ 関数の生成 8. 今回の開発には初期化が必要なので コンストラクターの中に Sub プロシージャなどを追加します 通常 コンストラクターはコードに表示されていません Public Sub New() を入力して Enter キーを押すことで コンストラクターが完成します FrmSudoku.vb のコードが表示されない場合は FrmSudoku.vb[ デザン ] を選んで 表示 メニューの コード を選択してください Enter キーを押すと 9. コンストラクターには XML フゔルのパズルの数を数えるために countpuzzles という関数 を追加します (countpuzzles の出力は整数のンスタンス変数 TotalPuzzles に割り当てます )
Enter キーを押すと インテリセンス 10. XML フゔルを読むために XmlDocument クラスを用意します XmlDocument を入力している途中で ンテリセンスが候補のクラスを表示してきます この中に利用したいクラスがあれば それを選択して タブキーを押すと コードとクラスが自働的に追加されます 11. XmlDocument はンテリセンスの候補にはないので 最後まで 手動で入力して 赤いスマー トタグをクリックし! をクリックし System.Xml をンポートします を選択すると Imports System.Xml が追加されます
12. 完成した countpuzzle 関数 ( 文字列定数 DATAPATH の値は PuzzleData.xml です) Private Function countpuzzles() As Integer Dim xd As New XmlDocument() 1. Write xd.load(datapath) code to read and load data from PuzzleData.xml into dgvplayarea and 2. Return xd.getelementsbytagname("puzzle").count 3. End Function
13. PuzzleData.xml から dgvplayarea と dgvanswer へデータを読み込むためのコードを書きます (btnnewgame_click の文字列のンスタンス変数 CurPuzzleID はランダムな ID を保存します ) Private Sub btnnewgame_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnnewgame.click CurPuzzleID = New Random().Next(TotalPuzzles).ToString() loadpuzzle() End Sub Private Sub loadpuzzle() ' リセット tbmessage.text = "" If dgvplayarea.rows.count > 0 Then For row As Integer = 0 To 8 dgvplayarea.rows.removeat(0) dgvanswer.rows.removeat(0) Next row ' PuzzleData.xmlからデータを抽出 Dim xd As New XmlDocument() xd.load(datapath) Dim xepuzzle As XmlElement = xd.getelementbyid(curpuzzleid) ' DataGridViewにゲームの情報を入力 For Each node As XmlNode In xepuzzle.firstchild.childnodes dgvplayarea.rows.add(node.innertext.split(new [Char]() {","c})) Next ' DataGridViewに解答の情報を入力 For Each node As XmlNode In xepuzzle.childnodes(1).childnodes dgvanswer.rows.add(node.innertext.split(new [Char]() {","c})) Next ' dgvplayareaにある初期値したセルをreadonlyに設定 For row As Integer = 0 To 8 For col As Integer = 0 To 8 Dim cell As DataGridViewCell = dgvplayarea(col, row) If Not cell.value.equals("") Then cell.readonly = True cell.style.forecolor = Color.Blue cell.style.font = New Font(cell.InheritedStyle.Font, FontStyle.Bold)
Next col Next row ' dgvplayareaを表示 dgvplayarea.visible = True ' 初期のセルハラトを無効に dgvplayarea.currentcell = Nothing dgvanswer.currentcell = Nothing ' タトルを更新 MyBase.Text = " 数独 [" + CurPuzzleID + "]" End Sub 14. dgvplayarea と dgvanswer にカラーフレームを描くために それぞれに Paint ベントハンド ラを追加します そして 各 Paint ベントハンドラに drawframe Sub プロシージャを実行し ます ( 定数 CELL_WIDTH と CELL_WIDTH_ANSWER の値はそれぞれ 40 と 20 です ) Private Sub dgvplayarea_paint(byval sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles dgvplayarea.paint drawframe(e, CELL_WIDTH, Color.Red) End Sub Private Sub dgvanswer_paint(byval sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles dgvanswer.paint drawframe(e, CELL_WIDTH_ANSWER, Color.Gray) End Sub Private Sub drawframe(byval e As PaintEventArgs, ByVal cellwidth As Integer, ByVal framecolor As Color) Dim curpoint As Point = New Point(0, 0) Dim size As Size = New Size(cellWidth * 3, cellwidth * 3) Dim mypen As Pen = New Pen(frameColor, 3) For i As Integer = 0 To 2 For j As Integer = 0 To 2 curpoint.x = i * cellwidth * 3 curpoint.y = j * cellwidth * 3 Dim rect As Rectangle = New Rectangle(curPoint, size) e.graphics.drawrectangle(mypen, rect) Next j Next i End Sub
15. ユーザーが Delete キーか Back Space キーを押したときに 消す 処理のために dgvplayarea に KeyDown ベントハンドラを追加します Private Sub dgvplayarea_keydown(byval sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles dgvplayarea.keydown If dgvplayarea.currentcell.readonly = False AndAlso (e.keycode = Keys.Delete OrElse e.keycode = Keys.Back) Then dgvplayarea.currentcell.value = "" dgvplayarea.currentcell.style.backcolor = SystemColors.Window isdirty = true End Sub 16. FrmSudoku を開始したときに dgvplayarea と dgvanswer を非表示にさせておくように コンストラクターに下記のコードを追加します Public Sub New() ' この呼び出しは Windows フォームデザナで必要です InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します TotalPuzzles = countpuzzles() ' DataGridViewを隠す dgvplayarea.visible = False dgvanswer.visible = False End Sub 17. ゲームを実行すると 下記のように表示されます
プロジェクトファイルのダウンロード 1 章と 2 章までのデザンとコーデゖングはこちらからダウンロードできます デザンとコードのダウンロード 環境によって FrmSudoku の表示が多少異なります サズ調整などを行ってください まとめ第 2 章では ベントハンドラを利用してゲーム開始の処理を作成し XML フゔルを使って問題データを画面に準備しました 次回 第 3 回目では 数独 のルールを実装してゲームを完成させます
第 3 回 Visual Studio 2008 でゲームを作る - 数独 を作ってみよう 3 - 数独 パズルを作ってみよう第 3 章 はじめに本章では 数独 のルールを設定して入力された値をチェックする機能を加えます ゲームの本質的な動作にあたる部分です 入力された値をチェックする 1. dgvplayarea に CellValueChanged のベントハンドラを追加する 2. 主な 3 つのチェックの処理を作成します 1 数字であるかどうか :checkinputisnumber 2 行 列 ミニブロック内に数字の重複がないかどうか :checkhaveduplicates 3 すべてのセルが入力されたかどうか :checkhavecompleted Private Sub dgvplayarea_cellvaluechanged(byval sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvplayarea.cellvaluechanged If canexecuteeventhandler Then ' メッセージをリセット tbmessage.text = "" If Not dgvplayarea.currentcell.value.equals("") Then If checkinputisnumber() = True Then checkhaveduplicates() checkhavecompleted() isdirty = True End Sub
checkinputisnumber Private Function checkinputisnumber() Dim input As String = dgvplayarea.currentcell.value.tostring() Dim r As Regex = New Regex("^[1-91-9]$") If Not r.ismatch(input) Then tbmessage.text = NOTNUMBER dgvplayarea.currentcell.style.backcolor = Color.Red Return False r = New Regex("^[1-9]$") If r.ismatch(input) Then dgvplayarea.currentcell.value = input.replace("1"c, "1"c) _.Replace("2"c, "2"c) _.Replace("3"c, "3"c) _.Replace("4"c, "4"c) _.Replace("5"c, "5"c) _.Replace("6"c, "6"c) _.Replace("7"c, "7"c) _.Replace("8"c, "8"c) _.Replace("9", "9"c) Return True End Function checkhaveduplicates Private Sub checkhaveduplicates() Dim hasduplicateinrow As Boolean = False Dim hasduplicateincol As Boolean = False Dim hasduplicateinbox As Boolean = False Dim input As Object = dgvplayarea.currentcell.value Dim currowindex As Integer = dgvplayarea.currentcell.rowindex Dim curcolindex As Integer = dgvplayarea.currentcell.columnindex ' 当行を確認 For i As Integer = 0 To 8 If dgvplayarea(i, currowindex).value.equals(input) AndAlso i <> curcolindex Then tbmessage.text += " 行 " + (currowindex + 1).ToString() + SAMENUMBER hasduplicateinrow = True Exit For Next i
' 当列を確認 For i As Integer = 0 To 8 If dgvplayarea(curcolindex, i).value.equals(input) AndAlso i <> currowindex Then tbmessage.text += " 列 " + (curcolindex + 1).ToString() + SAMENUMBER hasduplicateincol = True Exit For Next i ' 3x3ミニブロックを確認 Dim blockx As Integer = Math.Floor(curColIndex / 3) Dim blocky As Integer = Math.Floor(curRowIndex / 3) For i As Integer = 0 To 2 For j As Integer = 0 To 2 Dim curx As Integer = blockx * 3 + i Dim cury As Integer = blocky * 3 + j If (dgvplayarea(curx, cury).value.equals(input) AndAlso Not (curx = curcolindex AndAlso cury = currowindex)) Then tbmessage.text += " ミニブロック [" + (blockx + 1).ToString() + "," + (blocky + 1).ToString() + "]" + SAMENUMBER hasduplicateinbox = True Exit For Next j Next i ' 当セルを色付ける If hasduplicateinrow = False AndAlso _ hasduplicateincol = False AndAlso _ hasduplicateinbox = False Then dgvplayarea.currentcell.style.backcolor = SystemColors.Window Else dgvplayarea.currentcell.style.backcolor = Color.Red End Sub
checkhavecompleted Private Sub checkhavecompleted() Dim pass As Boolean = True ' 各セルに値が入力されているかどうか エラーがないか を確認 For row As Integer = 0 To 8 For col As Integer = 0 To 8 If dgvplayarea(col, row).value.equals("") OrElse _ dgvplayarea(col, row).style.backcolor.equals(color.red) Then Return Next col Next row ' 各セルには値があり かつエラーなし ' 念のため 入力と解答を一致することを確認 For row As Integer = 0 To 8 For col As Integer = 0 To 8 If Not dgvplayarea(col, row).value.equals(dgvanswer(col, row).value) Then dgvplayarea(col, row).style.backcolor = Color.Red tbmessage.text += "[" + col.tostring() + "," + row.tostring() + "] の答えは違います " + vbcrlf pass = False Next col Next row If pass Then tbmessage.text = " 正解! おめでとうございます!" End Sub 3. 残りのボタンの Click ベントハンドラに 次の処理のコードを書く ( ゕ ) btnopengame_click: 保存データを開く ( ) btnsavegame_click: 現在のゲームデータを保存する ( ウ ) btnhint_click: 選んだセルの答えを表示する ( エ ) btnanswer_click: 答えの表示 / 非表示を切り替えるボタン
( ア )btnopengame_click Private Sub btnopengame_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnopengame.click If isdirty AndAlso getconfirmation(loadconfirm) = False Then Return If File.Exists(SAVEPATH) Then Dim xd As XmlDocument = New XmlDocument() xd.load(savepath) Dim xnpuzzle As XmlNode = xd.getelementsbytagname("puzzle")(0) CurPuzzleID = xnpuzzle.attributes(0).value loadpuzzle() ' 保存したゲームの状態によってdgvPlayAreaに入力 For row As Integer = 0 To 8 Dim node As XmlNode = xnpuzzle.childnodes(row) Dim number() As String = node.innertext.split(new [Char]() {","c}) For col As Integer = 0 To 8 If dgvplayarea(col, row).value.equals("") AndAlso _ Not number(col).equals("") Then dgvplayarea.currentcell = dgvplayarea(col, row) dgvplayarea(col, row).value = number(col) Next col Next row tbmessage.text = "" dgvplayarea.currentcell = Nothing isdirty = False Else MessageBox.Show(" 保存したゲームはありません ") End Sub
( イ )btnsavegame_click Private Sub btnsavegame_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnsavegame.click If getconfirmation(saveconfirm) = True Then Dim settings As XmlWriterSettings = New XmlWriterSettings() settings.indent = True Try ' フゔルを作成 Writer を作成 Dim fs As FileStream = New FileStream(SAVEPATH, FileMode.Create) Dim w As XmlWriter = XmlWriter.Create(fs, settings) ' xml の宣言を書く w.writestartdocument() ' DTD を書く ' <!DOCTYPE save [ ' <!ELEMENT save (puzzle*)> ' <!ELEMENT puzzle (row*)> ' <!ATTLIST puzzle id ID #REQUIRED> ' ]> Dim dtd As String = "<!ELEMENT save (puzzle*)>" + _ "<!ELEMENT puzzle (row*)>" + _ "<!ATTLIST puzzle id ID #REQUIRED>" w.writedoctype("save", Nothing, Nothing, dtd) ' 内容を書く w.writestartelement("save") w.writestartelement("puzzle") w.writeattributestring("id", CurPuzzleID) For row As Integer = 0 To 8 Dim numbers As String = "" For col As Integer = 0 To 8 numbers += dgvplayarea(col, row).value.tostring() + "," Next col numbers = numbers.substring(0, numbers.length - 1) w.writestartelement("row") w.writevalue(numbers) w.writeendelement() 'row Next row w.writeendelement() 'puzzle w.writeendelement() 'save w.writeenddocument() w.flush() fs.close() isdirty = False Catch ex As Exception MessageBox.Show(ex.Message, " 保存失敗 ", MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning) End Try End Sub
( ウ )btnhint_click Private Sub btnhint_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnhint.click If dgvplayarea.currentcell Is Nothing Then MessageBox.Show(" セルを選択してください ") Else If Not dgvplayarea.currentcell.readonly AndAlso _ getconfirmation(" 選択したセルの答えを表示しますか ") Then dgvplayarea.currentcell.value = _ dgvanswer(dgvplayarea.currentcell.columnindex, dgvplayarea.currentcell.rowindex).value End Sub ( エ )btnanswer_click Private Sub btnanswer_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnanswer.click dgvanswer.visible = Not dgvanswer.visible dgvanswer.currentcell = Nothing End Sub 完成 完成した 数独 を実行してみましょう 本シリーズで完成したプロジェクトは こちらからダウンロードできます 第 3 章で完成したプロジェクトのダウンロード 環境によって FrmSudoku の表示が多少異なります サズ調整などを行ってください
まとめ本シリーズでは Visual Studio 2008 (VB) を使って 数独 パズルをプログラミングしてみました 一連の流れの中で フォーム ベントハンドラ XML フゔルのリード 入力判定など ソフトウェゕでよく使われる基本的なプログラミング手法を学習しました ここで作成したソースコードを参考にして また 新たなプログラムに挑戦してみてください