Pythonで歴史年号並び替えゲーム

Pythonで歴史上の出来事を起きた年号ごとに並べるゲームを作りました！
(アイデア参考: https://www.amazon.co.jp/%E3%83%9B%E3%83%93%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%91%E3%83%B3-HobbyJAPAN-%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%A9%E3%82%A4%E3%83%B3-Timeline-%E3%82%AB%E3%83%BC%E3%83%89%E3%82%B2%E3%83%BC%E3%83%A0/dp/B0098W8MOM)
半角数字の入力だけでプレイできます！(※途中で辞めるときには「stop」と入力)
西洋史がかなり難易度が高くなってなってしまいましたので、初見で全問正解できたら相当すごいです!
歴史の勉強にもなると思うので、ぜひ遊んでみてください！
(コードは最下部にあります)

◯ルール説明
デモプレイの画像を使い順を追って説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666665/220e9caa-5bfa-e668-2ee5-84527853196c.png)


①
ゲームは日本史と西洋史の2つから選べます。今回は１の日本史を選びました。

②
player数も何人でも可能です！もちろん1人でもokです！
今回は3人を選びました(デモプレイなのでもちろん本当は1人です！)

③
ゲームスタートです。stopと入力すれば途中で終了し、その時点での結果を見れます。
まず、歴史上の出来事と年号が1つ場に出されます。
「1. 1894年 日清戦争が起こる」
そこで、応仁の乱が起こる は　日清戦争が起こる　よりも前の出来事だと思うなら0を、あとの出来事だと思うならば　1　を入力します。（日清戦争が起こる　の先頭に表記されている1という番号との前後関係を答えています）

④
応仁の乱が起きたのはは1467年で1894年の日清戦争よりも前ですので、今回の正解は0になります。
正解したら 正解! と教えてくれます

⑤
間違えると 残念! と言われます

⑥
2回目以降は場に出された出来事が増えていき、どの出来事の次なのかを答える選択肢も増えるので難しくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666665/d94310c0-896f-adb8-61d9-27a185009003.png)


⑦
stopと入力すると、ゲームを終了して、その時点での不正解数をもとに勝敗を教えてくれます。
なお、stopを押さなくても、用意されている出来事が全てなくなれば終了します(日本史50個、西洋史74個)


ということで今回は歴史のカードゲームを作成しました！
意外と難易度が高いので、何問正解できるか試してみてください！

以下コード（Python）

```Python:history_game.py
import random
import bisect

INF = 1000
#日本史の出来事リスト(ここをいじれば好きな出来事の年号で遊べます！)
Japan = [
    (239,"邪馬台国の女王卑弥呼が中国(魏)に使いを送る"),
    (400,"大和朝廷が国土の統一を進める"),
    (538,"仏教が百済から伝来する"),
    (604,"聖徳太子が十七条の憲法を定める"),
    (645,"大化の改新が始まる"),
    (794,"平安京に都を移す"),
    (894,"菅原道真が遣唐使を廃止する"),
    (1016,"藤原道長が摂政になる"),
    (1185,"源氏が壇ノ浦の戦いで平氏を滅ぼす"),
    (1274,"文永の役"),
    (1281,"弘安の役"),
    (1338,"足利尊氏が京都に室町幕府を開く"),
    (1392,"南朝が北朝に三種の神器を渡し、南北朝が統一される"),
    (1467,"応仁の乱が起こる"),
    (1573,"織田信長が室町幕府を滅ぼす"),
    (1590,"豊臣秀吉が全国を統一する"),
    (1603,"徳川家康が江戸に幕府を開く"),
    (1641,"参勤交代の制度が定められる"),
    (1837,"大塩平八郎の乱が起こる"),
    (1854,"日米和親条約を結び、開国する"),
    (1858,"アメリカを皮切りに五か国と修好通商条約を結び、貿易を始める"),
    (1867,"徳川慶喜が政権を天皇に返す(大政奉還)"),
    (1869,"土地と人民を天皇に返す(版籍奉還)"),
    (1871,"廃藩置県"),
    (1872,"学制の公布、富岡製糸場"),
    (1873,"徴兵令、地租改正"),
    (1874,"板垣退助らが、民選議院設立建白書を政府に提出する"),
    (1881,"国会開設の勅諭が出される"),
    (1886,"ノルマントン号事件が起こる"),
    (1889,"大日本帝国憲法の発布"),
    (1890,"第一回の国会が開かれる"),
    (1894,"日清戦争が起こる"),
    (1904,"日露戦争が起こる"),
    (1911,"不平等条約の改正を達成する"),
    (1914,"日本が第一次世界大戦に参戦する"),
    (1918,"米騒動が起こる"),
    (1920,"国際連盟に加盟する"),
    (1929,"世界恐慌"),
    (1931,"満州事変が起こる"),
    (1932,"五・一五事件で、犬養毅が暗殺される"),
    (1933,"国際連盟から脱退する"),
    (1936,"皇道派と統制派の争いの中で、二・二六事件が起こる"),
    (1937,"日中戦争がはじまる"),
    (1941,"太平洋戦争"),
    (1946,"日本国憲法が公布される"),
    (1950,"朝鮮戦争が始まる"),
    (1952,"サンフランシスコ平和条約が結ばれる"),
    (1956,"国際連合に加盟する"),
    (1968,"五箇条の御誓文が示される"),
    (1978,"日中平和友好条約")
]
#西洋史の出来事リスト
Western = [
    (-331,"マケドニア王アレクサンドロス三世がペルシャ王国を滅ぼす"),
    (-218,"カルタゴの将軍ハンニバルがアルプス山脈を越えてローマに侵入"),
    (-46,"カエサルがローマの独裁官となる"),
    (-27,"オクタウィアヌスがローマ帝国の初代皇帝となる"),
    (313,"ローマ皇帝コンスタンティヌスがキリスト教を公認"),
    (375,"ゲルマン民族大移動"),
    (395,"ローマ帝国が東西に分裂する"),
    (476,"オドアケルが西ローマ帝国を滅ぼす"),
    (481,"フランク王国の成立"),
    (530,"ユスティニアヌス帝がローマ法大全の編纂を行う"),
    (800,"フランク王カールの戴冠"),
    (843,"ヴェルダン条約でフランク王国が3分割される"),
    (962,"神聖ローマ帝国の成立"),
    (1054,"ローマ教皇とコンスタンディヌーポリ総主教の相互破門"),
    (1077,"ハインリヒ4世がグレゴリウス7世に赦しを請う(カノッサの屈辱)"),
    (1096,"エルサレムへの第一回十字軍遠征が行わる"),
    (1122,"ヴォルムス協約で叙任権闘争が終わる"),
    (1215,"ジョン王がマグナ＝カルタ(大憲章)を承認する"),
    (1229,"シチリア王フリードリヒ2世とアル・カーミルが平和条約を結ぶ"),
    (1339,"百年戦争が勃発"),
    (1347,"ペストが地中海各地に広がる"),
    (1429,"ジャンヌダルクがオルレアンを開放する"),
    (1453,"東ローマ帝国の滅亡"),
    (1492,"コロンブスがアメリカ大陸を発見"),
    (1499,"ヴァスコ・ダ・ガマがインドに到達"),
    (1517,"ドイツでルターが宗教改革を始める"),
    (1521,"アステカ帝国の滅亡"),
    (1522,"マゼランの艦隊が初めて世界一周を達成"),
    (1571,"オスマンとスペインの間で、レパントの海戦が起こる"),
    (1581,"スペイン王フェリペ2世が、ポルトガル王位を継承する"),
    (1588,"アルマダ海戦でイギリスがスペインの無敵艦隊に勝利する"),
    (1608,"イギリスで名誉革命が起こる"),
    (1641,"イギリスで清教徒革命が起こる"),
    (1648,"オランダ独立戦争(80年戦争)が終わる"),
    (1721,"ピョートル1世がロシア帝国を建国する"),
    (1769,"イギリスのジェームズ・ワットが新型の蒸気機関を開発"),
    (1775,"アメリカ独立戦争が始まる"),
    (1789,"フランス革命が始まる"),
    (1792,"フランスが共和制に移行"),
    (1802,"イギリスで最初の工場法が制定される"),
    (1804,"ナポレオンが皇帝となり、フランス民法典を制定する"),
    (1812,"ナポレオンがロシアに侵攻するも、敗北し撤退する"),
    (1815,"ウィーン議定書が締結される"),
    (1825,"ロシアでデカブリストの乱が起こる"),
    (1840,"デイヴィッド・リヴィングストンが第一次アフリカ探検を始める"),
    (1848,"二月革命を引き金として、ウィーン体制が崩壊する"),
    (1856,"南下政策を目指したロシアが、クリミア戦争で敗れる"),
    (1861,"ロシアで農奴解放令が発せられる"),
    #(1861,"アメリカ南北戦争"),
    (1869,"スエズ運河、大陸横断鉄道の開通"),
    (1870,"普仏戦争が始まる"),
    (1876,"アメリカ独立宣言"),
    (1878,"ビスマルクが社会主義者鎮圧法を制定する"),
    (1881,"アレクサンドル2世が暗殺される"),
    (1884,"ベルリン会議"),
    (1896,"第一回国際オリンピック大会が開かれる"),
    (1898,"スーダンのファショダで、イギリスとフランスが衝突する"),
    (1901,"大英帝国女王ヴィクトリアの死去"),
    (1904,"英仏協商"),
    (1905,"第一次ロシア革命"),
    (1914,"サラエボ事件"),
    (1917,"第二次ロシア革命"),
    (1919,"ヴェルサイユ条約"),
    (1922,"ソビエト社会主義共和国連邦の樹立が宣言される"),
    (1929,"世界恐慌"),
    #(1933,"アメリカのニューディール政策の施行"),
    (1933,"ドイツでナチ党が政権を掌握する"),
    (1939,"第二次世界大戦"),
    (1947,"アメリカでトルーマンドクトリンが宣言される"),
    (1962,"キューバ危機"),
    (1965,"ベトナム戦争が始まる"),
    (1989,"マルタ会談で冷戦が終わる"),
    (1990,"湾岸戦争が始まる"),
    (1991,"ソビエト連邦が崩壊"),
    (2003,"イラク戦争が始まる"),
    (2022,"ロシアがウクライナに軍事侵攻")
]

#モードの確認
print("どのモードでゲームを行うか選んでください")
print("1.日本史")
print("2.西洋史")
mode = int(input())
if mode == 1:
    events = Japan
if mode == 2:
    events = Western

#player人数の確認
print("player数を入力してください")
num_players = int(input())
num_miss = dict()
for p in range(num_players):
    num_miss[p] = 0

#確認済みの出来事を保持
used = []
years = []

#最初に1つ出来事を場に出す
init_evnet = random.choice(events)
used.append(init_evnet)
years.append(init_evnet[0])

#ゲーム開始
print("ゲームスタート!(途中で辞めるときは「stop」と入力してください)")
turn = 0
while len(events) > len(used):
    #出来事リストから一つ出来事を取り出す
    event = random.choice(events)
    if event in used: #確認済みならスキップ
        continue

    #何番目のplayerかを確認
    player_number = turn%num_players
    print("player{}さんの番です".format(player_number+1))

    #順番を回答してもらう
    year = event[0]
    content = event[1]
    for u in range(len(used)):
        print("{}. {}年".format(u+1,used[u][0]) + used[u][1])
    print(content + " はどの出来事の次に起きたでしょうか？(一番古いと考えたときは0を入力してください)")
    
    normal_input = False
    while normal_input == False:        
        try:
            index = input() #回答者の答え
            if index == "stop": #stopと入力されたら終了
                break
            index = int(index)
        except ValueError as e:
            print("無効な入力です。入力は整数で行ってください")
            continue

        index = int(index)
        if index > len(used):
            print("入力が大きすぎます")
            continue
        if index < 0:
            print("入力が小さすぎます")
        normal_input = True

    if index == "stop":
        break


    #回答が正しいかを確認
    true_index = bisect.bisect(years,year) #本当の順番を調べる（二分探索という早く調べられる方法を使っています）
    if index == true_index:
        print("正解!")
    else:
        print("残念!")
        num_miss[player_number] = num_miss[player_number] + 1

    #今扱った出来事を確認済みにして、ターンも後進
    used.append(event)
    used.sort()
    years.append(year)
    years.sort()
    turn += 1


#playerが1人のときの結果発表(勝ち負けはない)
if num_players == 1:
    if num_miss[0] == 0:
        print("おめでとう! 全問正解です!")
    else:
        print("{}問間違いでした".format(num_miss[0]))

#playerが2人以上のときの結果発表
if num_players != 1:
    print("各playerの間違えた数は")
    winner = []
    min_miss = INF
    for k,v in num_miss.items():
        print("playee{}:{}回".format(k+1,v))
        if min_miss > v:
            min_miss = v
            winner = [k]
        elif min_miss == v:
            winner.append(k)

    print("ということで今回のゲームの勝者は...")
    for w in winner:
        print("player{}".format(w+1))

    print("さんです! おめでとう!")

```