/* ポーカー サンプルスクリプト ゲーム製作メモ http://minus273.s27.xrea.com/prog/ HSP3.0用 2005-08-23 作成開始。 2005-08-25 とりあえず完成。 */ ;----------いろいろな設定など #define VER "1.00" #define SOFTNAME "ポーカーのサンプル" #define TITLEBAR SOFTNAME+" "+VER #define EXENAME "poker" #packopt type 0 #packopt name EXENAME #packopt runtime "hsp3c.hrt" #packopt hide 0 randomize ;----------ウインドウの作成 screen 0,640,480 : title "ID 0: "+TITLEBAR font "MS ゴシック",48,16 width ,,0,0 screen 1,,,4 : title "ID 1: トランプのスート画像" ;実際にはbufferにすべき picload "poker_card.bmp",0 width ,,650,0 screen 2,640,360,4 : title "ID 2: 変数の中身を表示" if ginfo_dispy>=1024 : width ,,0,510 : else : width ,,0,340 ;----------初期化 *init ;主な変数の宣言 HSPではしなくてもいいけど ;したほうがあとから何の変数かわかりやすい dim yamafuda,52 dim tefuda,5 ;なお、トランプは数字でカードの種類(スート)を表します。 ;たとえばハートの2は14番。 ;スペード:0〜12 ハート:13〜25 ;ダイヤ:26〜38 クラブ:39〜51 repeat 52 yamafuda(cnt)=-1 ;まだカードが決まっていないところは-1で区別する loop repeat 5 tefuda(cnt)=-1 ;まだカードが決まっていないところは-1で区別する loop dim hantei_suit,5 ;カードのマーク 役判定で使う dim hantei_num,5 ;カードの数字 役判定で使う game_count=0 ;5回ごとに山札をシャッフルするためにゲーム回数をカウント bet=0 ;掛け金 money=100 ;持ち金 game_stat=0 ;今の状態 ;0:新しいゲーム 1:bet 2:カード交換 gsel 0 pos 520,280 : objsize 100,32,36 button "bet 1",*bet_1 button "bet 10",*bet_10 button "bet 100",*bet_100 button "bet 1000",*bet_1000 pos 520,440 : button "次へ",*tugi gsel 0,1 wait 1 ;----------メインループ *main await 33 ;1秒に30回くらいループする if game_stat=0 { if game_count=0 { gosub *shuffle ;山札をシャッフル game_count=5 } bet=0 game_stat=1 game_count-- } if game_stat=2 { ;カードがクリックされているかチェックする gsel 0 ;mousexとmouseyは描画対象のウインドウのカーソル座標 stick ky if ky&256 { ;左クリックされたら if (320<=mousey) & (mousey<=458) { x=16 repeat 5 if (x<=mousex) & (mousex<=(x+95)) { tefuda(cnt)=-1 ;クリックされたカードは消す } x+=96 loop } } } ;いろいろ描画 gsel 0 : title "ID 0: mousex = "+mousex+" mousey = "+mousey gosub *all_draw goto *main ;----------サブルーチン *bet_1 if game_stat=1 : bet++ if bet>9999 : bet=9999 if bet>money : bet=money goto *main *bet_10 if game_stat=1 : bet+=10 if bet>9999 : bet=9999 if bet>money : bet=money goto *main *bet_100 if game_stat=1 : bet+=100 if bet>9999 : bet=9999 if bet>money : bet=money goto *main *bet_1000 if game_stat=1 : bet+=1000 if bet>9999 : bet=9999 if bet>money : bet=money goto *main *tugi if game_stat=2 { gosub *deal gosub *hantei game_stat=0 repeat 5 tefuda(cnt)=-1 loop } if game_stat=1 { if bet=0 : bet=10 ;こういう細かな気配りが遊びやすさにつながる gosub *deal game_stat=2 } goto *main *all_draw ;メインウインドウと変数確認ウインドウの描画 ;ちなみに、マニュアルには書いてないけど引数なしのboxfは画面全体を塗りつぶすみたい gsel 0 redraw 0 color 255,255,255 : boxf gosub *tefuda_draw gosub *bet_draw redraw 1 gsel 2 redraw 0 color 255,255,255 : boxf gosub *variable_draw redraw 1 return *tefuda_draw ;手札を描画 x=16 : y=320 repeat 5 if tefuda(cnt)=-1 : x+=96 : continue ;捨てたのは描画しない card_suit = tefuda(cnt) / 13 ;13で割った商がスート(マーク) card_num = (tefuda(cnt) \ 13) + 1 ;13で割ったあまり+1が数字 ;絵札を記号に変換したり。軽い処理なのでelseは使わなかった。 if card_num<10 : card_num_str=" "+card_num if card_num=10 : card_num_str=10 if card_num=11 : card_num_str=" J" if card_num=12 : card_num_str=" Q" if card_num=13 : card_num_str=" K" color 0,0,0 : boxf x,y,x+95,y+137 color 255,255,255 : boxf x+1,y+1,x+94,y+136 pos x+16,y+8 : gcopy 1,64*card_suit,0,64,64 pos x+24,y+80 : color 0,0,0 : mes card_num_str x+=96 loop return *bet_draw ;掛け金その他の描画 ;(このくらいなら *tefuda_draw と一緒にしてもよさそうだけど) color 0,0,0 pos 360,180 : mes "money:"+money pos 360,230 : mes " bet:"+bet pos 0,0 if game_stat=0 : mes "山札をシャッフル中……\n(ボタンを押さないで下さい)" if game_stat=1 : mes "betしてください" if game_stat=2 : mes "捨てるカードをクリック\nしてください" return *variable_draw ;山札、手札等の変数の内容をウインドウID3に表示 redraw 0 pos 0,0 : color 0,0,0 : x=0 repeat 52 mes "yamafuda("+cnt+") = "+yamafuda(cnt) if cnt\13=12 : x+=160 : pos x,0 loop pos 0,240 repeat 5 mes "tefuda("+cnt+") = "+tefuda(cnt) loop pos 160,240 mes "game_stat = "+game_stat mes "game_count = "+game_count mes "bet = "+bet pos 320,240 : mes " 0〜12:スペード\n13〜25:ハート\n26〜38:ダイヤ\n39〜51:クラブ" pos 160 : mes "注意:手札を配っているときにボタンを押さないでください" redraw 1 return *shuffle ;山札をシャッフル。かなり強引な方法なので遅い。 ;カードが多い場合はもっとスマートな方法を考えましょう。 gsel 2 : title "ID 2: シャッフル中……" repeat 52 yamafuda(cnt)=-1 ;まだカードが決まっていないところは-1で区別する loop ;シャッフルされる様子を表示するため、あえてwaitを入れました。 ;wait と gosub *all_draw をコメントにすれば速くシャッフルできます。 repeat 52 wait 1 tmp=rnd(52) ;山札からランダムに一枚選ぶ if yamafuda(tmp)!=-1 { continue cnt ;すでに決まっていた場合はやり直し } else { ;まだどのカードか決まっていなければ yamafuda(tmp)=cnt ;カードの番号をセット gosub *all_draw ;シャッフルされる様子を表示 } loop gsel 2 : title "ID 2: シャッフル終了" wait 50 return *deal ;手札を配る(シャッフルと同様にwait入れています) ;山札の最初から見ていき、カードがあるところから順番に配る gsel 2 : title "ID 2: 手札を配っています……" repeat if yamafuda(cnt)!=-1 : i=cnt : break loop repeat 5 if tefuda(cnt)!=-1 : continue ;捨てていない手札は配らない wait 20 tefuda(cnt)=yamafuda(i) yamafuda(i)=-1 ;配ったカードをなくすのを忘れずに i++ gosub *all_draw ;配られる様子を表示 loop gsel 2 : title "ID 2: 手札を配りました" return *hantei ;役判定 同じようなことを何度もやっていてスマートではないです get_money = -bet : one_pair=0 : three_card=0 : flash=0 : straight=0 hantei_mes = "ノーペア\n"+bet+" * -1 = "+get_money ;デフォルト(標準)のメッセージ repeat 5 hantei_suit(cnt) = tefuda(cnt) / 13 ;13で割った商がスート(マーク) hantei_num(cnt) = (tefuda(cnt) \ 13) + 1 ;13で割ったあまり+1が数字 loop ;カードを数字の小さい順に並べなおす バブルソートというアルゴリズムを使っています i=4 repeat 4 repeat i if (hantei_num(cnt)) > (hantei_num(cnt+1)) { ;数字を入れ替える tmp = hantei_num(cnt) hantei_num(cnt) = hantei_num(cnt+1) hantei_num(cnt+1) = tmp } loop i-- loop ;ワンペア repeat 4 if (hantei_num(cnt)) = (hantei_num(cnt+1)) { get_money=bet hantei_mes="ワンペア!\n"+bet+" * 1 = "+get_money one_pair++ } loop ;ツーペア if one_pair=2 { get_money=bet*2 hantei_mes="ツーペア!\n"+bet+" * 2 = "+get_money } ;スリーカード repeat 3 if (hantei_num(cnt)) = (hantei_num(cnt+1)) { if (hantei_num(cnt+1)) = (hantei_num(cnt+2)) { get_money=bet*5 hantei_mes="スリーカード!\n"+bet+" * 5 = "+get_money three_card=1 } } loop ;ストレート repeat 4 if cnt=0 { ;最初が1のときは13ともつなげられるので特別な処理 if hantei_num(0) = 1 { if hantei_num(1) = 10 : { continue } ;1の次が10なら判定続行 } } if ((hantei_num(cnt)) + 1) != (hantei_num(cnt+1)) : break if cnt=3 { get_money=bet*10 hantei_mes="ストレート!\n"+bet+" * 10 = "+get_money straight=1 } loop ;フラッシュ repeat 4 if hantei_suit(cnt+1) != hantei_suit(0) : break if cnt=3 { get_money=bet*20 hantei_mes="フラッシュ!\n"+bet+" * 20 = "+get_money flash=1 } loop ;フルハウス if (one_pair=1) & (three_card=1) { get_money=bet*30 hantei_mes="フルハウス!\n"+bet+" * 30 = "+get_money } ;フォーカード repeat 2 if (hantei_num(cnt)) = (hantei_num(cnt+1)) { if (hantei_num(cnt+1)) = (hantei_num(cnt+2)) { if (hantei_num(cnt+2)) = (hantei_num(cnt+3)) { get_money=bet*50 hantei_mes="フォーカード!\n"+bet+" * 50 = "+get_money } } } loop ;ストレートフラッシュ if (straight=1) & (flash=1) { get_money=bet*100 hantei_mes="ストレートフラッシュ!\n"+bet+" * 100 = "+get_money } ;ロイヤルストレートフラッシュ if (straight=1) & (flash=1) { if (hantei_num(0)=1) & (hantei_num(4)=13) { get_money=bet*500 hantei_mes="ロイヤルストレートフラッシュ!\n"+bet+" * 500 = "+get_money } } dialog hantei_mes money += get_money if money<=0 : dialog "ゲームオーバー" : end return