User=['흑태자',"엘린","데스","힐다"] # 유저

Team={'흑태자':"red","엘린":"red","데스":"blue","힐다":"blue"} # 팀

Supernova=["supernova1","supernova2","supernova3","supernova4",'supernova5'] # 초신성

Asura=["asura1","asura2","asura3"] # 아수라

Grima=['grima'] # 그리마

Open=['grima'] # 개방


Money={'흑태자':100,"엘린":200,"데스":300,"힐다":400} # 자산


Private=['뉴욕','파리','런던'] # 사유지

Non_Private=['서울','도쿄','싱가포르']

Area=Private+Non_Private # 지역

Non_Area=["출발지","올림픽","무인도",'세계여행']

Block=Area+Non_Area # 블록


Toll={"도쿄":1,"뉴욕":2,"서울":3,"파리":4,"런던":5,"싱가포르":6} # 통행료(지역)

Owner={"뉴욕":"엘린","파리":"데스","런던":"힐다",

       "supernova1":'흑태자',"supernova2":'흑태자',"supernova3":'흑태자',"supernova4":'흑태자',

       "asura1":'흑태자',"asura2":'흑태자',"asura3":'흑태자',"supernova5":'흑태자','grima':'흑태자'} # 주인(사유지)

Unit={'출발지':['출발지','흑태자'],"도쿄":['도쿄'],"뉴욕":['뉴욕','엘린'],"서울":['서울'],"파리":['파리','데스'],"런던":['런던','힐다'],"싱가포르":['싱가포르'],

      '올림픽':['올림픽'],'무인도':['무인도'],'세계여행':['세계여행']} # 유닛(블록)


def Arrive(x,y): # 도착

    if x in User:

        if y in Block: # 블록에 도착

            print(f"{x}가 {y}에 도착")

            if x=='흑태자' and y in Area:

                print("\n아토믹 블라스트! 모든 상대로부터 도착한 지역의 통행료만큼 마블 강탈!\n")

                for user in User:

                    if Team[x]!=Team[user] and not any(Owner[grima]==user and grima in Open for grima in Grima) and Toll[y]!=0:

                        Steal(x,Toll[y],user)

            if y in Private and Team[x]!=Team[Owner[y]]:

                Pay(x,Toll[y],Owner[y])

            if x=='흑태자':

                block=input("\n초신성을 생성할 블록을 선택하세요:\n")

                if block in Block:

                    for supernova in Supernova:

                        if Owner[supernova]==x and not any(supernova in Unit[block2] for block2 in Block):

                            Generate(x,supernova,block)

                            break

            for supernova in Supernova:

                if any(supernova in Unit[block] and y!=block for block in Block) and Team[Owner[supernova]]!=Team[x]:

                    if any(supernova in Unit[block] and x not in Unit[block] for block in Block) and not any(Owner[grima]==x and grima in Open for grima in Grima):

                        Draw(Owner[supernova],x,supernova)

            for asura in Asura:

                if any(asura in Unit[block] and y!=block for block in Block) and Owner[asura]==x:

                    print("\n진 아수라파천무! 아수라의 개수만큼 이동 후 모든 상대 호출!\n")

                    break

            for asura in Asura:

                if any(asura in Unit[block] and y!=block for block in Block) and Owner[asura]==x:

                    Move(x,asura)

                    for user in User:

                        if Team[x]!=Team[user] and not any(Owner[grima]==user and grima in Open for grima in Grima):

                            Call(x,user,asura)

        elif y in Asura: # 아수라에 도착

            print(f"{x}가 {y}에 도착")

            if x==Owner[y]:

                print("\n아수라 도착! 모든 상대 호출!\n")

                for user in User:

                    if Team[x]!=Team[user] and not any(Owner[grima]==user and grima in Open for grima in Grima):

                        Call(x,user,y)

            elif Team[x]!=Team[Owner[y]] and sum(Toll[area] for area in Area)!=0:

                Pay(x,sum(Toll[area] for area in Area),Owner[y])

        elif y in Supernova: # 초신성에 도착

            print(f"{x}가 {y}에 도착")

            if Team[x]!=Team[Owner[y]] and sum(Toll[area] for area in Area)!=0:

                Pay(x,sum(Toll[area] for area in Area),Owner[y])

        elif y in User and x!=y: # 유저에게 도착

            print(f"{x}가 {y}에게 도착")

            if any(Owner[grima]==x and grima in Open for grima in Grima) and not any(Owner[grima]==y and grima in Open for grima in Grima):

                Call(x,y,x)

            elif any(Owner[grima]==y and grima in Open for grima in Grima):

                Pay(x,sum(Toll[area] for area in Area),y)


def Generate(x,y,z): # 생성

    if x in User and z in Block:

        print(f"{x}가 {y}를 {z}에 생성")

        if y in Asura: # 아수라 생성

            for asura in Asura:

                if any(asura in Unit[block] and z!=block for block in Block) and Owner[asura]==Owner[y]:

                    for block in Block:

                        if asura in Unit[block]:

                            Unit[block].remove(asura)

            for asura in Asura:

                if asura in Unit[z] and Team[Owner[asura]]!=Team[Owner[y]]:

                    for block in Block:

                        if asura in Unit[block]:

                            Unit[block].remove(asura)

            for supernova in Supernova:

                if any(supernova in Unit[block] and z!=block for block in Block) and Team[Owner[supernova]]!=Team[Owner[y]]:

                    for block in Area:

                        if supernova in Unit[block]:

                            Unit[block].remove(supernova)

            Unit[z].append(y)

            if z in Area:

                if z in Private and Owner[y]!=Owner[z]:

                    Acquire(Owner[y],z)

                elif z in Non_Private:

                    Acquire(Owner[y],z)

            print("\n아수라파천무! 아수라로 이동 후 모든 상대 호출!\n")

            Move(Owner[y],y)

            for user in User:

                    if Team[Owner[y]]!=Team[user] and not any(Owner[grima]==user and grima in Open for grima in Grima):

                        Call(Owner[y],user,y)

        elif y in Supernova: # 초신성 생성

            for asura in Asura:

                if any(asura in Unit[block] and z!=block for block in Block) and Team[Owner[asura]]!=Team[Owner[y]]:

                    for block in Block:

                        if asura in Unit[block]:

                            Unit[block].remove(asura)

            for supernova in Supernova:

                if any(supernova in Unit[block] and z!=block for block in Block) and any(Team[Owner[y]]!=Team[user] and Team[user]!=Team[Owner[supernova]] for user in User):

                    for block in Block:

                        if supernova in Unit[block]:

                            Unit[block].remove(supernova)

            Unit[z].append(y)

            if z in Area:

                if z in Private and Owner[y]!=Owner[z]:

                    Acquire(Owner[y],z)

                elif z in Non_Private:

                    Acquire(Owner[y],z)

            for user in User:

                    if (Team[Owner[y]]!=Team[user] and not any(user in Unit[block] and y in Unit[block] for block in Block)

                        and not any(Owner[grima]==user and grima in Open for grima in Grima)):

                        print("\n모든 상대를 초신성으로 끌어당김!\n")

                        break

            for user in User:

                    if (Team[Owner[y]]!=Team[user] and not any(user in Unit[block] and y in Unit[block] for block in Block)

                        and not any(Owner[grima]==user and grima in Open for grima in Grima)):

                        Draw(Owner[y],user,y)

           

def Steal(x,y,z): # 강탈

    if x in User and z in User:

        print(f"{x}가 {y}억원을 {z}로부터 강탈")

        Money[x]+=y

        Money[z]-=y

        print(f"{x}: {Money[x]}억원, {z}: {Money[z]}억원")


def Pay(x,y,z): # 지불

    if x in User and z in User:

        print(f"{x}가 {y}억원을 {z}에게 지불")

        Money[x]-=y

        Money[z]+=y

        print(f"{x}: {Money[x]}억원, {z}: {Money[z]}억원")


def Draw(x,y,z): # 끌어당김

    if x in User and y in User:

        if z in User:

            print(f"{x}가 {y}를 {z}에게 끌어당김")

        else:

            print(f"{x}가 {y}를 {z}로 끌어당김")

        for block in Block:

            if y in Unit[block]:

                Unit[block].remove(y)

        for block in Block:

            if z in Unit[block]:

                Unit[block].append(y)

                unit=Unit[block]

        for i in range(unit.index(y)-1,-1,-1):

            Arrive(y,unit[i])


def Call(x,y,z): # 호출

    if x in User and y in User:

        if z in User:

            print(f"{x}가 {y}를 {z}에게 호출")

        else:

            print(f"{x}가 {y}를 {z}로 호출")

        for block in Block:

            if y in Unit[block]:

                Unit[block].remove(y)

        for block in Block:

            if z in Unit[block]:

                Unit[block].append(y)

                unit=Unit[block]

        for i in range(unit.index(y)-1,-1,-1):

            Arrive(y,unit[i])


def Move(x,y): # 순간이동

    if x in User:

        if y in User:

            print(f"{x}가 {y}에게 순간이동")

        else:

            print(f"{x}가 {y}로 순간이동")

        for block in Block:

            if x in Unit[block]:

                Unit[block].remove(x)

        for block in Block:

            if y in Unit[block]:

                Unit[block].append(x)

                unit=Unit[block]

        for i in range(unit.index(x)-1,-1,-1):

            Arrive(x,unit[i])


def Walk(x,y): # 걸어서 이동

    if x in User:

        if y in User:

            print(f"{x}가 {y}에게 걸어서 이동")

        else:

            print(f"{x}가 {y}로 걸어서 이동")

        for block in Block:

            if x in Unit[block]:

                Unit[block].remove(x)

        for block in Block:

            if y in Unit[block]:

                Unit[block].append(x)

                unit=Unit[block]

        for i in range(unit.index(x)-1,-1,-1):

            Arrive(x,unit[i])

       

def Acquire(x,y): # 획득

    if x in User:

        print(f"{x}가 {y}를 획득")

        if y in Area:

            if y in Private and x!=Owner[y]:

                Owner[y]=x

            elif y in Non_Private:

                Non_Private.remove(y)

                Private.append(y)

                Owner[y]=x

            if x=='흑태자':

                print("랜드마크 건설!")


# 주사위 턴 시작


print("게임 시작! 궁극 그리마 개방!")


for i in range(3):

    print("My turn!")

    block=input("\n아수라를 생성할 블록을 선택하세요:\n")

    if block in Block:

        for asura in Asura:

            if Owner[asura]=='흑태자' and not any(asura in Unit[block2] for block2 in Block):

                Generate('흑태자',asura,block)

                break


    block=input("\n(주사위 굴린 후) 이동할 블록을 선택하세요:\n")

    if block in Block and '흑태자' not in Unit[block]:

        Walk('흑태자',block)


    print("\n주사위 턴 종료! 모든 상대로부터 전체 통행료 총합만큼 마블 강탈!\n")

    for user in User:

        if Team['흑태자']!=Team[user] and not any(Owner[grima]==user and grima in Open for grima in Grima):

            Steal('흑태자',sum(Toll[area] for area in Area),user)