HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0415
yuyu丸罰ゲームの判定6未解決


yuyu

リンク

2016/4/15(Fri) 20:24:24|NO.75229

○と×をマス目においていって縦横斜めに3つなどそろったら勝ちという
普通の丸罰ゲームをつくっているのですが、
どうやって揃うことの判定をしたらいいでしょうか。

マス目に番号を当てて、○が入っているか、
×が入っているかの判定はつきます。



この記事に返信する


GENKI

リンク

2016/4/15(Fri) 20:50:28|NO.75230

3x3のマスを○と×で埋めるゲームですね。
1列そろうパターンは8パターンしかありませんよね。
これぐらいなら毎回、全ての「そろうパターン」を調べてしまっていいのではないでしょうか?



Noap

リンク

2016/4/16(Sat) 14:47:51|NO.75231

答えになっているかはわかりませんが、つくりました。
定数の数値を変更すればプレイヤーの数と縦横の大きさを変えられます。


// 丸三角バツゲーム // プレイヤー数 // 増やす場合などは msgs_btns もいっしょにかきかえる #const int NUM_PLAYER 3 // 1行のボタンの数 #const int NUM_BTN_LINE 11 #const int NUM_BTN (NUM_BTN_LINE * NUM_BTN_LINE) // ボタンサイズ #const int X_SIZE_BTN 30 #const int Y_SIZE_BTN 30 #const int X_SIZE_WIN (X_SIZE_BTN * NUM_BTN_LINE) #const int Y_SIZE_WIN (Y_SIZE_BTN * (NUM_BTN_LINE + 1)) #const int LEN_FLAG_BTNS (NUM_BTN / 32 + 1) // フラグ設定マクロ #define set_flag_btn(%1,%2) flags_btns((%2)/32, (%1)) |= 1<<((%2)\32) #define ctype get_flag_btn(%1,%2) ( (flags_btns((%2)/32, (%1)) >> ((%2)\32)) & 1 ) #define del_flag_all_btn(%1) memset flags_btns(0, (%1)),, LEN_FLAG_BTNS * 4 // ボタンが押されたかどうかのフラグ #define set_flag_pushed_btn(%1) flags_pushed_btns((%1)/32) |= 1<<((%1)\32) #define ctype get_flag_pushed_btn(%1) ( (flags_pushed_btns((%1)/32) >> ((%1)\32)) & 1 ) #define del_flag_all_pushed_btn memset flags_pushed_btns,, LEN_FLAG_BTNS * 4 // 全部のボタンが押されたかのチェック #define CHECK_PUSHED_ALL_BTNS _check_pushed_all_btns_( flags_pushed_btns, NUM_BTN) #module #defcfunc _check_pushed_all_btns_ array flags, int num,\ local tmp tmp = 1 repeat num/32 if flags(cnt) != -1 { tmp = 0 : break } loop return tmp * ((flags(num/32) | (-1 << (num\32))) == -1) #global // 変数 dim flags_btns, LEN_FLAG_BTNS, NUM_PLAYER msgs_btns = "○", "△", "×" // プレイヤーの数に合わせる dim flags_pushed_btns, LEN_FLAG_BTNS turn_player = 0 // 画面 screen 0, X_SIZE_WIN, Y_SIZE_WIN,,,, X_SIZE_WIN, Y_SIZE_WIN objsize X_SIZE_BTN, Y_SIZE_BTN repeat NUM_BTN pos X_SIZE_BTN * (cnt\NUM_BTN_LINE), Y_SIZE_BTN * (cnt/NUM_BTN_LINE) button gosub "", *check_btn loop pos 0, ginfo_cy objsize X_SIZE_WIN, Y_SIZE_BTN button gosub "初期化", *init_btns gosub *init_btns stop // 初期化 *init_btns repeat NUM_BTN objprm cnt, "" loop repeat NUM_PLAYER del_flag_all_btn cnt loop del_flag_all_pushed_btn turn_player = 0 gosub *title_window return // ウィンドウタイトル *title_window title msgs_btns(turn_player) + "の番" return // ダイアログメッセージの作成 *make_msg_dialog msg_dialog = "" is_win-- if is_win { msg_dialog = msgs_btns(turn_player) + "のかち!\n" + is_win + "本そろいました" }else{ msg_dialog = "引き分け!" } return // ボタンにチェック *check_btn idx_btn = stat do if get_flag_pushed_btn(idx_btn) : _break set_flag_pushed_btn idx_btn set_flag_btn turn_player, idx_btn objprm idx_btn, msgs_btns(turn_player) gosub *check_win // 結果表示 if is_win == 0 : is_win = CHECK_PUSHED_ALL_BTNS : else :is_win++ // 引き分けまたはかち if is_win { gosub *make_msg_dialog dialog msg_dialog gosub *init_btns _break } turn_player++ if turn_player == NUM_PLAYER : turn_player=0 until gosub *title_window return // 勝ち判定 *check_win is_win = 0 // 横の判定 if get_flag_btn(turn_player, idx_btn - (idx_btn \ NUM_BTN_LINE)) { is_win ++ repeat NUM_BTN_LINE, idx_btn - (idx_btn \ NUM_BTN_LINE) if get_flag_btn(turn_player, cnt) == 0 { is_win -- : break } loop } // 縦の判定 if get_flag_btn(turn_player, idx_btn \ NUM_BTN_LINE) { is_win ++ repeat NUM_BTN_LINE if get_flag_btn(turn_player, cnt*NUM_BTN_LINE + (idx_btn \ NUM_BTN_LINE)) == 0 { is_win -- : break } loop } // 左斜めの判定 if (idx_btn / NUM_BTN_LINE) == (idx_btn \ NUM_BTN_LINE) { is_win ++ repeat NUM_BTN_LINE if get_flag_btn(turn_player, cnt*NUM_BTN_LINE + cnt) == 0 { is_win -- : break } loop } // 右斜めの判定 if (idx_btn / NUM_BTN_LINE) == (NUM_BTN_LINE - (idx_btn \ NUM_BTN_LINE) -1) { is_win ++ repeat NUM_BTN_LINE if get_flag_btn(turn_player, cnt*NUM_BTN_LINE + (NUM_BTN_LINE - cnt -1)) == 0 { is_win -- : break } loop } return



yuyu

リンク

2016/4/16(Sat) 21:50:58|NO.75233

ありがとうございます。
Noapさんのスプりクトですが、残念ながら実行
できませんでした。

結果レポート
#HSP script preprocessor ver3.4 / onion software 1997-2014(c)
#Use file [hspdef.as]
#Error:symbol in use [int] in line 7 [???]
#Fatal error reported.


スプりクトを参考にやってみます。



暇人

リンク

2016/4/16(Sat) 23:06:22|NO.75235

>#HSP script preprocessor ver3.4 / onion software

HSP3.5β3で#constにint指定が追加されたので3.4じゃ動かない

>2016/01/19 3.5 beta3
>[hspcmp] #constの後に「double」「int」の型を指定できるように修正



Drip

リンク

2016/4/17(Sun) 13:30:51|NO.75238

Dripです。

yuyuさん、こんにちは。
可読性を加味してどこまで簡素化できるか挑戦したくなったので作ってみました^^;
参考になれば幸いです。

#define max 3 //縦横マスの数 #define btnsz 64 //ボタンサイズ objsize btnsz,btnsz //ボタンのサイズを設定 font "",btnsz/2:objmode 2 //ボタンの文字を大きくしておく dim masu,max*max //マスの状態を管理する変数(0:空白 1:○ 2:× ) repeat max*max //ボタンを正方形に配置 pos cnt\max*btnsz,cnt/max*btnsz button "",*push loop stop *push //★ボタンが押されたときの処理 id=stat //押されたボタンIDがstatに返るのでidにボタンIDを確保しておく objprm id,"○" //押されたボタンを○に書き換える masu(id)=1 //押されたボタンのIDと同じmasuの配列に情報を反映しておく(1が○) objenable id,0 //押されたボタンをもう押せなくする prm=1:gosub *chk //○が並んだか判定する if ans:mes "○のかち!":goto *gameset //○が並んでたらゲームセット repeat max*max,rnd(max*max) //適当に敵が× を配置する処理 id=cnt\(max*max) //調べるマスのid if masu(id)=0:{ //マスが空白だったら配置処理 objprm id,"×" //ボタンを× に書き換える masu(id)=2 //ボタンのIDと同じmasuの配列に情報を反映しておく(2が× ) objenable id,0 //敵が押したボタンをもう押せなくする prm=2:gosub *chk //× が並んだか判定する(結果をansに代入、ansが1なら並んだ) break } loop if ans:mes "×のかち!":goto *gameset //× が並んでたらゲームセット if prm!2:mes "引き分け!":goto *gameset //敵が配置できなかったのでゲームセット stop *chk //★prm(1:○ 2:× )の記号が並んでるか判定してansに結果を返すサブルーチン ans=0,0,0 //ansが1になればprmの記号が並んだことを示す //ans(1)は左上から右下に向かってprmの記号が斜めに並んだ量 //ans(2)は右上から左下に向かってprmの記号が斜めに並んだ量 repeat max id=cnt //縦横方向の検索シードとなる数値 ans(3)=0,0 //ans(3)は縦に向かってprmの記号が並んだ量(シード毎にリセット) //ans(4)は横に向かってprmの記号が並んだ量(シード毎にリセット) repeat max if masu(id+cnt*max)=prm:ans(3)++ //縦に並んでる数をカウント if masu(id*max+cnt)=prm:ans(4)++ //横に並んでる数をカウント loop if ans(3)=max | ans(4)=max:ans=1:break //縦、あるいは横にprmの記号が全て並んだらansを1にして処理終了 if masu(cnt+cnt*max)=prm:ans(1)++ //左上から右下に向かってprmの記号が並んだ数をカウント if masu(max-cnt-1+cnt*max)=prm:ans(2)++ //右上から左下に向かってprmの記号が並んだ数をカウント loop if ans(1)=max | ans(2)=max:ans=1 //斜めにprmの記号が全て並んだらansを1にする return *gameset //★ゲームセット、全てのボタンを押せなくする repeat max*max:objenable cnt,0:loop stop



Humi/bass_clef_

リンク

2016/4/19(Tue) 19:42:45|NO.75270

んじゃ私は勝ち負けの判定が特殊なものを書きましょか。
仕組みがわかるともう少しループの回数をへらせるはず、、、


#enum XO_STATE_NONE = 0 #enum XO_STATE_X #enum XO_STATE_O #enum XO_PLAYER_MAX max = 3 // 縦横の数,奇数しか対応してないれす buttonWidth = 30 // ボタンの大きさ buttonHeight = 30 xoText = "", "×", "○" // 表示する文字 playerXO = XO_STATE_X // 最初の状態 playerWon = 0 dim xPlayerCount, max, XO_PLAYER_MAX // x が押された数 dim yPlayerCount, max, XO_PLAYER_MAX // y が押された数 dim xoXYFromButtonId, max * max // x と y からボタンIDを取得 dim xoButtonIdList, max, max // ボタンIDから y*max+x を取得 dim xoState, max, max // ボタンの状態 screen 0, buttonWidth * max, buttonHeight * max + buttonHeight objsize buttonWidth, buttonHeight for i, 0, max, 1 repeat max pos cnt*buttonWidth, i*buttonHeight +buttonHeight/2 button gosub xoText.0, *pushedButton xoButtonIdList( cnt, i ) = stat xoXYFromButtonId(stat) = i*max + cnt loop next objsize buttonWidth*max, buttonHeight/2 pos 0 button gosub "最初から", *init pos 0, 0 button gosub ""+ xoText.playerXO +"の番です", *dummy :displayId = stat objenable displayId, 0 stop *dummy return *init // 初期化 for i, 0, max, 1 repeat XO_PLAYER_MAX-1 xPlayerCount(i, 1+cnt) = 0 yPlayerCount(i, 1+cnt) = 0 loop repeat max objprm xoButtonIdList( cnt, i ), xoText.XO_STATE_NONE objenable xoButtonIdList( cnt, i ), 1 xoState( cnt, i ) = XO_STATE_NONE loop next objprm displayId, ""+ xoText.playerXO +"の番です" playerWon = 0 allCount = 0 return *pushedButton buttonId = stat objprm buttonId, xoText.playerXO objenable buttonId, 0 allCount++ // プレイヤーの押した場所を記録 x = xoXYFromButtonId(buttonId)\max y = xoXYFromButtonId(buttonId)/max xoState( x, y ) = playerXO // プレイヤーがその列を押した回数を記録 xPlayerCount( x, playerXO )++ yPlayerCount( y, playerXO )++ repeat XO_PLAYER_MAX-1, 1 checkWin cnt if stat { objprm displayId, ""+ xoText(cnt) +" の勝ち" repeat max*max objenable xoButtonIdList(cnt\max, cnt/max), 0 loop break } loop if playerWon :return if allCount == max*max { objprm displayId, "引き分けです" return } playerXO = ((playerXO-1)+1)\(XO_PLAYER_MAX-1)+1 objprm displayId, ""+ xoText.playerXO +"の番です" return #deffunc checkWin int checkState playerWon = 0 // 縦横の判定 (プレイヤーがその列を押した回数で判定) repeat max if max == xPlayerCount(cnt, checkState) || max == yPlayerCount(cnt, checkState) { playerWon = 1 break } loop if playerWon :return 1 // 斜めの判定 (中央と斜めの反対を見るだけでいい) // プレイヤーが中央を取ってない場合は判定すらしない if checkState == xoState( max/2, max/2 ) { // 一つは x と y が同じ場所 slantCount = 0 repeat max/2 if checkState == xoState( cnt, cnt ) :slantCount++ if checkState == xoState( max-1-cnt, max-1-cnt ) :slantCount++ loop if max-1 == slantCount :playerWon = 1 :return 1 // もう一つは x と y を足して max-1 の場所、かつ x と y が反転している場所 slantCount = 0 repeat max/2 if checkState == xoState( cnt, max-1-cnt ) :slantCount++ if checkState == xoState( max-1-cnt, cnt ) :slantCount++ loop if max-1 == slantCount :playerWon = 1 :return 1 } return 0



ONION software Copyright 1997-2021(c) All rights reserved.