Pythonを使って『三国志大戦』の実装
目次
- 作成の経緯
- 作成手順
- 次回に向けて
- 作成したコード全体
1. 作成の経緯
ゲームの制作をしてみたいと思い、好きでよくやっていた「三国志大戦」に目をつけて、自分で作ってみようと思いました。ゲームであればC++やC#がメジャーだとは思いますが、自由に扱える訳ではない(力量が足りない)ため、自信が得意としているPythonで実装することにしました。
2. 作成手順
1. キャラクター設定
今回使用するキャラクターは三国志でも有名な3名を使います。
・曹操 → 長安
・劉備 → 成都
・孫堅 → 建業
※都は適当につけています。
今回の注意点として、
- 武将による能力の差はない。
- 能力の代わりに兵量によって分ける。
ということです。(今後、改良予定です。)
こちらの武将・都・人数を配列に格納します。
army = ['曹操', '孫堅', '劉備'] #武将(キャラクター)
countries = ['長安', '建業' ,'成都'] #都
army_num = [10, 5, 3] #人数
2. 画面(地図の描画)
続けて地図を描画します。今回は何度も地図を呼び出すため関数にしています。
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. 攻撃する場所・攻撃人数の入力
続けてどこに攻撃するか、何人で攻撃するのかを入力します。
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、を入力することができます。
攻撃人数はこのように指定します。
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人ずつ減るように指定しました。初期化で、
attack_num = [0, 1]
を指定しました。randomのchoiceを使って、どちらかを選択して人数が減るようになっています。
攻撃全体のコードはこちらです。
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. 作成したコード
#---------------------------------#
# 全て自分で操作する三国志 #
#---------------------------------#
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()