#============================================================================== # 霧雨式簡易ブラックジャック。 # 作成者:misty_rain (http://page.freett.com/misty_rain/) # ★★★★★概要など★★★★★ # 2006/09/27 # ちょっとした修正。 # 2006/08/07 # 若干の変更。効果音付加。 # 2006/05/02~05/03。いきなり無理難題に挑戦してみる。 # 参加人数は一人。プレイヤーのみ。現金でやり取り。 # ステイとヒットにのみ対応。 # ダブルダウン、スプリットには非対応。 # Aは最初は11として数え、A以外のカードの合計+11が21を超える場合は # 1として数えます。 # 配当倍率は最初は1.0で始まりますが、 # プレイヤーの勝利により増加し、敗北により減少します。(21で勝ったら通常の倍増加) # ゲーム終了後に掛け金×配当倍率のお金が手に入ります。 # 配当倍率は、"やめる"を選択しない限り、そのまま次のゲームに引き継がれます。 # イベントコマンドのスクリプトで、$scene = BlackJack.newと記述すると始められます。 # # ★★★★★今後の目標★★★★★ # ・ダブルダウン、スプリットに対応させる。 # ・ディーラーがたまにイカサマをしたりするようにする(頻度は変数で指定?)。 # ・表示の改善 # # ★★★★★ブラックジャックのルール(大体こんな感じ)★★★★★ # ・プレイヤーが賭け金を決める。 # ・プレイヤーおよびディーラーに2枚ずつカードが配られる。 # ディーラーのカードのうち一枚は表向きに配られる。 # ・プレイヤーはディーラーの表向きのカードを見て、 # ディーラーの最終的な合計を予測し、カードをさらに追加(ヒット)するか、 # そのままにしておく(ステイ,スタンドとも言うらしい)。 # 21を超えるまでは何度ヒットしても良い。21を超えると負け(バスト)になる。 # ・プレイヤーがステイを宣言するとディーラーは自分の伏せて # あったカードを表向きにする。 # ・その時にディーラーのカードの合計が16以下だった場合、 # 17以上になるまでディーラーはカードを追加し続ける。 # ディーラーも21を超えるとバストになる。 # ・持っているカードの合計が多き方が勝ち。21が最強。 # ・Aは1と数えても11と数えてもいい。 # ・2〜9はそのままの数字で数える。 # ・10,J,Q,Kは10として数える。 # #============================================================================== #============================================================================== # ▲ Window_Rate #------------------------------------------------------------------------------ #  配当金の倍率を表示するウィンドウです。 #============================================================================== class Window_Rate < Window_Base #-------------------------------------------------------------------------- # ★ オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(rate = 1.0) @rate = rate super(0, 0, 80, 64) self.contents = Bitmap.new(width - 32, height - 32) refresh end #-------------------------------------------------------------------------- # ★ リフレッシュ #-------------------------------------------------------------------------- def refresh(rate = 1.0) @rate = rate * 1.0 self.contents.clear cx = contents.text_size("#{@rate}").width self.contents.font.color = system_color self.contents.draw_text(4, 0, 40-cx-2, 32, "×", 2) self.contents.font.color = normal_color self.contents.draw_text(40-cx, 0, cx, 32, sprintf("%4.1f", @rate), 2) end end #============================================================================== # ▲ BlackJack #------------------------------------------------------------------------------ #  霧雨式簡易ブラックジャックの本体です。 #============================================================================== class BlackJack #-------------------------------------------------------------------------- # ★ファイル名 #-------------------------------------------------------------------------- #トランプ画像の名前 TrumpFIle = "Graphics/Pictures/trump" #背景画像の名前 JackBackFile = "Graphics/Titles/001-Title01" #敗北時SE Lse = "Audio/SE/057-Wrong01" #勝利時SE Wse = "Audio/SE/056-Right02" #支払時SE Pse = "Audio/SE/006-System06" #-------------------------------------------------------------------------- # ★ オブジェクト初期化 # menu_index : コマンドのカーソル初期位置 #-------------------------------------------------------------------------- def initialize(menu_index = 0) #乱数初期化しちゃう srand end #-------------------------------------------------------------------------- # ★ メイン処理 #-------------------------------------------------------------------------- def main #勝敗による配当倍率の変化値 @rate_m = 0.4 #減少 @rate_p = 0.3 #増加 #初期配当倍率 @rate = 1.0 # 背景読んじゃう @JackBack = Sprite.new @JackBack.bitmap = Bitmap.new(JackBackFile) #トランプ読んじゃう @Trump = Sprite.new @Trump.bitmap = Bitmap.new(TrumpFIle) @Trump.visible = FALSE #ゲーム回数を零 @JackCount = 0 #親の勝ち数を零 @dealWin = 0 #子の勝ち数を零 @playWin = 0 #引き分け数を零 @drawCount = 0 #ゲームのフェイズを零にする。 @JackPhase = 0 #賭け金を零にする @Bet = 0 #プレイヤー所持カード @playerCards = [] # プレイヤーカード挿入位置 @playerInsert = 0 # プレイヤー合計 @playerSum = 0 #ディーラー所持カード @dealerCards = [] # ディーラーカード挿入位置 @dealerInsert = 0 # ディーラー合計 @dealerSum = 0 #山から出す位置 @motherOut = 0 #52種類のトランプの画像 @OneTrumpBmp = [] # @TrumpRect = Rect.new(x, y, width, height) for i in 0..51 @OneTrumpBmp[i] = Sprite.new @OneTrumpBmp[i].bitmap = Bitmap.new(64,96) @OneTrumpBmp[i].bitmap.blt(0, 0, @Trump.bitmap, Rect.new(320,384, 64, 96)) @OneTrumpBmp[i].visible = TRUE @OneTrumpBmp[i].x = 640 / 2 - 32 @OneTrumpBmp[i].y = -96 end #トランプが重なっている表現 @StackBmp = Sprite.new @StackBmp.bitmap = Bitmap.new(64,20) @StackBmp.bitmap.blt(0, 0, @Trump.bitmap, Rect.new(384,384, 64, 20)) @StackBmp.visible = TRUE @StackBmp.x = 640 / 2 - 32 @StackBmp.y = -96 #実際のトランプの並び @TrumpsRow = [] #まずは順番どおりに並べる for i in 0..51 @TrumpsRow[i] = i end #ランダムに並び替える for i in 0..51 j = rand(52) tmp = @TrumpsRow[j] @TrumpsRow[j] = @TrumpsRow[i] @TrumpsRow[i] = tmp end # コマンドウィンドウを作成 s1 = "はい" s2 = "いいえ" @command_window = Window_Command.new(100, [s1,s2]) @command_window.index = 0 @command_window.x = 320 - (@command_window.width / 2) @command_window.y = 240 - (@command_window.height / 2) @command_window.active = TRUE @command_window.opacity = 160 #ヒット・ステイウィンドウを作成 ダブルダウン、スプリットは未実装 s3 = "ヒット" s4 = "ステイ" @Hit_Stay_window = Window_Command.new(100, [s3,s4]) @Hit_Stay_window.index = 0 @Hit_Stay_window.x = 640 - @Hit_Stay_window.width @Hit_Stay_window.y = 240 - (@Hit_Stay_window.height / 2) @Hit_Stay_window.active = FALSE @Hit_Stay_window.opacity = 160 #Aceをどう数えるか?書きましたが、使っていません。 s5 = "1" s6 = "11" @AceChoice_window = Window_Command.new(100, [s5,s6]) @AceChoice_window.index = 0 @AceChoice_window.x = 0 @AceChoice_window.y = 480 - @AceChoice_window.height @AceChoice_window.active = FALSE @AceChoice_window.visible = FALSE @AceChoice_window.opacity = 160 #ヘルプウィンドウを作成 @Help_window = Window_Help.new @Help_window.opacity = 160 # ゴールドウィンドウを作成 @gold_window = Window_Gold.new @gold_window.x = 640 - @gold_window.width @gold_window.y = @Help_window.height @gold_window.opacity = 160 #賭け金を決めるウィンドウを出す @Bet_windowPare = Window_Base.new(640-128,480-64,128,64) @Bet_windowPare.opacity = 160 @Bet_window = Window_InputNumber.new(4) @Bet_window.visible = FALSE @Bet_window.active = FALSE @Bet_window.x = 640 - @Bet_window.width @Bet_window.y = 480 - @Bet_window.height # 倍率ウィンドウを作成 @rate_window = Window_Rate.new(@rate) @rate_window.x = 640 - @rate_window.width @rate_window.y = 480 - @Bet_window.height - @rate_window.height @rate_window.opacity = 160 # ヘルプウィンドウを関連付け # @Bet_window.help_window = @Help_window @Help_window.set_text("ブラックジャックをやりますか?") q = 0 u = 0 # トランジション実行 Graphics.transition # メインループ loop do case @JackPhase when 0 #やるか、やらないか・・・? # if @command_window.active # @JackPhase = 0 # else # @JackPhase = 1 # end j = 0 when 1 @Help_window.set_text(" ") #カードが場に現れる。 #for i in 0..51 #if @OneTrumpBmp[i].y < 128 and i <= j #@OneTrumpBmp[i].y = @OneTrumpBmp[i].y + 8 #end #end j = j + 1 if @OneTrumpBmp[0].y < 128 @OneTrumpBmp[0].y = @OneTrumpBmp[0].y + 8 @StackBmp.y = @OneTrumpBmp[0].y + 96 end if @OneTrumpBmp[0].y >= 128#j >= 80# and @OneTrumpBmp[i].y >= 128 for i in 0..51 @OneTrumpBmp[i].y = 128 end @Help_window.set_text("賭け金を決めてください。") @Bet_window.visible = TRUE @Bet_window.active = TRUE @JackPhase = 2 end when 2 #BET・フェイズ #何もしません。 #賭け金の入力を待ちます。 when 3 #カード配る #ディーラーのカード if @OneTrumpBmp[@NextHit].x > 64 @OneTrumpBmp[@NextHit].x = @OneTrumpBmp[@NextHit].x - 8 end if @OneTrumpBmp[@NextHit+2].x > 128 and @p > 8 @OneTrumpBmp[@NextHit+2].x = @OneTrumpBmp[@NextHit+2].x - 8 end #プレイヤーのカード if @OneTrumpBmp[@NextHit+1].x > 64 @OneTrumpBmp[@NextHit+1].x = @OneTrumpBmp[@NextHit+1].x - 8 end if @OneTrumpBmp[@NextHit+1].y < 322 @OneTrumpBmp[@NextHit+1].y = @OneTrumpBmp[@NextHit+1].y + 8 end if @p > 8 and @OneTrumpBmp[@NextHit+3].x > 128 @OneTrumpBmp[@NextHit+3].x = @OneTrumpBmp[@NextHit+3].x - 8 end if @p > 8 and @OneTrumpBmp[@NextHit+3].y < 322 @OneTrumpBmp[@NextHit+3].y = @OneTrumpBmp[@NextHit+3].y + 8 end @p = @p + 1 if @OneTrumpBmp[@NextHit].x <=64 and @OneTrumpBmp[@NextHit+2].x <= 128 and @OneTrumpBmp[@NextHit+1].x <= 64 and @OneTrumpBmp[@NextHit+1].y >= 322 and @OneTrumpBmp[@NextHit+3].x <= 128 and @OneTrumpBmp[@NextHit+3].y >= 322 @Help_window.set_text("ヒットするかステイするか選んでください。") trumpPrint(@NextHit,@dealerCards[0],TRUE) trumpPrint(@NextHit+1,@playerCards[0],TRUE) trumpPrint(@NextHit+3,@playerCards[1],TRUE) @Hit_Stay_window.active = TRUE @JackPhase = 4 @DealerNext = @NextHit + 2 @NextHit = @NextHit + 4 # 合計チェック PlayerSumCheck() end when 4 #ヒットするかステイするか - 選択 #何もしない when 5 #ヒット 追加 if @OneTrumpBmp[@NextHit].x > ((@playerInsert % 4)+1) * 64 @OneTrumpBmp[@NextHit].x = @OneTrumpBmp[@NextHit].x - 8 end if @OneTrumpBmp[@NextHit].y < (322 - (((@playerInsert / 4)) * 48) ) @OneTrumpBmp[@NextHit].y = @OneTrumpBmp[@NextHit].y + 8 end if @OneTrumpBmp[@NextHit].x <= ((@playerInsert % 4)+1) * 64 and @OneTrumpBmp[@NextHit].y >= (322 - (((@playerInsert / 4)) * 48) ) PlayerCardInsert() trumpPrint(@NextHit,@playerCards[@playerInsert-1],TRUE) @NextHit = @NextHit + 1 @Help_window.set_text("ヒットするかステイするか選んでください。") @JackPhase = 6 @Hit_Stay_window.active = TRUE # 合計チェック PlayerSumCheck() if @playerSum > 21 @Help_window.set_text("バストしました。") @Hit_Stay_window.active = FALSE trumpPrint(@DealerNext,@dealerCards[@dealerInsert-1],TRUE) DealerSumCheck() @JackPhase = 7 end end when 6 #再選択 when 7 #ステイ・ディーラーは16以下の間引き続ける if @dealerSum <= 16 @JackPhase = 8 else @JackPhase = 9 end when 8 # ディーラーが引く。 if @OneTrumpBmp[@NextHit].y > 96 - (@dealerInsert / 4) @OneTrumpBmp[@NextHit].y = @OneTrumpBmp[@NextHit].y - 8 end if @OneTrumpBmp[@NextHit].x > (((@dealerInsert-1) % 4) * 64) @OneTrumpBmp[@NextHit].x = @OneTrumpBmp[@NextHit].x - 8 end if @OneTrumpBmp[@NextHit].x <= (((@dealerInsert-1) % 4) * 64) and @OneTrumpBmp[@NextHit].y <= 96 - (@dealerInsert / 4) DealerCardInsert() trumpPrint(@NextHit,@dealerCards[@dealerInsert-1],TRUE) @NextHit = @NextHit + 1 DealerSumCheck() @JackPhase = 7 q = 1 end when 9 # 勝敗& if (q == 1) @JackCount = @JackCount + 1 if( @playerSum > 21 and @dealerSum > 21 ) or ( @playerSum == @dealerSum) @Help_window.set_text("引き分けです。") @drawCount = @drawCount + 1 elsif (@playerSum > 21 and @dealerSum <= 21) or ( @playerSum < @dealerSum and @dealerSum <= 21) #敗北 @Help_window.set_text("あなたの負けです。") Audio.se_play(Lse, 80, 100) @dealWin = @dealWin + 1 # 配当の倍率を減少 @rate = @rate - @rate_m if @rate < 0.0 @rate = 0.0 end elsif (@playerSum <= 21 and @dealerSum > 21) or ( @playerSum > @dealerSum and @playerSum <= 21) @Help_window.set_text("あなたの勝ちです。") Audio.se_play(Wse, 80, 100) @playWin = @playWin + 1 # 配当の倍率を増加 @rate = @rate + @rate_p if @playerSum == 21 # 配当の倍率を増加 @rate = @rate + @rate_p end else @Help_window.set_text("#{@playerSum}VS#{@dealerSum}で例外です。スクリプトに誤りがあります。") end if @rate < 0.0 @rate = 0.0 end @rate_window.refresh(@rate) end for k in 0...@NextHit if @OneTrumpBmp[k].x >= -64 and q > 50 @OneTrumpBmp[k].x = @OneTrumpBmp[k].x - 16 end end q = q + 1 if q >= 100 q = 0 @p = 0 @playerCards = [] @dealerCards = [] @playerSum = 0 @dealerSum = 0 @JackPhase = 3 @playerInsert = 0 @dealerInsert = 0 DealerCardInsert() PlayerCardInsert() DealerCardInsert() PlayerCardInsert() if @JackCount == 5 @JackPhase = 10 u = 1 end end when 10 # 続けるか? #支払いをする if u == 1 Audio.se_play(Pse, 80, 100) $game_party.gain_gold((@Bet*@rate).truncate) @gold_window.refresh u = 0 end @Help_window.set_text("続けますか?") @command_window.active = TRUE @command_window.visible = TRUE when 11 # 続けます @command_window.active = FALSE @command_window.visible = FALSE if @rate < 1.0 @rate = 1.0 end @rate_window.refresh(@rate) j = 0 q = 0 @p = 0 @Bet = 0 @playerInsert = 0 @playerSum = 0 @dealerInsert = 0 @dealerSum = 0 @motherOut = 0 for i in 0..51 @OneTrumpBmp[i].dispose end for i in 0..51 @OneTrumpBmp[i] = Sprite.new @OneTrumpBmp[i].bitmap = Bitmap.new(64,96) @OneTrumpBmp[i].bitmap.blt(0, 0, @Trump.bitmap, Rect.new(320,384, 64, 96)) @OneTrumpBmp[i].visible = TRUE @OneTrumpBmp[i].x = 640 / 2 - 32 @OneTrumpBmp[i].y = -96 end for i in 0..51 @TrumpsRow[i] = i end for i in 0..51 j = rand(52) tmp = @TrumpsRow[j] @TrumpsRow[j] = @TrumpsRow[i] @TrumpsRow[i] = tmp end @JackPhase = 1 @JackCount = 0 when 12 # 終了する # マップ画面に切り替え $scene = Scene_Map.new end # ゲーム画面を更新 Graphics.update # 入力情報を更新 Input.update # フレーム更新 update # 画面が切り替わったらループを中断 if $scene != self break end end # トランジション準備 Graphics.freeze #開放します @AceChoice_window.dispose @Hit_Stay_window.dispose @command_window.dispose @JackBack.dispose @Trump.dispose @Bet_window.dispose @gold_window.dispose for i in 0..51 @OneTrumpBmp[i].dispose end @StackBmp.dispose @Help_window.dispose @Bet_windowPare.dispose @rate_window.dispose end #-------------------------------------------------------------------------- # ★ フレーム更新 #-------------------------------------------------------------------------- def update # ウィンドウを更新 @gold_window.update @rate_window.update #ヒットorステイウィンドウの更新 if @Hit_Stay_window.active @Hit_Stay_window.update update_Hit_Stay #return end #ベットウィンドウの更新 if @Bet_window.active @Bet_window.update @Bet_windowPare.update update_Bet #return end #ベットウィンドウの更新 if @command_window.active @command_window.update update_command #return end #Ace選択ウィンドウ更新 if @AceChoice_window.active @AceChoice_window.update update_command #return end end #---------------------- ---------------------------------------------------- # ★ フレーム更新(賭け金入力ウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_Bet if Input.trigger?(Input::B) # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) @JackPhase = 12 end # C ボタンが押された場合 if Input.trigger?(Input::C) #所持金以下か? if @Bet_window.number <= $game_party.gold if @Bet_window.number > 0 # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) @Help_window.set_text(" ") @Bet_window.active = FALSE @JackPhase = 3 @p = 0 @Bet = @Bet_window.number $game_party.lose_gold(@Bet) @gold_window.refresh @NextHit = 0 DealerCardInsert() PlayerCardInsert() DealerCardInsert() PlayerCardInsert() else #ブザー $game_system.se_play($data_system.buzzer_se ) @Help_window.set_text("1#{$data_system.words.gold}以上を指定してください。") end else #ブザー $game_system.se_play($data_system.buzzer_se ) @Help_window.set_text("お金が足りないようです。") end return end end #-------------------------------------------------------------------------- # ● フレーム更新 (ヒットステイ選択ウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_Hit_Stay # C ボタンが押された場合 if Input.trigger?(Input::C) # コマンドウィンドウのカーソル位置で分岐 case @Hit_Stay_window.index when 0 # ヒット # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) @Help_window.set_text("ヒットします。") @Hit_Stay_window.active = FALSE @JackPhase = 5 when 1 # ステイ # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) @Hit_Stay_window.active = FALSE trumpPrint(@DealerNext,@dealerCards[@dealerInsert-1],TRUE) DealerSumCheck() @JackPhase = 7 end return end end #-------------------------------------------------------------------------- # ● フレーム更新 (コマンドウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_command # B ボタンが押された場合 if Input.trigger?(Input::B) # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) # マップ画面に切り替え $scene = Scene_Map.new return end # C ボタンが押された場合 if Input.trigger?(Input::C) if @JackPhase == 10 # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) case @command_window.index when 0 # 続けます @JackPhase = 11 when 1 # やめます。(賞金支払いフェイズへ) @JackPhase = 12 end else # コマンドウィンドウのカーソル位置で分岐 case @command_window.index when 0 # やります #一文無しならダメです。 if $game_party.gold == 0 #ブザー $game_system.se_play($data_system.buzzer_se ) @Help_window.set_text("お金が足りないようです。") else # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) @Help_window.set_text(" ") @command_window.active = FALSE @command_window.visible = FALSE @JackPhase = 1 end when 1 # やりません # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # マップ画面に切り替え $scene = Scene_Map.new end end return end end #-------------------------------------------------------------------------- # ★ プレイヤーにカード挿入 #-------------------------------------------------------------------------- def PlayerCardInsert @playerCards[@playerInsert] = @TrumpsRow[@motherOut] @playerInsert = @playerInsert + 1 @motherOut = @motherOut + 1 end #-------------------------------------------------------------------------- # ★ ディーラーにカード挿入 #-------------------------------------------------------------------------- def DealerCardInsert @dealerCards[@dealerInsert] = @TrumpsRow[@motherOut] @dealerInsert = @dealerInsert + 1 @motherOut = @motherOut + 1 end #-------------------------------------------------------------------------- # ★ プレイヤーのカードの合計を取る。 #-------------------------------------------------------------------------- def PlayerSumCheck() sum = 0 acecount = 0 for i in 0...@playerInsert count = (@playerCards[i] % 13) + 1 if count > 10 # J,Q,Kは10と数える。 count = 10 end if count == 1 # Aを持っていた場合。 acecount = acecount + 1 count = 0 end sum = sum + count end while acecount > 0 if sum+11 > 21 sum = sum + 1 else sum = sum + 11 end acecount = acecount - 1 end @Help_window.set_text("プレイヤーの合計値:#{sum}") @playerSum = sum end #-------------------------------------------------------------------------- # ★ ディーラーのカードの合計を取る。 #-------------------------------------------------------------------------- def DealerSumCheck() sum = 0 acecount = 0 for i in 0...@dealerInsert count = (@dealerCards[i] % 13) + 1 if count > 10 # J,Q,Kは10と数える。 count = 10 end if count == 1 # Aを持っていた場合。 acecount = acecount + 1 count = 0 end sum = sum + count end while acecount > 0 if sum+11 > 21 sum = sum + 1 else sum = sum + 11 end acecount = acecount - 1 end @Help_window.set_text("ディーラーの合計値:#{sum}") @dealerSum = sum end #-------------------------------------------------------------------------- # ★ カード表示 # 任意のスーツ、数字のカードをx,yに表示する #-------------------------------------------------------------------------- def trumpPrint( card,num,flag) # num = num - 1 if flag == TRUE @OneTrumpBmp[card].bitmap.blt(0, 0, @Trump.bitmap, Rect.new(((num % 13) * 64),((num / 13) * 96), 64, 96)) else @OneTrumpBmp[card].bitmap.blt(0, 0, @Trump.bitmap, Rect.new(320,384, 64, 96)) end end end