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 3 years have passed since last update.

Pythonによる『三国志大戦』の実装(1)

Posted at

Pythonを使って『三国志大戦』の実装

目次

  1. 作成の経緯
  2. 作成手順
  3. 次回に向けて
  4. 作成したコード全体

1. 作成の経緯

ゲームの制作をしてみたいと思い、好きでよくやっていた「三国志大戦」に目をつけて、自分で作ってみようと思いました。ゲームであればC++やC#がメジャーだとは思いますが、自由に扱える訳ではない(力量が足りない)ため、自信が得意としているPythonで実装することにしました。

2. 作成手順

1. キャラクター設定

今回使用するキャラクターは三国志でも有名な3名を使います。
・曹操 → 長安
・劉備 → 成都
・孫堅 → 建業
※都は適当につけています。

今回の注意点として、

  1. 武将による能力の差はない。
  2. 能力の代わりに兵量によって分ける。
    ということです。(今後、改良予定です。)

こちらの武将・都・人数を配列に格納します。

sangoku.py
army = ['曹操', '孫堅', '劉備']   #武将(キャラクター)
countries = ['長安', '建業' ,'成都']  #都
army_num = [10, 5, 3]  #人数

2. 画面(地図の描画)

続けて地図を描画します。今回は何度も地図を呼び出すため関数にしています。

sangoku.py
def Drawmap():
    os.system('clear')
    print(str(year) + "")
    print()
    print("            長安")
    print("            " + army[0] + " " + str(army_num[0]))
    print()
    print("                              建業")
    print("                              " + army[1] + " " + str(army_num[1]))
    print()
    print(" 成都")
    print(" " + army[2] + " " + str(army_num[2]))
    print()

実際に実行するとこのような画面になります。

220年

            長安
            曹操 10

                              建業
                              孫堅 5

 成都
 劉備 3

簡易的ではありますが、地図を表示することができました。
領地が略奪されたり、武将が倒されると初期化した武将のリストが書き換えられます。

3. 攻撃する場所・攻撃人数の入力

続けてどこに攻撃するか、何人で攻撃するのかを入力します。

sangoku.py
print(countries[i] + "" + army[i] + "様 どちらへ攻撃しますか?" + " (" + str(i+1) + "/" + str(len(army)) + ")")
        for j in range(len(army)):
            if not j == i:
                print(str(j) + " : " + countries[j] + " " + army[j])
        print("3 : 温存")
        attack_counrty = int(input("攻撃する場所を入力 => "))

こちらでは、長安に攻撃→0、建業に攻撃→1、成都に攻撃→2、兵力を温存→3、を入力することができます。

攻撃人数はこのように指定します。

sangoku.py
if (attack_counrty == 0) or (attack_counrty == 1) or (attack_counrty == 2):
            at_num = int(input("何千人で攻撃しますか(1~9) => "))
            print()
            print(countries[i] + "" + army[i] + "様が" + str(at_num) + "000人で" + countries[attack_counrty] + "" + army[attack_counrty] + "様に攻撃!!")
            input()
            attack(i, at_num, attack_counrty)
        else:
            print()
            print("今年は兵力を温存するでござる")
            input()

4. 攻撃する

実際に攻撃をします。
攻撃は1000人ずつ減るように指定しました。初期化で、

sangoku.py
attack_num = [0, 1]

を指定しました。randomのchoiceを使って、どちらかを選択して人数が減るようになっています。
攻撃全体のコードはこちらです。

sangoku.py
def attack(own, own_num, enemy):
    os.system('clear')
    print(countries[own] + "          " + countries[enemy])
    print(army[own] + str(own_num) + "000人" + "" + army[enemy] + str(army_num[enemy]) + "000人")
    print()

    number = own_num
    enemy_num = army_num[enemy]

    while(True):
        offence = rd.choice(attack_num)
        deffence = rd.choice(attack_num)

        if offence > deffence:
            enemy_num -= offence
            if enemy_num <= 0:
                print(army[own] + "  " + str(own_num*1000) + "人  X  " + army[enemy] + "  0人")
                break
            else:
                print(army[own] + "  " + str(own_num*1000) + "人  X  " + army[enemy] + "  " + str(enemy_num*1000) + "")
        elif offence < deffence:
            own_num -= deffence
            if own_num <= 0:
                print(army[own] + "  0人  X  " + army[enemy] + "  " + str(enemy_num*1000) + "")
                break
            else:
                print(army[own] + "  " + str(own_num*1000) + "人  X  " + army[enemy] + "  " + str(enemy_num*1000) + "")
        else:
            print(army[own] + "  " + str(own_num*1000) + "人  X  " + army[enemy] + "  " + str(enemy_num*1000) + "")
        
        input()

    if own_num > enemy_num:
        print()
        print(army[own] + "様 勝利!!")
        army[enemy] = army[own]
        army_num[enemy] = own_num
        army_num[own] -= number
    else:
        print()
        print(army[enemy] + "様 勝利!!")
        army_num[own] -= number
        army_num[enemy] = enemy_num
    input()

3. 次回に向けて

次回に向けて以下のことを改良していきます。
・ 武将を増やす
・ 自分で操作する武将と自動で動く武将を追加する
・ バグを減らす
・ ゲームクリア、ゲームオーバーの実装

※2021.4.10現在 完成しました。

4. 作成したコード

sangoku.py
#---------------------------------#
# 全て自分で操作する三国志            #
#---------------------------------#

import os
import random as rd

army = ['曹操', '孫堅', '劉備']
countries = ['長安', '建業' ,'成都']
army_num = [10, 5, 3]
attack_num = [0, 1]
year = 220

# 画面マップを描画する関数
def Drawmap():
    os.system('clear')
    print(str(year) + "")
    print()
    print("            長安")
    print("            " + army[0] + " " + str(army_num[0]))
    print()
    print("                              建業")
    print("                              " + army[1] + " " + str(army_num[1]))
    print()
    print(" 成都")
    print(" " + army[2] + " " + str(army_num[2]))
    print()

# 対戦をする関数
def attack(own, own_num, enemy):
    os.system('clear')
    print(countries[own] + "          " + countries[enemy])
    print(army[own] + str(own_num) + "000人" + "" + army[enemy] + str(army_num[enemy]) + "000人")
    print()

    number = own_num
    enemy_num = army_num[enemy]

    while(True):
        offence = rd.choice(attack_num)
        deffence = rd.choice(attack_num)

        if offence > deffence:
            enemy_num -= offence
            if enemy_num <= 0:
                print(army[own] + "  " + str(own_num*1000) + "人  X  " + army[enemy] + "  0人")
                break
            else:
                print(army[own] + "  " + str(own_num*1000) + "人  X  " + army[enemy] + "  " + str(enemy_num*1000) + "")
        elif offence < deffence:
            own_num -= deffence
            if own_num <= 0:
                print(army[own] + "  0人  X  " + army[enemy] + "  " + str(enemy_num*1000) + "")
                break
            else:
                print(army[own] + "  " + str(own_num*1000) + "人  X  " + army[enemy] + "  " + str(enemy_num*1000) + "")
        else:
            print(army[own] + "  " + str(own_num*1000) + "人  X  " + army[enemy] + "  " + str(enemy_num*1000) + "")
        
        input()

    if own_num > enemy_num:
        print()
        print(army[own] + "様 勝利!!")
        army[enemy] = army[own]
        army_num[enemy] = own_num
        army_num[own] -= number
    else:
        print()
        print(army[enemy] + "様 勝利!!")
        army_num[own] -= number
        army_num[enemy] = enemy_num
    input()


# メイン関数
while(True):
    for i in range(len(army)):
        Drawmap()
        print(countries[i] + "" + army[i] + "様 どちらへ攻撃しますか?" + " (" + str(i+1) + "/" + str(len(army)) + ")")
        for j in range(len(army)):
            if not j == i:
                print(str(j) + " : " + countries[j] + " " + army[j])
        print("3 : 温存")
        attack_counrty = int(input("攻撃する場所を入力 => "))

        if (attack_counrty == 0) or (attack_counrty == 1) or (attack_counrty == 2):
            at_num = int(input("何千人で攻撃しますか(1~9) => "))
            print()
            print(countries[i] + "" + army[i] + "様が" + str(at_num) + "000人で" + countries[attack_counrty] + "" + army[attack_counrty] + "様に攻撃!!")
            input()
            attack(i, at_num, attack_counrty)
        else:
            print()
            print("今年は兵力を温存するでござる")
            input()

    os.system('clear')
    print("兵力が回復しました。")
    for n in range(len(army)):
        army_num[n] += 1
    year += 1
    input()
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?