こいこいアプリを作りたいと思っています。
ええと、『サマーウォーズ』見ましてね、うわ、なんて面白いんだろう、この映画! って思ったんです。それで花札やりたくなりまして、でも相手がいない。仕方がないから、ネットで遊べる花札、主にこいこいを探したのですが、なかなかこれだっ! というものが見付からなくて、しかたがない、自分で作ろうか、そんな気になってしまいました。
けれど私はこれまでこうしたプログラムをしたことがなくて、うまくいくかどうかは未知数。無理なんじゃないかな、と思いながらも、少しずつ進めていきたいなと思っているところです。
とりあえずやりたいことは、任天堂のサイトに公開されている花札、こいこいの遊び方で遊べるようにする、ということです。
花札を遊ぶというのなら、その前提としてまず札をちゃんと配れないければならない。つまりシャッフルをどうしようかと考えて、まあ、考えるより書いた方がはやい。書いてみたんですが、いやあ、Pythonは素晴しい。ちゃんと配列をシャッフルする関数が用意されてるんですね。
def shuffle(self): order = self.order self.order = list() while len(order) != 0: i = random.randint(0, len(order) - 1) self.order.append(order[i]) del order[i]
これが、
def shuffle(self): random.shuffle(self.order)
こうなりました。
凡人は、考えるだけ無駄なんだろうか……。
シャッフルできるようになったというわけで、札を配るところまでできるようになりました。あとはロジックさえできれば、とりあえず遊べるようになりそうですね。って、それが一番難しいんでしょうけどさ。
koikoi.py
# -*- coding: utf-8-unix; mode: python -*- import random class Deck(object): def __init__(self, cards=None): if cards is None: self.cards = self._default_cards() else: self.cards = self._default_cards() self.order = list() self._initorder() self.index = 0 def _initorder(self): self.order = list() for season in self.cards: for number in self.cards[season]: self.order.append(season + u'_' + number) def shuffle(self): random.shuffle(self.order) ## order = self.order ## self.order = list() ## while len(order) != 0: ## i = random.randint(0, len(order) - 1) ## self.order.append(order[i]) ## del order[i] def draw(self, index=None): if index is None: i = self.index else: i = index - 1 try: (season, number) = self.order[i].split(u'_') except: return None else: return self.cards[season][number] finally: if index is None: self.index += 1 def _default_cards(self): return { u'01': { u'1': Card(u'1', u'01', u'松に鶴', 20), u'2': Card(u'2', u'01', u'松に赤短', 5), u'3': Card(u'3', u'01', u'松のカス', 1), u'4': Card(u'4', u'01', u'松のカス', 1) }, u'02': { u'1': Card(u'1', u'02', u'梅に鶯', 10), u'2': Card(u'2', u'02', u'梅に赤短', 5), u'3': Card(u'3', u'02', u'梅のカス', 1), u'4': Card(u'4', u'02', u'梅のカス', 1) }, u'03': { u'1': Card(u'1', u'03', u'桜に幕', 20), u'2': Card(u'2', u'03', u'桜に赤短', 5), u'3': Card(u'3', u'03', u'桜のカス', 1), u'4': Card(u'4', u'03', u'桜のカス', 1), }, u'04': { u'1': Card(u'1', u'04', u'藤に不如帰', 10), u'2': Card(u'2', u'04', u'藤に短冊', 5), u'3': Card(u'3', u'04', u'藤のカス', 1), u'4': Card(u'4', u'04', u'藤のカス', 1), }, u'05': { u'1': Card(u'1', u'05', u'菖蒲に八ツ橋', 10), u'2': Card(u'2', u'05', u'菖蒲に短冊', 5), u'3': Card(u'3', u'05', u'菖蒲のカス', 1), u'4': Card(u'4', u'05', u'菖蒲のカス', 1), }, u'06': { u'1': Card(u'1', u'06', u'牡丹に蝶', 10), u'2': Card(u'2', u'06', u'牡丹に青短', 5), u'3': Card(u'3', u'06', u'牡丹のカス', 1), u'4': Card(u'4', u'06', u'牡丹のカス', 1), }, u'07': { u'1': Card(u'1', u'07', u'萩に猪', 10), u'2': Card(u'2', u'07', u'萩に短冊', 5), u'3': Card(u'3', u'07', u'萩のカス', 1), u'4': Card(u'4', u'07', u'萩のカス', 1), }, u'08': { u'1': Card(u'1', u'08', u'芒に月', 20), u'2': Card(u'2', u'08', u'芒に雁', 10), u'3': Card(u'3', u'08', u'芒のカス', 1), u'4': Card(u'4', u'08', u'芒のカス', 1), }, u'09': { u'1': Card(u'1', u'09', u'菊に盃', 10), u'2': Card(u'2', u'09', u'菊に青短', 5), u'3': Card(u'3', u'09', u'菊のカス', 1), u'4': Card(u'4', u'09', u'菊のカス', 1), }, u'10': { u'1': Card(u'1', u'10', u'紅葉に鹿', 10), u'2': Card(u'2', u'10', u'紅葉に青短', 5), u'3': Card(u'3', u'10', u'紅葉のカス', 1), u'4': Card(u'4', u'10', u'紅葉のカス', 1), }, u'11': { u'1': Card(u'1', u'11', u'小野道風に蛙', 20), u'2': Card(u'2', u'11', u'柳に燕', 10), u'3': Card(u'3', u'11', u'柳に短冊', 5), u'4': Card(u'4', u'11', u'柳のカス', 1), }, u'12': { u'1': Card(u'1', u'12', u'桐に鳳凰', 20), u'2': Card(u'2', u'12', u'桐のカス', 1), u'3': Card(u'3', u'12', u'桐のカス', 1), u'4': Card(u'4', u'12', u'桐のカス', 1), } } class Card(dict): def __init__(self, number, season, name, point=1): self[u'number'] = number self[u'season'] = season self[u'name'] = name self[u'point'] = point
テスト用プログラム(index.cgi)
#! /usr/bin/env python # -*- coding: utf-8-unix; mode: python -*- import cgi import cgitb; cgitb.enable() import sys import locale sys.path.insert(0, './lib/') import htmldocument import koikoi deck = koikoi.Deck() locale.setlocale(locale.LC_ALL, '') ht = htmldocument.HTML(lang=u'ja', sitetitle=u'koikoi', cssfiles=[u'resource/main.css']) ht.print_resp_header() ht.print_html_header() ## ht.printe(u'<p>') ## ht.printe(deck.order) ## ht.printe(u'</p>') deck.shuffle() ## ht.printe(u'<p>') ## ht.printe(deck.order) ## ht.printe(u'</p>') cards = list() oya = list() ba = list() ko = list() yama = list() count = 0 card = deck.draw() while card is not None: count += 1 cards.append(card) if count in [1, 2, 7, 8, 13, 14, 19, 20]: ko.append(card) elif count in [3, 4, 9, 10, 15, 16, 21, 22]: ba.append(card) elif count in [5, 6, 11, 12, 17, 18, 23, 24]: oya.append(card) else: yama.append(card) card = deck.draw() ht.printe(ht.h1(u'proto-koikoi')) ht.printe(u'<div class="oya">') ht.printe(ht.h2(u'親の手札')) ht.printe(ht.ol(ht.li([c[u'name'] for c in oya]))) ht.printe(u'</div>') ht.printe(u'<div class="ba">') ht.printe(ht.h2(u'場札')) ht.printe(ht.ol(ht.li([c[u'name'] for c in ba]))) ht.printe(u'</div>') ht.printe(u'<div class="ko">') ht.printe(ht.h2(u'子の手札')) ht.printe(ht.ol(ht.li([c[u'name'] for c in ko]))) ht.printe(u'</div>') ht.printe(u'<div class="yama">') ht.printe(ht.h2(u'山札')) ht.printe(ht.ol(ht.li([c[u'name'] for c in yama]))) ht.printe(u'</div>') ht.printe(u'<div class="all">') ht.printe(ht.h2(u'全部')) ht.printe(ht.ol(ht.li([c[u'name'] for c in cards]))) ht.printe(u'</div>') ht.printe(u'<div class="test">') ht.printe(ht.h2(u'番号指定')) ht.printe(u'<dl>') for index in [5, 10, 15, 20, 25, 30, 35, 40, 45, 48]: ht.printe(ht.dt(u'{0}枚目'.format(index))) ht.printe(ht.dd(u'{0[name]} ({0[point]}点)'.format(deck.draw(index)))) ht.printe(u'</dl>') ht.printe(u'</div>') ht.print_html_close()