app/modules/parse_input.py
import re
from app.modules.shogi import Koma
str2info = {
"一": 0, "1": 0, "1": 0,
"二": 1, "2": 1, "2": 1,
"三": 2, "3": 2, "3": 2,
"四": 3, "4": 3, "4": 3,
"五": 4, "5": 4, "5": 4,
"六": 5, "6": 5, "6": 5,
"七": 6, "7": 6, "7": 6,
"八": 7, "8": 7, "8": 7,
"九": 8, "9": 8, "9": 8
}
str2koma = {
"歩": Koma.fu, "と": Koma.promoted_fu,
"成歩": Koma.promoted_fu, "成と": Koma.promoted_fu,
"香": Koma.kyosha, "香車": Koma.kyosha,
"成香": Koma.promoted_kyosha, "成香車": Koma.promoted_kyosha,
"桂": Koma.keima, "桂馬": Koma.keima,
"成桂": Koma.promoted_keima, "成桂馬": Koma.promoted_keima,
"銀": Koma.gin, "銀将": Koma.gin,
"成銀": Koma.promoted_gin, "成銀将": Koma.promoted_gin,
"金": Koma.kin, "金将": Koma.kin,
"成金": Koma.kin, "成金将": Koma.kin,
"角": Koma.kaku, "角行": Koma.kaku, "馬": Koma.promoted_kaku,
"成角": Koma.promoted_kaku, "成角行": Koma.promoted_kaku,
"成馬": Koma.promoted_kaku,
"飛": Koma.hisha, "飛車": Koma.hisha, "龍": Koma.promoted_hisha,
"成飛": Koma.promoted_hisha, "成飛車": Koma.promoted_hisha,
"成龍": Koma.promoted_hisha,
"王": Koma.gyoku, "玉": Koma.gyoku,
"王将": Koma.gyoku, "玉将": Koma.gyoku,
"成王": Koma.gyoku, "成玉": Koma.gyoku,
"成王将": Koma.gyoku, "成玉将": Koma.gyoku
}
str2oppkoma = {
"歩": Koma.opponent_fu, "と": Koma.opponent_promoted_fu,
"成歩": Koma.opponent_promoted_fu, "成と": Koma.opponent_promoted_fu,
"香": Koma.opponent_kyosha, "香車": Koma.opponent_kyosha,
"成香": Koma.opponent_promoted_kyosha,
"成香車": Koma.opponent_promoted_kyosha,
"桂": Koma.opponent_keima, "桂馬": Koma.opponent_keima,
"成桂": Koma.opponent_promoted_keima,
"成桂馬": Koma.opponent_promoted_keima,
"銀": Koma.opponent_gin, "銀将": Koma.opponent_gin,
"成銀": Koma.opponent_promoted_gin,
"成銀将": Koma.opponent_promoted_gin,
"金": Koma.opponent_kin, "金将": Koma.opponent_kin,
"成金": Koma.opponent_kin, "成金将": Koma.opponent_kin,
"角": Koma.opponent_kaku, "角行": Koma.opponent_kaku,
"馬": Koma.opponent_promoted_kaku,
"成角": Koma.opponent_promoted_kaku,
"成角行": Koma.opponent_promoted_kaku,
"成馬": Koma.opponent_promoted_kaku,
"飛": Koma.opponent_hisha, "飛車": Koma.opponent_hisha,
"龍": Koma.opponent_promoted_hisha,
"成飛": Koma.opponent_promoted_hisha,
"成飛車": Koma.opponent_promoted_hisha,
"成龍": Koma.opponent_promoted_hisha,
"王": Koma.opponent_gyoku, "玉": Koma.opponent_gyoku,
"王将": Koma.opponent_gyoku, "玉将": Koma.opponent_gyoku,
"成王": Koma.opponent_gyoku, "成玉": Koma.opponent_gyoku,
"成王将": Koma.opponent_gyoku, "成玉将": Koma.opponent_gyoku
}
koma_names = [
"歩", "と",
"香", "香車",
"桂", "桂馬",
"銀", "銀将",
"金", "金将",
"角", "角行", "馬",
"飛", "飛車", "龍",
"王", "玉", "王将", "玉将"
]
koma_names += list(map(lambda n: "成" + n, koma_names))
def transposition_num(num):
"""
transposition axis(y) number.
0 => 8, 1 => 7, ..., 8 => 0
"""
return (4 - num) + 4
class ParseInput:
@staticmethod
def parse(input_str, shogi):
"""
parse input text and get (from, to) Coordinate.
"""
is_first_turn = shogi.first
def get_koma():
# input_str is only koma name
if input_str in koma_names:
if is_first_turn:
koma = str2koma[input_str]
else:
koma = str2oppkoma[input_str]
return koma
return False
# promote
promote = False
if input_str[-1] == ("成"):
if input_str.find("打") != -1:
return False
if input_str[-2] == ("不"):
input_str = input_str.replace("不成", "")
else:
# TODO : Detect to be able to promote
promote = True
input_str = input_str.replace("成", "")
# same
if input_str.find("同") != -1:
idx = input_str.find("同") + 1
input_str = input_str[idx:]
to_x = shogi.last_move_x
to_y = shogi.last_move_y
# get to_x, to_y from text
else:
if input_str[0] in str2info and input_str[0] in str2info:
to_x = transposition_num(str2info[input_str[0]])
to_y = str2info[input_str[1]]
else:
# TODO : Send Error Message
return False
input_str = input_str[2:] # remove number of axis
# setting from flag
from_flag = 0
if input_str.find("上") != -1:
from_flag = 1
input_str = input_str.replace("上", "")
if input_str.find("右") != -1:
from_flag += 2
input_str = input_str.replace("右", "")
# 3 => 右上
if input_str.find("引") != -1:
from_flag += 4
input_str = input_str.replace("引", "")
# 5 => None
# 6 => 右引
# 7 => None
if input_str.find("左") != -1:
from_flag += 8
input_str = input_str.replace("左", "")
# 9 => 左上
# 10,11 => None
# 12 => 左引
# 13~15 => None
if input_str.find("寄") != -1:
from_flag = 16
input_str = input_str.replace("寄", "")
if input_str.find("直") != -1:
from_flag = 17
input_str = input_str.replace("直", "")
# drop
if input_str.find("打") != -1:
from_x = -1
from_y = -1
input_str = input_str.replace("打", "")
koma = get_koma()
if shogi.droppable(koma, to_x, to_y):
return (from_x, from_y, to_x, to_y, promote, koma)
else:
return False
# if in this block, input_str is only koma name
koma = get_koma()
if not koma:
return False
candidate_komas = shogi.find_koma(koma)
movable_komas = []
for candidate_koma in candidate_komas:
if shogi.movable(candidate_koma[0],
candidate_koma[1],
to_x, to_y, promote):
movable_komas.append(candidate_koma)
if len(movable_komas) == 0:
# TODO : Send Error Message
return False
elif len(movable_komas) == 1:
from_x = movable_komas[0][0]
from_y = movable_komas[0][1]
else:
turn = is_first_turn # for pep
# "上"
if from_flag == 1:
for t in movable_komas: # t => "t"arget
if (turn and t[1] > to_y) or \
(not turn and t[1] < to_y):
from_x, from_y = t
from_flag = 0
break
# "右"
elif from_flag == 2:
for t in movable_komas:
if (turn and t[0] > to_x) or \
(not turn and t[0] < to_x):
from_x, from_y = t
from_flag = 0
break
# "右上"
elif from_flag == 3:
for t in movable_komas:
if (turn and t[0] > to_x and t[1] > to_y) or \
(not turn and t[0] < to_x and t[1] < to_y):
from_x, from_y = t
from_flag = 0
break
# "引"
elif from_flag == 4:
for t in movable_komas:
if (turn and t[1] < to_y) or \
(not turn and t[1] > to_y):
from_x, from_y = t
from_flag = 0
break
# "右引"
elif from_flag == 6:
for t in movable_komas:
if (turn and t[0] > to_x and t[1] < to_y) or \
(not turn and t[0] < to_x and t[1] > to_y):
from_x, from_y = t
from_flag = 0
break
# "左"
elif from_flag == 8:
for t in movable_komas:
if (turn and t[0] < to_x) or \
(not turn and t[0] > to_x):
from_x, from_y = t
from_flag = 0
break
# "左上"
elif from_flag == 9:
for t in movable_komas:
if (turn and t[0] < to_x and t[1] > to_y) or \
(not turn and t[0] > to_x and t[1] < to_y):
from_x, from_y = t
from_flag = 0
break
# "左引"
elif from_flag == 12:
for t in movable_komas:
if (turn and t[0] < to_x and t[1] < to_y) or \
(not turn and t[0] > to_x and t[1] > to_y):
from_x, from_y = t
from_flag = 0
break
# "寄"
elif from_flag == 16:
for t in movable_komas:
if (t[1] == to_y):
from_x, from_y = t
from_flag = 0
break
# "直"
elif from_flag == 17:
for t in movable_komas:
if (t[0] == to_x and ((turn and t[1] > to_y) or (not turn and t[1] < to_y))):
from_x, from_y = t
from_flag = 0
break
# TODO : Send Error Message
if from_flag != 0:
return False
return (from_x, from_y, to_x, to_y, promote, koma)