PowerShell Memo

このサイトはPowerShell(MSH/Monad)奮闘記です

管理人「newpops吉岡洋」が
「PowerShell(旧名:MSH/Monad)」の研究結果を日々綴っていきます。

【お知らせ】
この日記からPowerShellのTipsを抽出し「PowerShell FAQ」として整理しました。


2008-05-27

[][]オセロゲームを作ろう(6):盤面描画とカーソル移動(1)

盤面描画とカーソル移動

今回はオセロの盤面描画とカーソル移動です。

以下のサンプルを実行してみてください。

  1 : ###############################################################################
  2 : # 初期処理/定義
  3 : ###############################################################################
  4 : # アセンブリ読み込み/参照
  5 : $rui = $host.UI.RawUI
  6 : [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
  7 : $keyMap = [Windows.Forms.Keys]
  8 : # 初期化/定義
  9 : $boardStartLine = 3
 10 : ($startX, $startY) = (2, ($boardStartLine + 1))
 11 : ($msgStartLine, $debugMsgStartLine)     = (21, 23)
 12 : $script:screen = $null
 13 : #色定義
 14 : ($boardFgColor, $boardBgColor) = ("Black", "White")
 15 : 
 16 : ###############################################################################
 17 : # メイン
 18 : ###############################################################################
 19 : function Start-Game()
 20 : {
 21 :     Backup-ScrBuf
 22 :     Draw-Init
 23 :     Get-InputKey
 24 :     Restore-ScrBuf
 25 : }
 26 : 
 27 : ###############################################################################
 28 : # キー入力受付関連の関数
 29 : ###############################################################################
 30 : 
 31 : # キー入力関数
 32 : function Get-InputKey()
 33 : {
 34 :     while($true)
 35 :     {
 36 :         # キー取得
 37 :         $keyInfo = $rui.ReadKey("NoEcho,IncludeKeyDown")
 38 :         $keyCode = $keyInfo.VirtualKeyCode
 39 : 
 40 :         # Enterを入力
 41 :         if($keyCode -eq $keyMap::Enter){continue}
 42 : 
 43 :         # Escを入力→終了
 44 :         if($keyCode -eq $keyMap::Escape){return}
 45 : 
 46 :         # 上下左右のキー操作
 47 :         if($keyCode -eq $keyMap::Up)   {Move-CursorByDirection ([String]$keyMap::Up);   continue}
 48 :         if($keyCode -eq $keyMap::Down) {Move-CursorByDirection ([String]$keyMap::Down); continue}
 49 :         if($keyCode -eq $keyMap::Left) {Move-CursorByDirection ([String]$keyMap::Left); continue}
 50 :         if($keyCode -eq $keyMap::Right){Move-CursorByDirection ([String]$keyMap::Right);continue}
 51 : 
 52 :         # Aを入力→現在の座標を表示
 53 :         if($keyCode -eq $keyMap::A)
 54 :         {
 55 :             $dX = $rui.CursorPosition.X
 56 :             $dY = $rui.CursorPosition.Y
 57 :             $dMsg = "X : " + $dX + " Y : " + $dY
 58 :             Show-DebugMsg $dMsg
 59 :         }
 60 : 
 61 :     }
 62 : }
 63 : 
 64 : ###############################################################################
 65 : # メッセージ表示関数
 66 : ###############################################################################
 67 : 
 68 : # メッセージ表示
 69 : function Show-Msg($msg)
 70 : {
 71 :     Show-MsgInner $msgStartLine $msg $msgFgColor $msgBgColor
 72 : }
 73 : 
 74 : function Show-DebugMsg($msg)
 75 : {
 76 :     Show-MsgInner $debugMsgStartLine $msg $boardFgColor $boardBgColor
 77 : }
 78 : 
 79 : function Show-MsgInner([int]$pos, [String]$msg, [ConsoleColor]$fg, [ConsoleColor]$bg)
 80 : {
 81 :     Push-Cursor
 82 :     Move-Cursor 0 $pos
 83 :     Write-Host -NoNewLine "                                                                                    "
 84 :     Move-Cursor 0 $pos
 85 :     Write-Host -NoNewLine $msg -ForegroundColor $fg -BackgroundColor $bg
 86 :     Pop-Cursor
 87 : }
 88 : 
 89 : ###############################################################################
 90 : # スクリーン操作関数
 91 : ###############################################################################
 92 : 
 93 : # スクリーンバッファバックアップ
 94 : function Backup-ScrBuf()
 95 : {
 96 :     $rect = New-Object System.Management.Automation.Host.Rectangle
 97 :     $rect.Left   = 0
 98 :     $rect.Top    = 0
 99 :     $rect.Right  = $rui.WindowSize.Width
100 :     $rect.Bottom = $rui.CursorPosition.Y
101 :     $script:screen = $rui.GetBufferContents($rect)
102 : }
103 : 
104 : # スクリーンバッファリストア
105 : function Restore-ScrBuf()
106 : {
107 :     Clear-Host
108 :     $origin = New-Object System.Management.Automation.Host.Coordinates(0, 0)
109 :     $rui.SetBufferContents($origin, $script:screen)
110 :     $pos = New-Object System.Management.Automation.Host.Coordinates(0, $script:screen.GetUpperBound(0))
111 :     $rui.CursorPosition = $pos
112 : }
113 : 
114 : ###############################################################################
115 : # 描画関連の関数
116 : ###############################################################################
117 : 
118 : # 初期描画
119 : function Draw-Init
120 : {
121 :     # タイトルの描画
122 :     Clear-Host
123 :     Write-Host "=================================="
124 :     Write-Host "      Othello  by  PowerShell     "
125 :     Write-Host "=================================="
126 : 
127 :     # オセロ盤の描画
128 :     Move-Cursor 0 $boardStartLine
129 :     Draw-Board
130 : 
131 :     # カーソル位置の初期化
132 :     Move-Cursor $startX $startY
133 : }
134 : 
135 : # オセロ盤の描画
136 : function Draw-Board()
137 : {
138 :     Write-Host "┌─┬─┬─┬─┬─┬─┬─┬─┐" -ForegroundColor $boardFgColor -BackgroundColor $boardBgColor
139 :     for($i=1; $i -le 7;$i++)
140 :     {
141 :         Write-Host "│ │ │ │ │ │ │ │ │" -ForegroundColor $boardFgColor -BackgroundColor $boardBgColor
142 :         Write-Host "├─┼─┼─┼─┼─┼─┼─┼─┤" -ForegroundColor $boardFgColor -BackgroundColor $boardBgColor
143 :     }
144 :     Write-Host "│ │ │ │ │ │ │ │ │" -ForegroundColor $boardFgColor -BackgroundColor $boardBgColor
145 :     Write-Host "└─┴─┴─┴─┴─┴─┴─┴─┘" -ForegroundColor $boardFgColor -BackgroundColor $boardBgColor
146 : }
147 : 
148 : ###############################################################################
149 : # カーソル操作関数
150 : ###############################################################################
151 : 
152 : # 指定した位置にカーソルを移動する
153 : function Move-Cursor([int]$newX, [int]$newY)
154 : {
155 :     $coordinate = New-Object System.Management.Automation.Host.Coordinates $newX, $newY
156 :     $rui.CursorPosition = $coordinate
157 : }
158 : 
159 : # 上下左右のキーを押した時のカーソル移動
160 : function Move-CursorByDirection([String]$key)
161 : {
162 :     ($oldX, $oldY) = ($rui.CursorPosition.X, $rui.CursorPosition.Y)
163 :     if($key -eq "Up")       {$newX = $oldX; if($oldY -gt 0){$newY = $oldY - 1}}
164 :     elseif($key -eq "Down") {$newX = $oldX; $newY = $oldY + 1}
165 :     elseif($key -eq "Left") {if($oldX -gt 0){$newX = $oldX - 1}; $newY = $oldY}
166 :     elseif($key -eq "Right"){$newX = $oldX + 1; $newY = $oldY}
167 :     Move-Cursor $newX $newY
168 : }
169 : 
170 : function Push-Cursor()
171 : {
172 :     $script:savedCursorPositionX = $rui.CursorPosition.X
173 :     $script:savedCursorPositionY = $rui.CursorPosition.Y
174 : }
175 : 
176 : function Pop-Cursor()
177 : {
178 :     Move-Cursor $script:savedCursorPositionX $script:savedCursorPositionY
179 : }
180 : 
181 : # 処理スタート
182 : Start-Game

上記コードを実行すると、オセロの盤面を描画します。

実行直後

f:id:newpops:20080527014052j:image


上下左右キーを押下すると、キーの方向にカーソルが「1」移動します。

また、Aキーを押下すると現在のカーソル位置を表示します。

#カーソル位置を表示する処理はデバッグ目的で実装しています。

下に移動+カーソル位置表示

起動後、下キーを押下し、下方向に1移動。

その後、Aキーを押下し、カーソル位置を表示しました。

f:id:newpops:20080527014053j:image



ただ、このままではオセロ盤の枠上にもカーソルが移動してしまいます。

このオセロゲームを、

  • 上下左右キーでカーソル移動
  • Enterで駒を置く

という仕様にする場合、カーソルが枠上に移動可能なのは好ましくありません。

駒が配置可能な8×8のマス上にカーソル移動を制限する必要があります。


つづく。。。

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。

トラックバック - http://d.hatena.ne.jp/newpops/20080527/p1