Public Grid As ReverseGrid Public Position As Point ' 論理位置 Public Rectangle As Rectangle ' 物理位置 Status; 黒 白 なしの状態 Grid; オセロの盤面 Position; 盤面内の説明 Rectan

Similar documents
(Microsoft Word \203v\203\215\203O\203\211\203~\203\223\203O)

アプリケーション

グラフィックス

バスケットボール

ブロック崩し風テニス

ルーレットプログラム

ブロック パニック

LogisticaTRUCKServer-Ⅱ距離計算サーバ/Active-Xコントロール/クライアント 概略   

かべうちテニス

LogisticaTRUCKServer-Ⅱ距離計算サーバ/Active-Xコントロール/クライアント 概略   

ランボール

VB 資料 電脳梁山泊烏賊塾 音声認識 System.Speech の利用 System.Speech に依るディクテーション ( 音声を文字列化 ).NetFramework3.0 以上 (Visual Studio 2010 以降 ) では 標準で System.Speech が用意されて居るの

プロシード

Microsoft Word 練習問題の解答.doc

ドッグファイト

VB.NET解説


データアダプタ概要

ウィンドウ操作 応用

チア ダンス

平成 30 年度 プログラミング研修講座 岩手県立総合教育センター

3D回転体プログラム

グラフィックトレーニング 概要.NET のグラフィック描画は どんなことができるのでしょうか? グラフィックオブジェクトやグラフィック環境 概念を理解するためには クラスを使って馴れることが近道です 本 書に記載されているコードをカットアンドペーストして 一つ一つの機能を体験してください 前提 グラ

情報システム設計論II ユーザインタフェース(1)

With sqlda sqlda に SelectCommand を追加.SelectCommand = New MySqlCommand() With.SelectCommand.CommandType = CommandType.Text.CommandText = "select * from

MISAO with WPF

ファイル操作

コンピュータ概論

ICONファイルフォーマット

ファイル操作-インターネットキャッシュ

NotifyIconコントロール

インベーダープログラム

Case 0 sqlcmdi.parameters("?tencode").value = Iidata(0) sqlcmdi.parameters("?tenname").value = Iidata(1) 内容を追加します sqlcmdi.executenonquery() Case Else

API 連携方式 外部 DLL の呼び出し宣言 外部 DLL の呼び出し宣言のサンプルコード (Microsoft Visual C#.NET の場合 ) プログラムコードの先頭で using System.Runtime.InteropServices; が必要 クラスの内部に以下のような外部 D

1. 入力画面

VFD256 サンプルプログラム

untitled

DAOの利用

sinfI2005_VBA.doc

情報システム設計論II ユーザインタフェース(1)

3軸加速度センサーモジュール MM-2860 書込み済みマイコンプログラム通信コマンド概要

Userコントロール

GS1-128 の描画 DLL について (ver. 2.3) 動作環境など動作環境 WindowsXP Windows Vista Windows7 Windows8/8.1 Windows10 上記 OS について すべて日本語版を対象としております 32bit アプリケーションから呼び出される

PowerPoint プレゼンテーション

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

プロセス間通信

クリッピング領域

untitled

パラパラ漫画

Microsoft Word _VBAProg1.docx

プレポスト【問題】

C#の基本

はるよちゃんっ!

PowerPoint プレゼンテーション

Microsoft Word - VBA基礎(3).docx

Microsoft PowerPoint - VBA解説1.ppt [互換モード]

Microsoft PowerPoint - vp演習課題

Oracle Lite Tutorial

Prog2_12th

プリンタ印字用 DLL 取扱説明書

プラグイン

Visual Studio2008 C# で JAN13 バーコードイメージを作成 xbase 言語をご利用の現場でバーコードの出力が必要なことが多々あります xbase 言語製品によっては 標準でバーコード描画機能が付加されているものもあるようで す C# では バーコードフォントを利用したりバー

ドライブは安全運転で in 滋賀♪


VB実用⑦ エクセル操作Ⅰ

占領双六ゲーム

ExcelVBA


Javaプログラムの実行手順

Ver.1.1

倉庫番

Oracle Lite Tutorial

発展プログラミング (5) 例題 5-03( 応用プログラム 3 目並べ その 2) 勝敗判定機能をそなえた 3 目並べ のゲーム盤を作りましょう 必要な変数を考えましょう 1 マス目の状態を保持する配列 整数型 :mas[] 2 何手目かを数える変数 整数型 :nante 3 ゲームが終了したかど

PowerPoint プレゼンテーション

レコードとオブジェクト

EXCEL VBA講座

Microsoft Word -

Msako技術資料 

Microsoft Word - VB_10.doc

Microsoft Word - VB.doc

ListViewコントロール

PowerPoint プレゼンテーション

Java言語 第1回

Secure iNetSuite for .NET 4.0Jの新仕様について

Microsoft PowerPoint - diip ppt

PowerPoint プレゼンテーション

My関数の作成演習問題集

D0050.PDF

MS-ExcelVBA 基礎 (Visual Basic for Application)

スライド 1

D0120.PDF

平成 29 年度卒業研究 初心者のためのゲームプログラミング用 教材の開発 函館工業高等専門学校生産システム工学科情報コース 5 年 25 番細見政央指導教員東海林智也

神経衰弱ゲーム

CodeGear Developer Camp

情報基礎A

csv csv

PowerPoint プレゼンテーション

Microsoft PowerPoint ppt

Prog2_4th

Microsoft PowerPoint - Visualプログラミング

Transcription:

31204 プログラミング 3605 井上寛晶 3531 松井佑樹 3635 宮地翼 要旨各自でフリーソフトを作成 インターネット上に公開することを目的とし Visual Basic2008 2010 を使い 二年生までは ちんちろりん という簡単なゲームを作ったが 今回はより難度が高い オセロ の作成に成功した 本文 1. 目的情報化が進んだ現代において 社会に出ていくためにはパソコンの一つや二つ 軽く扱えなければならない さらに 資源の乏しい日本においては今後 情報技術の発展することが望ましいと考える 私たちのグループでは SE( システムエンジニア ) 等の職に就き 今後の日本のみならず情報技術によって世界に貢献できる人材となるべく プログラミング技術の習得を目的とした また 今回は IA( 人工知能 ) が必要となる対戦型オセロゲームを作成することを目的とし より高度なプログラミング技術の取得を目的とした 2. 使用した器具 装置など (1) 使用言語 Visual Basic (2) 開発ソフト Microsoft Visual Studio 2008 Microsoft Visual Studio 2010 使用マシン FMV K5290 Intel LB-D701S 3. 研究 実験の手順一年生から積み上げてきた Visual Basic の知識を生かし 以下のソフトを開発 対戦型オセロゲーム 4. 結果 プログラムの説明 Cell,txt のプログラム Public Class cell Public Status As CellStatus ' セルの状態 黒 白 空 04-1

Public Grid As ReverseGrid Public Position As Point ' 論理位置 Public Rectangle As Rectangle ' 物理位置 Status; 黒 白 なしの状態 Grid; オセロの盤面 Position; 盤面内の説明 Rectangle; 描画を行う四角形の領域 ' コンストラクタ ''' <summary> 論理位置を指定してセルを作成します </summary> ''' <param name="grid"> セルが属するグリッドを指定します </param> ''' <param name="position"> セルの論理位置を指定します </param> Public Sub New(ByVal Grid As ReverseGrid, ByVal Position As Point) Me.Grid = Grid Me.Position = Position Dim Rect As New Rectangle ' 論理位置から物理位置を求めます Rect.X = Position.X * ReverseGrid.CellSize Rect.Y = Position.Y * ReverseGrid.CellSize Rect.Width = ReverseGrid.CellSize Rect.Height = ReverseGrid.CellSize Me.Rectangle = Rect Dim FrontBrush As New SolidBrush(Color.Black) Dim BackBrush As New SolidBrush(Color.White) ' Draw ''' <summary> 現在の状態を描画します </summary> ''' <param name="g"> 描画対象の Graphics オブジェクトを指定します </param> Public Sub Draw(ByVal g As Graphics) Dim CellRect As Rectangle ' 描画領域 CellRect は描画領域であると宣言 04-2

' 描画領域の算定 ' セルいっぱいに描画するとぎちぎちになるので範囲を -2 する CellRect = Me.Rectangle CellRect.Inflate(-2, -2) ' 描画状態の設定 Select Case Me.Status Case CellStatus.Black FrontBrush.Color = Color.Black ' 表を黒に設定 BackBrush.Color = Color.White ' 裏を白に設定 Case CellStatus.White FrontBrush.Color = Color.White ' 表を白に設定 BackBrush.Color = Color.Black ' 裏を黒に設定 End Select 黒の石は表を黒 裏を白に 白の石は表を白 裏を黒に設定する ' 描画実行 If Me.Status <> CellStatus.Nothing Then ' 裏面描画 CellRect.Y += 2 ' 裏と表をちょっとずらして立体的に見せる g.fillellipse(backbrush, CellRect) ' 表面描画 CellRect.Y -= 2 g.fillellipse(frontbrush, CellRect) 石の状態が有色 ( 石が置かれている ) であれば 石の表 裏を描画する この時 裏表を若干ずらして立体的に見せる ' アクティブな場合は枠を描画する If Me.Focused Then g.drawrectangle(pens.orange, CellRect) 下記の赤色の変更を適応するコード 04-3

Public Focused As Boolean ' Focus ''' <summary> セルをアクティブにします </summary> ''' <remarks> アクティブなセルとは Focused プロパティが True のセルです ''' このメソッドを呼び出すと同じ盤に属するその他のセルのFocused プロパティを Falseにします ''' アクティブであることにそれ以上の効果はありませんが ''' 描画の際に Focused プロパティが True のセルに枠線を描画します ''' </remarks> Public Sub Focus() Dim X As Integer Dim Y As Integer ' 同じグリッドに属する自分以外のセルを非アクティブにする For X = 0 To ReverseGrid.XCount - 1 For Y = 0 To ReverseGrid.YCount - 1 Grid.Cells(X, Y).Focused = False Next Next ' 自分自身をアクティブにする Me.Focused = True マスの上にマウスを置いたときに枠線を表示する (Form1 の MouseMove イベントと対応 ) * こちらではマウスが来たときに枠を描く準備を行う 実際に描画しているのは Paint イベントの Draw イベント ( 上の青色の部分 ) 04-4

computer3 のプログラム Public Class Computer3 Dim Grid As ReverseGrid Public Standard As CellStatus ReverseGrid; オセロの盤面を表し 石を置く ひっくり返すことや それに関するイベント セルの管理 描画処理を行う Cellstatus; 石のもと ( 白 黒 なし の三つの状態を表す ) Grid はオセロの盤面 Standard は黒 白 なしの三色と宣言 Public Sub New(ByVal Grid As ReverseGrid, ByVal Standard As CellStatus) Me.Grid = Grid Me.Standard = Standard Public Sub Put() コンピュータに石を置かせる Dim X As Integer Dim Y As Integer Dim PlayerColor As CellStatus ' 角に置けるなら角におく If Grid.CanPut(Standard, 0, 0) Then Grid.Put(Standard, 0, 0) If Grid.CanPut(Standard, 0, ReverseGrid.YCount - 1) Then Grid.Put(Standard, 0, ReverseGrid.YCount - 1) If Grid.CanPut(Standard, ReverseGrid.XCount - 1, 0) Then Grid.Put(Standard, ReverseGrid.XCount - 1, 0) 04-5

If Grid.CanPut(Standard, ReverseGrid.XCount - 1, ReverseGrid.YCount - 1) Then Grid.Put(Standard, ReverseGrid.XCount - 1, ReverseGrid.YCount - 1) 右上 右下 左上 左下に置くことが可能な時はその置けるところに石を置かせるなお 角を図 1のように定義している図 1 If Standard = CellStatus.Black Then PlayerColor = CellStatus.White Else PlayerColor = CellStatus.Black コンピュータの使う色が黒ならプレイヤーの石の色は白 それ以外 ( 白 ) なら プレイヤーの石は黒 ' 順番に見ていってはじめに置けるところを探す Dim ImageGrid As ReverseGrid Dim Puts As New ArrayList ImageGrid はオセロの盤面 Puts は新しいコレクションと宣言 For Y = 0 To ReverseGrid.YCount - 1 For X = 0 To ReverseGrid.XCount - 1 If Grid.CanPut(Standard, X, Y) Then Puts.Add(New Point(X, Y)) y 座標の上端から下端 x 座標の左端から右端をみて置けるマスがあればそこに石を置く 04-6

' まず コピーのグリッドに石を置いてみる ImageGrid = Grid.Copy ImageGrid.Put(Standard, X, Y) ' この状態で相手に角を取られる可能性があるか検証する Select Case True Case ImageGrid.CanPut(PlayerColor, 0, 0) ' 左上の角を取られてしまうので何もしない Case ImageGrid.CanPut(PlayerColor, 0, ReverseGrid.YCount - 1) ' 左下の角を取られてしまうので何もしない Case ImageGrid.CanPut(PlayerColor, ReverseGrid.XCount - 1, 0) ' 右上の角を取られてしまうので何もしない Case ImageGrid.CanPut(PlayerColor, ReverseGrid.XCount - 1, ReverseGrid.YCount - 1) ' 右下の角を取られてしまうので何もしない Case Else ' 角を取られる心配がないのでこの位置に石を置く Grid.Put(Standard, X, Y) End Select Next Next ' 角を取られる位置にしか置けない場合 仕方ないので置く Dim Pos As Point = DirectCast(Puts(0), Point) Grid.Put(Standard, Pos.X, Pos.Y) End Class 置く場所を考える場合 コピーの盤面を AI が考え それぞれの角を取られる場合を考える それ 以外の条件 ( 角を取られない ) なら そこに石を置く 04-7

Constant のプログラム ' CellStatus ''' <summary> セルの状態を表します </summary> Public Enum CellStatus [Nothing] ' なし Black ' 黒 White ' 白 End Enum ' ScanDirection ''' <summary> 方向を表します </summary> Public Enum ScanDirection Left Right Up Down LeftUp LeftDown RightUp RightDown End Enum form1 のプログラム Public Class Form1 Dim WithEvents Grid As New ReverseGrid Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Grid.Initialize() lblblackcount.text = Grid.Count(CellStatus.Black) lblwhitecount.text = Grid.Count(CellStatus.White) lblwhiteturn.visible = False ゲーム開始時に現在のターンをラベルを使って表示 04-8

Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click ' マウスの座標を PictureBox1 のコントロール座標に変換する Dim Pos As Point = PictureBox1.PointToClient(Windows.Forms.Cursor.Position) マウスで表される座標 (PC 上の画面での座標 ) を盤面上のマスの座標に変換 Dim ThisCell As cell ThisCell = Grid.CellFromPoint(Pos.X, Pos.Y) If Grid.Put(Turn, ThisCell.Position.X, ThisCell.Position.Y) Then ChangeTurn() 石を置いたときにターンを交代させる また ReverseGrid の Canput で設定した置けるマスのみに石を置けるようにする ''' <summary> マウスの移動に伴ってセルにアクティブを示す枠を描画する </summary> Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove Dim ThisCell As cell ' マウスがある位置のセルを取得 ThisCell = Grid.CellFromPoint(e.X, e.y) If Not IsNothing(ThisCell) Then ' セルが取得できた場合は セルにアクティブを示す枠を描画 ThisCell.Focus() ' 現在の状態を描画 (PictureBox1 の Paint イベントを発生させる ) PictureBox1.Invalidate() ' 実際の描画はすべてここで行う Cell の Focus と対応 ( こっちでは マウスがある位置等を取得 ) 04-9

Dim Turn As CellStatus = CellStatus.Black ' 今どっちの順番か Dim PlayerColor As CellStatus = CellStatus.Black ' プレイヤーの色 ' ChangeTurn ''' <summary> ターン交代 </summary> Public Sub ChangeTurn() ' 現在の状態を描画 (PictureBox1 の Paint イベントを発生させる ) PictureBox1.Invalidate() paint イベントを強制的に発生させる 勝敗判定 1すべてのマスに石が置かれる 2マスはまだ空いているが石を置けない状況 3すべての色が同じ色になる 1 If Grid.Count(CellStatus.Nothing) = 0 Then 石の置けるマスが0になり ' 全セルへの配置が終了した場合は勝敗判定して終了 If Grid.Count(CellStatus.Black) > Grid.Count(CellStatus.White) Then 黒のほうが多かったら MsgBox(" 黒の勝ちです!") ElseIf Grid.Count(CellStatus.Black) < Grid.Count(CellStatus.White) Then 白のほうが多かったら MsgBox(" 白の勝ちです!") Else MsgBox(" 引き分けです!!") マスすべてに石が置かれ どちらの石の数が多いか調べた後 それぞれのメッセージを表示 ElseIf Grid.PuttableCount(CellStatus.Black) = 0 AndAlso Grid.PuttableCount(CellStatus.White) = 0 Then 2 ' 空いているセルがあるのに黒も白も置けない場合 If Grid.Count(CellStatus.Black) > Grid.Count(CellStatus.White) Then MsgBox(" 黒の勝ちです!") ElseIf Grid.Count(CellStatus.Black) < Grid.Count(CellStatus.White) Then MsgBox(" 白の勝ちです!") Else MsgBox(" 引き分けです!!") 04-10

石を置くことのできるマスがなくなり どちらが多いかを調べた後 それぞれのメッセージを表示 ElseIf Grid.Count(CellStatus.Black) = 0 Then 3 ' すべての石が白になった場合 (= 黒の石が 0 個の場合 ) MsgBox(" 白の勝ちです!") ElseIf Grid.Count(CellStatus.White) = 0 Then ' すべての石が黒になった場合 (= 白の石が 0 個の場合 ) MsgBox(" 黒の勝ちです!") 石すべてが白または黒になったらそれぞれのメッセージを表示 ' 次のターンの決定 If Turn = CellStatus.Black Then Turn = CellStatus.White lblblackturn.visible = False lblwhiteturn.visible = True Else Turn = CellStatus.Black lblblackturn.visible = True lblwhiteturn.visible = False 石が黒のターンなら次は白に 白なら次は黒に ターンの交代を処理また 黒のターン 白のターンであることを示す線を表示させる ' 置ける場所があるか判定 If Grid.PuttableCount(Turn) = 0 Then ' 置く場所がなければパスして次のターン ChangeTurn() ' 人間かコンピュータかで処理を分岐 If Turn = PlayerColor Then ' 人間の番ならば PictureBox を使用可能にする PictureBox1.Enabled = True Else プレイヤーの番は盤面の操作を可能にし コンピュータの番のときは盤面の操作を不可能にする ' コンピュータの番ならば PictureBox を使用不可にする PictureBox1.Enabled = False 04-11

' ちょっと時間をおく Application.DoEvents() System.Threading.Thread.Sleep(500) 0.5 秒の間を空ける ' コンピュータに石を置かせる どのセルに置くかはコンピュータ (AI) が決定する Computer.Put() ChangeTurn() ' プレイヤーの番へ コンピュータが石を置きターンを交代する Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint Grid.Draw(e.Graphics) ''' <summary> 石を置いたときに発生するイベント </summary> Private Sub Grid_PutNew(ByVal sender As Object, ByVal e As System.EventArgs) Handles Grid.PutNew Call Grid_Reversed(sender, e) ''' <summary> 石がひっくり返されたときに発生するイベント </summary> Private Sub Grid_Reversed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Grid.Reversed ' 現在の状態を描画 (PictureBox1 の Paint イベントを発生させる ) PictureBox1.Invalidate() ' 現在の黒と白の石の数を表示する 04-12

lblblackcount.text = Grid.Count(CellStatus.Black) lblwhitecount.text = Grid.Count(CellStatus.White) 黒石 白石の数をラベルに表示し paint イベントを発生させ 描画を行う ' ちょっと時間をおく Application.DoEvents() System.Threading.Thread.Sleep(500) 石をひっくり返す動作をする際に 毎回 0.5 秒の間を空ける 瞬時に変わるとゲーム性が損なわれる! ' Start ''' <summary> ゲームを開始します </summary> ''' <param name="playercolor"> 人間の石の色を指定します </param> ''' <remarks> 黒が先手になります </remarks> Private Sub Start(ByVal PlayerColor As CellStatus) Grid.Initialize() Me.PlayerColor = PlayerColor ' 人間の色 If PlayerColor = CellStatus.Black Then Computer.Standard = CellStatus.White ' コンピュータの色は白 Else Computer.Standard = CellStatus.Black ' コンピュータの色は黒 プレイヤー コンピュータの色を設定 ' 現在の黒と白の駒の数を表示する lblblackcount.text = Grid.Count(CellStatus.Black) lblwhitecount.text = Grid.Count(CellStatus.White) ラベルに黒石 白石の数を表示 'ChangeTurn を呼び出して黒の番を開始する そのために仮に今は白の番であることにする Turn = CellStatus.White ChangeTurn() Private Sub btnstartblack_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnstartblack.click 04-13

Start(CellStatus.Black) Private Sub btnstartwhite_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnstartwhite.click Start(CellStatus.White) 黒 白で始まるかを選択するボタンの処理 5. 結果に対する考察 わかったこと 感想人工知能というと 難しいイメージがあったが一つ一つ見ていくと角に置けるかを確認するプログラム 右上から左下まで置けるところを探すプログラム 実際に仮の盤面に置くプログラム 相手に角を取られないことを確認するプログラム 実際に置くプログラムと 単純なことの積み重ねだったので 理解できた この経験を生かして今後もプログラムの道に精進したい 6. 参考文献 引用文献 http://homepage1.nifty.com/rucio/main/main.htm 04-14