taQu_rule(5) taQu Rule Engine Reference taQu_rule(5)

Name

taQu_rule — taQu カスタムルール記述言語リファレンス (v1.5.0)

Synopsis

メタデータ宣言
    rule = "ルール名"
    description = "説明文"
    maxAns = 数値
    const NAME = 整数
    変数.label = "ラベル"
    sync(変数)

イベント定義
    def correct():  |  def wrong():  |  def through():
    def push():    |  def next():

制御構文
    if 条件:   |  else:
    switch :  |  case :  |  default:

コマンド
    win()  |  lose()  |  lock()  |  unlock()
    tLock()  |  tUnlock()  |  pass
    giveAns(条件)  |  throughAns()
    othersAdd(var, val)  |  othersSet(var, val)
    tAdd(var, val)  |  tSet(var, val)
    setBorderColor()  |  resetBorderColor()
    scope(条件):

Description

taQu のカスタムルールを記述するためのインデントベース言語です。Python ライクな構文でクイズ早押しゲームのルールを定義します。

文字コード
UTF-8 推奨。
コメント
# 以降の文字はすべて無視されます。
インデント
半角スペースによるインデントでブロックを表現します。
文字列リテラル
"..." および '...' のどちらも使用できます。

Metadata

def の外側(ファイル先頭付近)に記述します。

構文説明
rule = "名前" ルール名。[定数名] で定数値を展開できます。
description = "説明" ルールの説明文。同様に [定数名] 展開が使えます。
maxAns = N 1 問あたりの最大回答人数。デフォルト 10 で無制限(エンドレスチャンス)。
const NAME = 整数 定数を定義します。実行時に必ず定数値で上書きされます。ルール選択 GUI から変更可能。
x|y|z.label = "文字列" 変数のラベルを設定します。未設定の変数は画面に表示されません。
sync(x|y|z) 変数をチーム内で同期します(詳細は TEAM セクション参照)。
const TARGET = 7
rule = "セブンス[TARGET]"
description = "[TARGET]ポイント先取で勝利"
maxAns = 1
x.label = "pts"

Variables

組み込み変数(表示用)

画面に表示できる変数は x, y, z の 3 つのみです。ラベル未設定の変数は非表示になります。

組み込み読み取り専用変数

変数名説明
mt チームインデックス。チーム名をアルファベット順にソートした順番(1 始まり)。チーム未所属のソロは 0

カスタム変数

x, y, z 以外の任意の名前(例: hp, phase)も使用できます。def の外で代入すると初期値として扱われます。画面には表示されません。カスタム変数は各プレイヤーごとに独立して保持され、scope() 内での代入も正しく各プレイヤーに保存されます。

phase = 0   # 全プレイヤーの初期値を 0 に設定

def push():
  if phase == 0:
    phase = 1
    scope(my_mt == mt):
      phase = 1   # チームメンバーにも phase=1 が保存される

my_ プレフィックス

scope() の条件式・ブロック内、および othersAdd / othersSet / tAdd / tSet の値式の中で使います。

参照(読み取り)
コマンドを発行したプレイヤー自身の変数を参照します。
代入(書き込み)
scope() のブロック内で my_x = 式 と書くと、各対象プレイヤーへの処理中に発行者自身の変数へ書き込みます。+= / -= / *= も使用可能です。
othersSet(x, my_x)       # 自分以外全員のxに「自分のx値」をセット
scope(mt == my_mt):       # 自分と同じチームのプレイヤーに実行
    x += my_x             # 対象メンバーのxに自分のxを加算(参照)

scope(mt == my_mt and x >= 10):
    my_z += 1             # 条件を満たすチームメンバーの数を発行者のzに積算(代入)

チーム集計関数

構文説明
tProd(var) チーム全員(自分含む)の指定変数の を返します。

全体集計関数

構文説明
rankVal(var, n) 全プレイヤー中で指定変数 var の値が n 番目(降順)のプレイヤーのその変数値を返します。n が範囲外の場合は 0 を返します。

特殊関数

構文説明
rand(min, max) min 以上 max 未満のランダムな整数を返します。対象プレイヤーごとに独立した乱数が生成されます。
floor() 式の結果を小数切り捨てして返します。
/(除算)演算子はすでに整数除算(切り捨て)として動作します。floor() は複合式の切り捨てに使います。

Events

def イベント名(): の形式でイベントハンドラを定義します。def外側に書いたコードは、プレイヤーが参加した時点の初期化処理として実行されます。

イベント名実行タイミング対象
def correct(): ホストが「正解」を押したとき 現在の回答者のみ
def wrong(): ホストが「不正解」を押したとき 現在の回答者のみ
def through(): ホストが「スルー」を押したとき 回答者がいれば回答者のみ。いなければ誰にも実行されない
def push(): プレイヤーが早押しボタンを押した瞬間 押したプレイヤーのみ
def next(): correct / wrong / through のいずれかの処理が完了した後 全プレイヤー(一人ずつ順番に実行)

push() 内の処理順序

push() でキューに積んだコマンドは、ルール実行後に以下の順で処理されます。

  1. scope() — 対象プレイヤーへの変数操作
  2. giveAns() — 解答権の付与
  3. throughAns() — 解答権の放棄(カーソル前進)
  4. 解答者の決定(updateRoomAnswerState
giveAns() が先に実行されてから throughAns() でカーソルが調整されるため、「他の人に渡して自分は解答権なし」という組み合わせが正しく動作します。

Operators

代入演算子

演算子意味
x = 代入
x += 加算代入
x -= 減算代入
x *= 乗算代入

算術演算子

演算子意味備考
+加算
-減算
*乗算
/整数除算(切り捨て)ゼロ除算は 0 を返す
%剰余ゼロ除算は 0 を返す
^べき乗x ^ 2 → x の 2 乗

比較・論理演算子

演算子別記法意味
==等しい
!=等しくない
>より大きい
<より小さい
>=以上
<=以下
and&&論理積(両方真のとき 1)
or||論理和(どちらか真のとき 1)

条件分岐 (if / else)

# 基本形
if x >= 10:
    win()
else:
    x += 1

# ネスト
if x > 0:
    if x == 5 and y == 0:
        z += 2
    else:
        z += 1

# 1行 if(インライン形式)
if x >= 10: win()

多分岐 (switch / case / default)

変数や式の値に応じて処理を切り替えます。マッチしたケースだけが実行され、以降のケースには処理が流れません(フォールスルーなし)。連続する if と異なり、あるケース内で変数を変更しても他のケースに影響しません。

switch phase:
    case 0:
        x += 3
        phase = 1
    case 1:
        x += 1
        phase = 0
    default:
        pass
複数の if を並べると、1つ目の if 内で変数を書き換えた場合に2つ目の if が意図せず真になることがあります。フェーズ遷移のような「状態で処理を切り替える」用途では switch/case を推奨します。

Commands

状態変更コマンド

コマンド説明
win()勝利状態にします。以降の処理は実行されません。
lose()敗北状態にします。以降の処理は実行されません。
lock()そのプレイヤーの回答権をロック(ボタンを押せなくする)。
unlock()ロックを解除します。
tLock()チーム全体の回答権をロックします。
tUnlock()チーム全体のロックを解除します。
pass何もしません(空のブロックで使用)。
setBorderColor()そのプレイヤーのカード囲み線の色を設定します。色は #rrggbbred など CSS に有効な値を指定します。
resetBorderColor()setBorderColor() で設定した周り線の色をリセットします。

解答権操作コマンド

コマンド使用可能なイベント説明
giveAns(条件) すべてのイベント 条件を満たすプレイヤーの中からランダムに 1 人を選び、解答権を付与します。
push() 内:まだボタンを押していない(isPressed=false)プレイヤーが対象になります。
correct / wrong / through 内:その問のリセット後に実行されるため、ボタンを押していたプレイヤーも対象になります。
発行者自身と、ホストは対象外です。
throughAns() 主に push() ボタンを押した事実(isPressed)は残したまま、そのプレイヤーの解答権だけを消します。同じターン内で再度ボタンを押すことはできません。
giveAns() と組み合わせることで「ボタンを押したら自分ではなくチームメンバーが回答者になる」仕組みを実現できます。
# push() でチームメンバーに解答権を渡し、自分は解答しない例
def push():
    if phase == 0:
        giveAns(my_mt == mt)   # 同チームのメンバーに解答権を渡す
        throughAns()            # 自分の解答権を放棄(isPressed は残る)
        scope(my_mt == mt):
            phase = 1
throughAns()push() 以外(correct / wrong / through)でも呼べますが、それらのイベントでは通常のリセット処理と組み合わせるため動作が複雑になります。push() での使用を推奨します。

他プレイヤーへの操作コマンド

コマンド対象説明
othersAdd(var, val) 自分以外の全員 varval を加算します。
othersSet(var, val) 自分以外の全員 varval にセットします。
uAdd(var, val) 自分以外の全員 othersAdd の別名。
uSet(var, val) 自分以外の全員 othersSet の別名。
tAdd(var, val) 同チームのメンバー(自分以外) varval を加算します。
tSet(var, val) 同チームのメンバー(自分以外) varval にセットします。

Team

プレイヤーは参加時の「フレーバーテキスト」でチーム分けされます。

フレーバーテキスト動作
チーム名(コロンなし) 通常のチーム。同じ文字列のプレイヤーが 1 チームになります。
メタ名:サブ名(コロンあり) メタチーム構造。同じ「メタ名」を持つプレイヤーが大グループとして扱われます。

変数の同期設定 (sync)

チーム内で変数を全メンバーに共有したい場合に def の外側に記述します。

sync(x)   # x はチーム内で同期(誰かが更新すると全員に反映)
          # y, z は同期されず個人の値として保持

Scope

scope(条件): は発行者を基準として、全プレイヤーに対して条件付きで処理を実行します。

構文説明
scope(条件): 条件が真のプレイヤーに対してブロック内を実行します。
my_xxx scope 内で発行者の変数を参照します。
mt scope 内で各プレイヤー自身のチームインデックスを参照します。
イベント発行者(scope の基準)
push()ボタンを押したプレイヤー
correct() / wrong() / through()現在の回答者(ホストが判定したプレイヤー)
next()処理中の各プレイヤー自身
def push():
    # 発行者と同じチームのプレイヤーにだけ実行
    scope(mt == my_mt):
        x += 1

    # 全員に実行(条件を常に真にする)
    scope(1):
        y += my_x
scope 内でも win(), lose(), lock() 等が使えます。ただし othersAdd / othersSettAdd などの対他コマンドは scope の外に記述してください。scope 内でのカスタム変数への代入は各プレイヤーに正しく保存されます。

Examples

Free — 正解で〇、誤答で×が増えるシンプルなルール

description = "正解で〇、誤答で×が増えるシンプルなルール。"
name="Free"
maxAns=1
x.label = "〇"
y.label = "×"

def correct():
  x += 1

def wrong():
  y += 1

def through():
  pass

M〇N× — 設定した回数で勝敗が決まるルール

rule="[M]〇[N]×"
description = "[M]回正解で勝ち抜け、[N]回誤答で失格"
maxAns=1
x.label = "〇"
y.label = "×"
const M = 7
const N = 3

def correct():
  x += 1

def wrong():
  y += 1

def through():
  pass

def next():
  if x >= M: win()
  if y >= N: lose()

Freeze N — n回目の誤答でnターン休み

rule="Freeze[N]"
description = "[N]回正解で勝ち抜け、n回目の誤答でn回休み"
maxAns=1
x.label = "〇"
y.label = "×"
z.label = "Lock"
const N = 10

def correct():
  x += 1

def wrong():
  y += 1
  z = y + 1
  lock()

def through():
  pass

def next():
  if z > 0:
    z -= 1
    if z == 0:
      unlock()

  if x >= N: win()

Attack Survival — 正解で相手を削り、誤答で自分が削られるサバイバル

rule="Attack Survival"
description = "持ち点[M]が無くなると失格、正解で他のプレイヤー-1pt、誤答で自身が-[N]pt"
const M = 20
const N = 1

x.label = "Pts"
x = M

def correct():
  othersAdd(x, -1)

def wrong():
  x -= N

def next():
  if x <= 0:
    x = 0
    lose()

10by10by10mini — チーム内の正解数の積が[N]以上で勝ち

description = "チーム内の正解数の積が[N]以上で勝ち。誤答でその人のPtsが1にリセット。2回誤答でロック。ただし誰かが2回誤答すると、他の全チームの2回目の誤答が1回に戻り、ロックも解除される。"
rule = "10by10by10mini"
x.label = "Pts"
y.label = "×"
z.label = "Prod"
const N = 200
x = 1
z = 1
sync(z)
def correct():
  x += 1
  z = tProd(x)
  if z >= N:
    win()

def wrong():
  x = 1
  y += 1
  z = tProd(x)
  if y >= 2:
    lock()
  scope(mt != my_mt):
    if y == 2:
      y = 1
      unlock()
フェーズ遷移のある wrong() / correct() では switch/case を使うことで、あるケース内で phase を変更しても別のケースが意図せず実行されることを防げます。

AI Code Generation

下のプロンプトをコピーし、[要望] を書き換えてから、このページ全体(Ctrl+A で全選択)と一緒に AI に送信してください。

See Also

taQu ルールテスター — /rule_tester