オセロゲームを作ろう(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

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

実行直後


上下左右キーを押下すると、キーの方向にカーソルが「1」移動します。
また、Aキーを押下すると現在のカーソル位置を表示します。
#カーソル位置を表示する処理はデバッグ目的で実装しています。

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

起動後、下キーを押下し、下方向に1移動。
その後、Aキーを押下し、カーソル位置を表示しました。



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

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

という仕様にする場合、カーソルが枠上に移動可能なのは好ましくありません。
駒が配置可能な8×8のマス上にカーソル移動を制限する必要があります。


つづく。。。