0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GMC-4 / ORANGE-4Advent Calendar 2022

Day 20

【GMC-4】インチキじゃんけん

Posted at

学研の4ビットマイコン GMC-4 で、一見じゃんけんのようなゲームを作ってみた。

遊び方

0 (グー)、1 (チョキ)、2 (パー) のいずれかのキーを押して自分の手を選択する。
自分の手を選択すると、選択した手を表す2進LEDが光り、7セグメントLEDに相手の手が表示される。
相手の手は、6 (グー)、A (チョキ)、0 (パー) のいずれかで表示される。(手の形をイメージした設計)

仕様

2人で行う通常のじゃんけんでは、1回手を出すと、1/3の確率で勝ち、1/3の確率で負け、1/3の確率であいこになる。
しかし、今回のプログラムでは、プレイヤーは1/8の確率で勝ち、7/8の確率で負け、あいこになる確率は0である。
勝つか負けるかをランダムで決め、プレイヤーの手を見てから後出しで手を出すのである。

Tモールの「CMじゃんけん」で全然あいこが出ないことから思いついた。

プログラム

以下のプログラムは、MikeAssembler でアセンブルできる。

target gmc4

	; プレイヤーの操作
	;   グー   : 0
	;   チョキ : 1
	;   パー   : 2
	; プレイヤーの出す手 (2進LED)
	;   グー   : 2ビット目
	;   チョキ : 1ビット目
	;   パー   : 0ビット目
	; 相手の出す手 (7セグメントLED)
	;   グー   : 6
	;   チョキ : A
	;   パー   : 0

	TIA 0
	TIY 0xE
	AM
	TIY 0xF
	AM
main_loop:
	CAL RSTO
	CAL DSPR
	; Zレジスタ : 勝敗制御用ルーレット
	TIY 0
	CH
key_wait:
	CH
	AIY 2
	CH
	KA
	JUMP key_wait
	; 3以上の値が入力された場合は、戻る
	AIA 0x10 - 3
	JUMP key_wait
	; 押された手を2進LEDに表示する
	CAL CMPL
	CY
	CAL SETR
	CY
	; さらに、勝てる手に変換する
	CAL CMPL
	AIA 5
	; ルーレットが0だった場合、1を引いて負ける手にする
	CH
	CIY 0
	JUMP no_win
	CH
	AIA -1
	CH
no_win:
	CH
	; mod 3 をとる (3以上だったら3を引く)
	AIA 0x10 - 3
	JUMP mod_no_rollback
	AIA 3
mod_no_rollback:
	; 出す手を7セグメントLEDに表示する数字に変換する
	TIY 0xD
	AM
	M+
	AM
	M+
	AIA 8
	JUMP hand_decided
	AIA -2
hand_decided:
	AO
	CAL SHTS
key_release_wait:
	KA
	JUMP main_loop
	JUMP key_release_wait

以下は、このプログラムの機械語表現である。

  | 0 1 2 3  4 5 6 7  8 9 A B  C D E F
--+-----------------------------------
0 | 8 0 A E  4 A F 4  E 0 E D  A 0 2 2
1 | B 2 2 0  F 0 F 9  D F 0 F  E 4 3 E
2 | 1 3 E 4  9 5 2 D  0 F 3 0  2 9 F 2
3 | 2 9 D F  3 8 9 3  A D 4 6  4 6 9 8
4 | F 4 5 9  E 1 E 9  0 F 0 8  F 4 8

解説

まず、キーから0~2の入力を受け付ける。
これに-3を足すと、それぞれ -3 (0b1101)、-2 (0b1110)、-1 (0b1111) となる。
これをビット反転すると、2 (0b0010)、1(0b0001)、0 (0b0000) となり、2進LEDの点灯位置が求まる。
もう一度ビット反転して元に戻し、5を足すと、2~4になる。
これは、0 (グー) に対して 2 (パー) などのように、3で割った余りがプレイヤーの出した手に勝てる手になっている。
プレイヤーの出した手に勝てる手にするには、さらに1を引けばよい。
すると、例えば 0 (グー) に対して 1 (チョキ) のようになる。
これらの計算で求まった値は3以上にはなり得るが6以上にはならないので、3以上であれば3を引くことで3で割った余りが求まる。
これは、まず3を引いてみて、0未満になったら3を足して取り消す、という処理で実現できる。
3を引いて0未満になるかは、例えば0に-3を足すことを考えるとわかるように、キャリーが無いかで判定できる。
最後に、求まった0~3の手を、7セグメントLEDに表示する数字に変換する。
今回は、0を6、1をA、2を0に変換することにした。
6とAの差は4なので、まず数値を4倍する。
すると、0は0、1は4、2は8になる。
これに8を足すと、それぞれ 8、C、0 となり、変換前が2のときは変換したい0となった。
さらに、このとき変換前が2のときはキャリーがあり、それ以外のときはキャリーが無い。
よって、キャリーが無ければさらに2を引くことで、求めたい 6、A、0 を求めることができる。

実行結果

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?