PowerShellでマインスイーパーを作る
Windowsユーザーお馴染みのマインスイーパーをPowerShellで作ってみました。
function minesweeper(){
$masu_size = 8 #マスの大きさ
$boom_cnt = 8 #爆弾の数
$unopened_cnt = $masu_size*$masu_size #未開封の数
$boom_char = '*' #爆弾の文字
$unopened_char = '+' #開いていないマスの文字
$turn = 0 #ターン数
#####
# マスの作成
#爆弾マス
$masu_boom = New-Object "System.Object[,]"$masu_size,$masu_size
#表示用マス
$masu_disp = New-Object "System.Object[,]"$masu_size,$masu_size
#表示用マス 未開封マーク
for($i=0;$i -lt $masu_size;$i++){
for($j=0;$j -lt $masu_size;$j++){
$masu_boom[$i,$j] = " "
$masu_disp[$i,$j] = $unopened_char
}
}
#爆弾を置く処理
for($i=0;$i -lt $boom_cnt;$i++){
$x = Get-Random -Maximum $masu_size -Minimum 0
$y = Get-Random -Maximum $masu_size -Minimum 0
#同じ場所に置かない処理
if($masu_boom[$y,$x] -eq $boom_char){
$i-- #同じ場所に爆弾を置くときは再度処理するためにループカウンタを減らす
} else {
$masu_boom[$y,$x] = $boom_char
}
}
#周りの爆弾の数を数え、マスに書き込む処理
$dx=@(-1,-1, 0, 1, 1, 1, 0,-1)
$dy=@(0 ,-1,-1,-1, 0, 1, 1, 1)
for($i=0;$i -lt $masu_size;$i++){
for($j=0;$j -lt $masu_size;$j++){
if($masu_boom[$i,$j] -ne $boom_char){
$cnt=0
for($k=0;$k -lt 8;$k++){
if( ($($i+$dy[$k]) -ge 0) -and ($($i+$dy[$k]) -lt $masu_size) -and ($($j+$dx[$k]) -ge 0) -and ($($j+$dx[$k]) -lt $masu_size)){
if($masu_boom[$($i+$dy[$k]),$($j+$dx[$k])] -eq $boom_char){
$cnt+=1
}
}
}
if($cnt -ne 0) { # 0個の場合は書き込まない
$masu_boom[$i,$j]=$cnt
}
}
}
}
# マスの表示関数
function disp-masu($masu,$size){
$disp_tmp=" ABCDEFGH"
write-host " "
write-host $disp_tmp
for($i=0;$i -lt $size;$i++){
write-host " $($i+1)" -NoNewline
for($j=0;$j -lt $size;$j++){
if($masu[$i,$j] -eq $boom_char){
write-host $masu[$i,$j] -NoNewline
} elseif($masu[$i,$j] -eq $unopened_char) {
write-host $masu[$i,$j] -NoNewline -BackgroundColor DarkGray
} elseif($masu[$i,$j] -eq '1') {
write-host $masu[$i,$j] -NoNewline -ForegroundColor Blue
} elseif($masu[$i,$j] -eq '2') {
write-host $masu[$i,$j] -NoNewline -ForegroundColor DarkGreen
} elseif($masu[$i,$j] -eq '3' -or $masu[$i,$j] -eq '4' -or $masu[$i,$j] -eq '5' -or $masu[$i,$j] -eq '6' -or $masu[$i,$j] -eq '7' -or $masu[$i,$j] -eq '8' ) {
write-host $masu[$i,$j] -NoNewline -ForegroundColor red
} else {
write-host $masu[$i,$j] -NoNewline
}
}
write-host ""
}
}
# 未開封のカウント関数
function cnt-unopened($masu,$size){
$cnt=0
for($i=0;$i -lt $size;$i++){
for($j=0;$j -lt $size;$j++){
if($masu[$i,$j] -eq $unopened_char){
$cnt+=1
}
}
}
return $cnt
}
#disp-masu $masu_boom $masu_size
#####
# 解答の入力
#未開封の数
$unopened_cnt = (cnt-unopened $masu_disp $masu_size)
#タイマーセット
$start_time = Get-Date
$flg_loop=$True
while($flg_loop){
$turn+=1
disp-masu $masu_disp $masu_size
write-host "残り爆弾数 $boom_cnt"
write-host "未開封の数 $unopened_cnt"
$Input_x = '?'
while( ($Input_x.Length -ne 1) -or ([Byte][Char]($Input_x) -lt 65) -or ([Byte][Char]($Input_x) -gt 72)){
$Input_x = Read-Host "調べる座標 横位置(A~H)"
}
$Input_y = -1
while( ($Input_y -lt 1) -or ($Input_y -gt $masu_size) ){
$Input_y = Read-Host "調べる座標 縦位置(1~$masu_size)"
}
write-host "入力されたのは 横 $Input_x 縦 $Input_y"
write-host ""
#入力補正
$x = [Byte][Char]($Input_x) - 65
$y = $Input_y - 1
$flg_out = $False
if($masu_boom[$y,$x] -eq $boom_char){
#爆弾
$flg_loop = $False
} else {
#周りの表示
$search_que=@()
$search_que+=,($y,$x)
while($search_que.length -ne 0){
$y = $search_que[0][0];
$x = $search_que[0][1];
$search_que = $search_que[1..($search_que.length)] #キューの先頭を削除
$masu_disp[$y,$x] = $masu_boom[$y,$x]
for($k=0;$k -lt 8;$k++){
if( ($($y+$dy[$k]) -ge 0) -and ($($y+$dy[$k]) -lt $masu_size) -and ($($x+$dx[$k]) -ge 0) -and ($($x+$dx[$k]) -lt $masu_size)){
#未開封マス
if($masu_disp[$($y+$dy[$k]),$($x+$dx[$k])] -eq $unopened_char){
#爆弾発見判定
if($masu_boom[$($y+$dy[$k]),$($x+$dx[$k])] -eq $boom_char){
$boom_cnt-=1
}
#空白発見判定 検索キューに加える
if($masu_boom[$($y+$dy[$k]),$($x+$dx[$k])] -eq ' '){
$search_que+= ,($($y+$dy[$k]),$($x+$dx[$k]))
}
#マスを開く
$masu_disp[$($y+$dy[$k]),$($x+$dx[$k])] = $masu_boom[$($y+$dy[$k]),$($x+$dx[$k])]
}
}
}
}
$unopened_cnt = (cnt-unopened $masu_disp $masu_size)
if(($boom_cnt -eq 0) -or ($unopened_cnt -eq $boom_cnt)){
$flg_loop = $False
}
}
}
if(($boom_cnt -eq 0) -or ($unopened_cnt -eq $boom_cnt)){
write-host "★★★爆弾を全て発見しました★★★"
} else {
write-host "☆☆☆爆弾に当たってしまいました☆☆☆"
}
write-host "調べた数:$turn"
$rap_time=(Get-Date) - $start_time
write-host "掛かった時間(時:分:秒):$rap_time"
disp-masu $masu_boom $masu_size
}
上のコードをコピーしてPowerShell の画面に貼り付け、Enter。
そしてコマンド minesweeper とエンターキーを押すと遊べます。
だいたいマインスイーパーです。
#PowerShell #マインスイーパー #コマンドレット #プログラミング初心者 #プログラミング学習 #毎日Note
この記事が気に入ったらサポートをしてみませんか?