今回は花札のこいこいゲームの判定です
こいこいを知らない方でも
楽しむ事が出来ると思います
解説動画はこちら
さて初めは花札に関してです
花札
花札と言えば任天堂さんが有名ですね!!!
任天堂さんのHPから拝借させていただきます
ハマると時間泥棒なんで気をつけてくださいね
さて
ここからは判定を考えていきましょう
最初は札を定義しましょう
花札の定義
無理くり文字列でカードをリストで用意します
デッキを作る
もしゲームを作るなら
デッキはこんな感じでしょうね
役を判定する
ここからは格役を判定していきます
役ごとに関数を作ります
何の役が揃ったかを判定する
役の判定関数を用いて揃った役を
判定する関数を作ります
点数計算を行う
最後に点数計算を考えてみます
役ごとに判定して加算していきます
確認
一応の確認用です
手札からどう判定されるのかを見てみましょう
さて、そうしたら
軽いシミュレーションをしてみましょう
10000回ほど、16枚の札を取ると
どんな役になるかを判定して
点数も集計してみましょう
結果は
やはり点数の高いものの方が出にくいですね
10000回試行していますが
16枚取っただけでは役が揃わないのも
5分の1ほどあるようです
点数の分布も見てみましょう
各回の点数の出現回数のランキングでみると
[(0, 2313), (1, 2094), (2, 1187), (5, 721), (6, 606),
(14, 554), (3, 524), (20, 425), (22, 288), (16, 248)]
役なし0点が一番多く
1点2点は出現回数が多いですね
やはりこの程度で上がってしまう事が
多いのだろうなと予想できます
点数のヒストグラムはこうなりました

7点以上で倍になるので7-13点の結果は有りませんね
ゲームの回数は12回なので1点で上がるより
14点以上で上がった時のインパクトは
かなり大きいですよね
点を取れる確率を考えつつ
手札の取り方を考えるところが
「こいこい」の醍醐味です
時間が有れば
・ゲームシステム
・戦略AI
なども考えていきたいですね
今日はこれまでです
それでは。
こいこいを知らない方でも
楽しむ事が出来ると思います
解説動画はこちら
さて初めは花札に関してです
花札
花札と言えば任天堂さんが有名ですね!!!
任天堂さんのHPから拝借させていただきます
花札の歴史は安土・桃山時代の「天正かるた」
江戸時代上期の「ウンスンカルタ」から
江戸時代中期に現在使用している花札ができ
花札ゲームの中でも2人でプレイする「こいこい」は
勝負勘・度胸・かけひき・冷静さを必要とする
知的ゲーム!! だそうです
知的ゲーム!! だそうです
特にばくち性が有って
最高に面白いゲームだと思います
こいこい

1-12月で各月4枚があり
20,10,5,1点札があります
次のような役があります
プログラムでもこの内容で判定していきます
こいこいをする、しないや
早く上がって阻止したり
残りの月を考えての采配など
やってみると結構面白いんですよーーーー
めちゃくちゃにハマります
ちなみにすぐゲームしたい方は
世界のアソビ大全51 | Nintendo Switch | 任天堂
こちらが分かりやすくて遊びやすいですよ最高に面白いゲームだと思います
こいこい
こいこいは
花札1組48枚を用いて役を作るゲーム
二人の各手札8枚
場に8枚の状態を作り
残りは山札として積みます
場に8枚の状態を作り
残りは山札として積みます
親から順番に手札の1枚を場に出し
同じ月の札があれば取り
ない場合は場に捨てます
同じ月の札があれば取り
ない場合は場に捨てます
次に山札から1枚をめくり
同様に同じ月の札は取り
ない場合は場に捨てます
同様に同じ月の札は取り
ない場合は場に捨てます
親と子で交互に手札を使い
手札がなくなる前に、役ができれば止め
「こいこい」するか決めることとなります
手札がなくなる前に、役ができれば止め
「こいこい」するか決めることとなります
こいこいしない場合:
役から点数計算に入り次の局へ移行
こいこいした場合:
さらに役が出来たらそこで終局
点数計算に入り、得点は倍入る、次の局へ移行
点数計算に入り、得点は倍入る、次の局へ移行
ただし、自分に次の役ができる前に
相手に役ができた時は、得点を倍返しされる
相手に役ができた時は、得点を倍返しされる
得点7点以上は倍の得点となります
12回戦で終了し、合計点の多いほうが勝ち
48枚の札

1-12月で各月4枚があり
20,10,5,1点札があります
役の一覧
次のような役があります
プログラムでもこの内容で判定していきます
こいこいをする、しないや
早く上がって阻止したり
残りの月を考えての采配など
やってみると結構面白いんですよーーーー
めちゃくちゃにハマります
ちなみにすぐゲームしたい方は
世界のアソビ大全51 | Nintendo Switch | 任天堂
ハマると時間泥棒なんで気をつけてくださいね
さて
ここからは判定を考えていきましょう
最初は札を定義しましょう
花札の定義
# 月:名前:点数
cards = [
'1:松に鶴:20','1:松に赤短:5','1:松のカス:1','1:松のカス:1',
'2:梅に鶯:10','2:梅に赤短:5','2:梅のカス:1','2:梅のカス:1',
'3:桜に幕:20','3:桜に赤短:5','3:桜のカス:1','3:桜のカス:1',
'4:藤に不如帰:10','4:藤に短冊:5','4:藤のカス:1','4:藤のカス:1',
'5:菖蒲に八ツ橋:10','5:菖蒲に短冊:5','5:菖蒲のカス:1','5:菖蒲のカス:1',
'6:牡丹に蝶:10','6:牡丹に青短:5','6:牡丹のカス:1','6:牡丹のカス:1',
'7:萩に猪:10','7:萩に短冊:5','7:萩のカス:1','7:萩のカス:1',
'8:芒に月:20','8:芒に雁:10','8:芒のカス:1','8:芒のカス:1',
'9:菊に盃:10','9:菊に青短:5','9:菊のカス:1','9:菊のカス:1',
'10:紅葉に鹿:10','10:紅葉に青短:5','10:紅葉のカス:1','10:紅葉のカス:1',
'11:柳に小野道風:20','11:柳に燕:10','11:柳に短冊:5','11:柳のカス:1',
'12:桐に鳳凰:20','12:桐のカス:1','12:桐のカス:1','12:桐のカス:1']
cards = [c.split(':') for c in cards]
cards = [[int(c[0]),c[1],int(c[2])] for c in cards]
無理くり文字列でカードをリストで用意します
デッキを作る
import random deck = cards random.shuffle(deck) print(deck)
もしゲームを作るなら
デッキはこんな感じでしょうね
役を判定する
ここからは格役を判定していきます
役ごとに関数を作ります
# 五光
def jadge_gokou(hands):
c = 0
for hand in hands:
if hand[2]==20:
c+=1
if c==5:
return True
else:
return False
# 四光
def jadge_shikou(hands):
c = 0
for hand in hands:
if hand[2]==20 and hand[0]!=11:
c+=1
if c==4:
return True
else:
return False
# 雨四光
def jadge_ameshikou(hands):
c,flg = 0,False
for hand in hands:
if hand[2]==20:
c+=1
if hand[0]==11:
flg=True
if c==4 and flg:
return True
else:
return False
# 三光
def jadge_sankou(hands):
c,flg = 0,False
for hand in hands:
if hand[2]==20:
c+=1
if hand[0]==11:
flg=True
if c==3 and not flg:
return True
else:
return False
# 猪鹿蝶
def jadge_inoshikacho(hands):
c = 0
for hand in hands:
if hand[1]=='萩に猪' or hand[1]=='紅葉に鹿' or hand[1]=='牡丹に蝶':
c+=1
if c==3:
return True
else:
return False
# 赤短
def jadge_akatan(hands):
c = 0
for hand in hands:
if hand[1]=='松に赤短' or hand[1]=='梅に赤短' or hand[1]=='桜に赤短' :
c+=1
if c==3:
return True
else:
return False
# 青短
def jadge_aotan(hands):
c = 0
for hand in hands:
if hand[1]=='牡丹に青短' or hand[1]=='菊に青短' or hand[1]=='紅葉に青短':
c+=1
if c==3:
return True
else:
return False
# 月見で一杯
def jadge_tukimi(hands):
c = 0
for hand in hands:
if hand[1]=='芒に月' or hand[1]=='菊に盃':
c+=1
if c==2:
return True
else:
return False
# 花見で一杯
def jadge_hanami(hands):
c = 0
for hand in hands:
if hand[1]=='芒に月' or hand[1]=='菊に盃':
c+=1
if c==2:
return True
else:
return False
# たね
def jadge_tane(hands):
c = 0
for hand in hands:
if hand[2]==10:
c+=1
if c>=5:
return True
else:
return False
# たん
def jadge_tann(hands):
c = 0
for hand in hands:
if hand[2]==5:
c+=1
if c>=5:
return True
else:
return False
# かす
def jadge_kasu(hands):
c = 0
for hand in hands:
if hand[2]==1:
c+=1
if c>=10:
return True
else:
return False
何の役が揃ったかを判定する
役の判定関数を用いて揃った役を
判定する関数を作ります
def jadge_yaku(hands):
result = []
if jadge_gokou(hands):
result.append('五光')
if jadge_shikou(hands):
result.append('四光')
if jadge_ameshikou(hands):
result.append('雨四光')
if jadge_sankou(hands):
result.append('三光')
if jadge_inoshikacho(hands):
result.append('猪鹿蝶')
if jadge_akatan(hands):
result.append('赤短')
if jadge_aotan(hands):
result.append('青短')
if jadge_tukimi(hands):
result.append('月見で一杯')
if jadge_hanami(hands):
result.append('花見で一杯')
if jadge_tane(hands):
result.append('たね')
if jadge_tann(hands):
result.append('たん')
if jadge_kasu(hands):
result.append('かす')
if len(result)==0:
result = ['役なし']
return result
点数計算を行う
最後に点数計算を考えてみます
役ごとに判定して加算していきます
def get_score(hands):
score = 0
if jadge_gokou(hands):
score += 10
if jadge_shikou(hands):
score += 8
if jadge_ameshikou(hands):
score += 7
if jadge_sankou(hands):
score += 5
if jadge_inoshikacho(hands):
score += 5
if jadge_akatan(hands):
score += 5
if jadge_aotan(hands):
score += 5
if jadge_tukimi(hands):
score += 5
if jadge_hanami(hands):
score += 5
if jadge_tane(hands):
score += sum([1 for hand in hands if hand[2]==10])-4
if jadge_tann(hands):
score += sum([1 for hand in hands if hand[2]==5])-4
if jadge_kasu(hands):
score += sum([1 for hand in hands if hand[2]==1])-9
if score >= 7:
score = score * 2
return score
確認
一応の確認用です
手札からどう判定されるのかを見てみましょう
import random hands = random.choices(deck,k=16) print(hands) print() print(jadge_yaku(hands)) print() print(get_score(hands))
さて、そうしたら
軽いシミュレーションをしてみましょう
10000回ほど、16枚の札を取ると
どんな役になるかを判定して
点数も集計してみましょう
import random
import matplotlib.pyplot as plt
%matplotlib inline
result,scores = [],[]
for i in range(10000):
hands = random.choices(deck,k=16)
result += jadge_yaku(hands)
scores += [get_score(hands)]
calc1,calc2 = {},{}
for r in result:
if r in calc1:
calc1[r] += 1
else:
calc1[r] = 1
for s in scores:
if s in calc2:
calc2[s] += 1
else:
calc2[s] = 1
for k,v in sorted(calc1.items(),key=lambda x:x[1]):
print(k,v)
print()
print([(k,v) for k,v in sorted(calc2.items(),reverse=True,key=lambda x:x[1])][0:10])
plt.hist(scores , bins = 100)
plt.show()
結果は
五光 159
四光 291
雨四光 320
猪鹿蝶 577
赤短 602
青短 641
三光 766
月見で一杯 1139
花見で一杯 1139
たね 1655
たん 2287
かす 2301
役なし 2313
やはり点数の高いものの方が出にくいですね
10000回試行していますが
16枚取っただけでは役が揃わないのも
5分の1ほどあるようです
点数の分布も見てみましょう
各回の点数の出現回数のランキングでみると
[(0, 2313), (1, 2094), (2, 1187), (5, 721), (6, 606),
(14, 554), (3, 524), (20, 425), (22, 288), (16, 248)]
役なし0点が一番多く
1点2点は出現回数が多いですね
やはりこの程度で上がってしまう事が
多いのだろうなと予想できます
点数のヒストグラムはこうなりました

7点以上で倍になるので7-13点の結果は有りませんね
ゲームの回数は12回なので1点で上がるより
14点以上で上がった時のインパクトは
かなり大きいですよね
点を取れる確率を考えつつ
手札の取り方を考えるところが
「こいこい」の醍醐味です
時間が有れば
・ゲームシステム
・戦略AI
なども考えていきたいですね
今日はこれまでです
それでは。



コメントする