Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将某物称为对象而不是列表?_Python_Python 3.x_Oop_Multidimensional Array_Game Engine - Fatal编程技术网

Python 如何将某物称为对象而不是列表?

Python 如何将某物称为对象而不是列表?,python,python-3.x,oop,multidimensional-array,game-engine,Python,Python 3.x,Oop,Multidimensional Array,Game Engine,假设我有两个MapTile类的对象: class MapTile(object): #The main class for stationary things that inhabit the grid ... grass, trees, rocks and stuff. def __init__(self, name, internal_column, internal_row, visible): self.

假设我有两个MapTile类的对象:

class MapTile(object):                       #The main class for stationary things that inhabit the grid ... grass, trees, rocks and stuff.
        def __init__(self, name, internal_column, internal_row, visible):
            self.name = name
            self.internal_column = internal_column
            self.internal_row = internal_row
            self.visible = visible
它们位于二维数组中,各自的内部_列和内部_行属性表示它们在数组中的坐标

我想写一个函数,返回两个这样的对象之间的距离。以下是我到目前为止的情况:

def return_distance(self, pointA, pointB):
        distance = math.sqrt((pointA.internal_column - pointB.internal_column)**2 + (pointA.internal_row - pointB.internal_row)**2)
        return distance
其中,pointA和pointB是两个对象

当我尝试时,会出现以下错误:

Traceback (most recent call last):
  File "/Users/kosay.jabre/Desktop/Monster.py", line 380, in <module>
    Map.update()
  File "/Users/kosay.jabre/Desktop/Monster.py", line 297, in update
    if Map.return_distance(Map.Grid[column][row], character) <= character.visionrange:
  File "/Users/kosay.jabre/Desktop/Monster.py", line 245, in return_distance
    distance = math.sqrt((pointA.internal_column - pointB.internal_column)**2 + (pointA.internal_row - pointB.internal_row)**2)
AttributeError: 'list' object has no attribute 'internal_column'
我直接把东西添加到地图上。每个人都喜欢这样:

for column in range(MAPSIZE):
            for row in range(MAPSIZE):
                for i in range(len(Map.Grid[column][row])):
                    if Map.Grid[column][row][i].__class__.__name__ == "Character":
                        Map.everyone.append(Map.Grid[column][row][i])
下面是我正在运行的完整代码:

import random
import math
import pygame

pygame.init()                                 
Clock = pygame.time.Clock()                   
Screen = pygame.display.set_mode([650, 650])  
DONE = False                                  
MAPSIZE = 25   #how many tiles
TURN = 0


TILEWIDTH  = 20    #pixel size of tile                               
TILEHEIGHT = 20
TILEMARGIN = 4

BLACK = (0, 0, 0)                             
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
BROWN = (123, 123, 0)
MOVECOLOR = (150, 250, 150)

KeyLookup = {
    pygame.K_LEFT: "W",
    pygame.K_RIGHT: "E",
    pygame.K_DOWN: "S",
    pygame.K_UP: "N"
}

class MapTile(object):                       #The main class for stationary things that inhabit the grid ... grass, trees, rocks and stuff.
    def __init__(self, name, internal_column, internal_row, visible):
        self.name = name
        self.internal_column = internal_column
        self.internal_row = internal_row
        self.visible = visible

class Character(object):                    #can move around and do cool stuff
    def __init__(self, name, HP, internal_column, internal_row, damage, allegiance):
        self.name = name
        self.HP = HP
        self.internal_column = internal_column
        self.internal_row = internal_row
        self.damage = damage
        self.allegiance = allegiance

    visionrange = 10
    moves_left = 15
    direction = "N"

    def move(self, direction):      #how characters move around
        if self.collision_check(direction):
            print("Collision")
            return
        if self.moves_left == 0:
            print("No more moves left")
            return

        elif direction == "N":                    
                self.internal_row -= 1
                self.direction = "N"
        elif direction == "W":
                self.internal_column -= 1
                self.direction = "W"
        elif direction == "E":
                self.internal_column += 1
                self.direction = "E"
        elif direction == "S":
                self.internal_row += 1
                self.direction = "S"

        self.moves_left = self.moves_left - 1


    def collision_check(self, direction):       
        if direction == "N":
            if self.internal_row == 0:
                return True
            if len(Map.Grid[self.internal_column][(self.internal_row)-1]) > 1:
                return True
        elif direction == "W":
            if self.internal_column == 0:
                return True
            if len(Map.Grid[self.internal_column-1][(self.internal_row)]) > 1:
                return True
        elif direction == "E":
            if self.internal_column == MAPSIZE-1:
                return True
            if len(Map.Grid[self.internal_column+1][(self.internal_row)]) > 1:
                return True
        elif direction == "S":
            if self.internal_row == MAPSIZE-1:
                return True
            if len(Map.Grid[self.internal_column][(self.internal_row)+1]) > 1:
                return True

        return False

    def attack(self, direction):
        if self.collision_check(direction):
            print("Attack attempt.")
            if self.direction == "N":
              for i in range(0, len(Map.Grid[self.internal_column][self.internal_row-1])):
                if Map.Grid[int(self.internal_column)][int(self.internal_row-1)][i].__class__.__name__ == "Character":
                    Map.Grid[self.internal_column][self.internal_row-1][i].HP -= self.damage
                    print(str(self.damage) + " damage")
            elif self.direction == "E":
                for i in range(0, len(Map.Grid[self.internal_column+1][self.internal_row])):
                    if Map.Grid[self.internal_column+1][self.internal_row][i].__class__.__name__ == "Character":
                        Map.Grid[self.internal_column+1][self.internal_row][i].HP -= self.damage
                        print(str(self.damage) + " damage")
            elif self.direction == "W":
                for i in range(0, len(Map.Grid[self.internal_column-1][self.internal_row])):
                    if Map.Grid[self.internal_column-1][self.internal_row][i].__class__.__name__ == "Character":
                        Map.Grid[self.internal_column-1][self.internal_row][i].HP -= self.damage
                        print(str(self.damage) + " damage")
            elif self.direction == "S":
                for i in range(0, len(Map.Grid[self.internal_column][self.internal_row+1])):
                    if Map.Grid[self.internal_column][self.internal_row+1][i].__class__.__name__ == "Character":
                        Map.Grid[self.internal_column][self.internal_row+1][i].HP -= self.damage
                        print(str(self.damage) + " damage")

            self.moves_left = self.moves_left - 1

    def ranged_attack(self, direction):
            if self.direction == "S":
                for k in range(1, (MAPSIZE - self.internal_row)):
                    for i in range(0, len(Map.Grid[self.internal_column][self.internal_row + k])):
                        if Map.Grid[self.internal_column][self.internal_row + k][i].__class__.__name__ == "Character":
                            Map.Grid[self.internal_column][self.internal_row + k][i].HP -= self.damage
                            print(str(self.damage) + " damage")
                            self.moves_left = self.moves_left - 1 
            if self.direction == "N":
                for k in range(1, self.internal_row):
                    for i in range(0, len(Map.Grid[self.internal_column][self.internal_row - k])):
                        if Map.Grid[self.internal_column][self.internal_row - k][i].__class__.__name__ == "Character":
                            Map.Grid[self.internal_column][self.internal_row - k][i].HP -= self.damage
                            print(str(self.damage) + " damage")
                            self.moves_left = self.moves_left - 1
            if self.direction == "W":
                for k in range(1, self.internal_column):
                    for i in range(0, len(Map.Grid[self.internal_column - k][self.internal_row])):
                        if Map.Grid[self.internal_column - k][self.internal_row][i].__class__.__name__ == "Character":
                            Map.Grid[self.internal_column - k][self.internal_row][i].HP -= self.damage
                            print(str(self.damage) + " damage")
                            self.moves_left = self.moves_left - 1
            if self.direction == "E":
                for k in range(1, (MAPSIZE - self.internal_column)):
                    for i in range(0, len(Map.Grid[self.internal_column + k][self.internal_row])):
                        if Map.Grid[self.internal_column + k][self.internal_row][i].__class__.__name__ == "Character":
                            Map.Grid[self.internal_column + k][self.internal_row][i].HP -= self.damage
                            print(str(self.damage) + " damage")
                            self.moves_left = self.moves_left - 1
            else:
                return 


class Goblin(Character):
    def __init__(self):
        Character.__init__(self, "Goblin", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1), 10, random.randint(0,1))

    def random_move(self):
        i = random.randint(0,3)
        if i == 0:
            self.move("N")
        elif i == 1:
            self.move("S")
        elif i == 2:
            self.move("W")
        elif i == 3:
            self.move("E")

        self.moves_left = 10


class Archer(Character):
    def __init__(self):
        Character.__init__(self, "Archer", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Warrior(Character):
    def __init__(self):
        Character.__init__(self, "Warrior", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Scout(Character):
    def __init__(self):
        Character.__init__(self, "Scout", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Rogue(Character):
    def __init__(self):
        Character.__init__(self, "Rogue", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Wizard(Character):
    def __init__(self):
        Character.__init__(self, "Wizard", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Map(object):              #The main class; where the action happens
    global MAPSIZE
    wild_characters = []
    can_move = []
    no_moves = []
    Grid = []
    friendlies = []
    enemies = []
    everyone = [friendlies + enemies]
    visible = []

    for row in range(MAPSIZE):     # Creating grid
        Grid.append([])
        for column in range(MAPSIZE):
            Grid[row].append([])

    for row in range(MAPSIZE):     #Filling grid with grass
        for column in range(MAPSIZE):
            TempTile = MapTile("Grass", column, row, False)
            Grid[column][row].append(TempTile)

    for row in range(MAPSIZE):     #Putting some rocks near the top
        for column in range(MAPSIZE):
            TempTile = MapTile("Rock", column, row, False)
            if row == 1:
                Grid[column][row].append(TempTile)

    for i in range(10):         #Trees in random places
        random_row = random.randint(0, MAPSIZE - 1)
        random_column = random.randint(0, MAPSIZE - 1)
        TempTile = MapTile("Tree", random_column, random_row, False)
        Grid[random_column][random_row].append(TempTile)

    def generate_hero(self):            #Generate a character and place it randomly
        temp_hero = Character("Hero", 30, random.randint(0, MAPSIZE - 1), random.randint(0, MAPSIZE - 1) , 10, random.randint(0,1))
        self.Grid[temp_hero.internal_column][temp_hero.internal_row].append(temp_hero)
        self.can_move.append(temp_hero)
        if temp_hero.allegiance == 0:
            self.friendlies.append(temp_hero)
        elif temp_hero.allegiance == 1:
            self.enemies.append(temp_hero)

    def return_distance(self, pointA, pointB):
        distance = math.sqrt((pointA.internal_column - pointB.internal_column)**2 + (pointA.internal_row - pointB.internal_row)**2)
        return distance

    def generate_goblin(self):            #Generate a character and place it randomly
        random_row = random.randint(0, MAPSIZE - 1)
        random_column = random.randint(0, MAPSIZE - 1)
        temp_goblin = Goblin()
        self.Grid[random_column][random_row].append(temp_goblin)
        Map.wild_characters.append(temp_goblin)

    def update(self):           
        for column in range(MAPSIZE):                           #These nested loops go through entire grid 
            for row in range(MAPSIZE):                          #They check if any objects internal coordinates
                for i in range(len(Map.Grid[column][row])):     #disagree with its place on the grid and update it accordingly                            
                    if Map.Grid[column][row][i].internal_column != column:
                        TempChar = Map.Grid[column][row][i]
                        Map.Grid[column][row].remove(Map.Grid[column][row][i])
                        Map.Grid[int(TempChar.internal_column)][int(TempChar.internal_row)].append(TempChar)

                    elif Map.Grid[column][row][i].internal_row != row:
                        TempChar = Map.Grid[column][row][i]
                        Map.Grid[column][row].remove(Map.Grid[column][row][i])
                        Map.Grid[int(TempChar.internal_column)][int(TempChar.internal_row)].append(TempChar)

        temparr = Map.no_moves[:]
        for characterobject in temparr:    #This moves any characters with moves to the can move list 
            if len(temparr) > 0:
                if characterobject.moves_left > 0:
                    Map.can_move.append(characterobject)
                    Map.no_moves.remove(characterobject)
            if characterobject.HP <= 0:
                Map.no_moves.remove(characterobject)

        arr = Map.can_move[:] # copy
        for item in arr:
            if item.moves_left == 0:
                Map.can_move.remove(item)
                Map.no_moves.append(item)
            if item.HP <= 0:
                Map.can_move.remove(item)

        for column in range(MAPSIZE):                           
            for row in range(MAPSIZE):                          
                for i in range(len(Map.Grid[column][row])):     
                    if Map.Grid[column][row][i].__class__.__name__ == "Character":
                        if Map.Grid[column][row][i].HP <= 0:
                            Map.Grid[column][row].remove(Map.Grid[column][row][i])
                            print("Character died")

        for column in range(MAPSIZE):
            for row in range(MAPSIZE):
                for i in range(len(Map.Grid[column][row])):
                    if Map.Grid[column][row][i].__class__.__name__ == "Character":
                        Map.everyone.append(Map.Grid[column][row][i])

        for character in Map.everyone:            
            for column in range(MAPSIZE):
                for row in range(MAPSIZE):
                    if Map.return_distance(Map.Grid[column][row][0], character ) <= 15:
                        Map.Grid[column][row].visible = True

    def listofcharacters(self):
        for column in range(MAPSIZE):
            for row in range(MAPSIZE):
                for i in range(len(Map.Grid[column][row])):
                    if Map.Grid[column][row][i].__class__.__name__ == "Character":
                        print("Column: ", Map.Grid[column][row][i].internal_column, ", Row: ", Map.Grid[column][row][i].internal_row, ", Allegiance: ", Map.Grid[column][row][i].allegiance)





Map = Map()
Map.generate_hero()

while not DONE:     #Main pygame loop
    for event in pygame.event.get():         #catching events
        if event.type == pygame.QUIT:
            DONE = True       
        elif event.type == pygame.MOUSEBUTTONDOWN:
            Pos = pygame.mouse.get_pos()
            column = Pos[0] // (TILEWIDTH + TILEMARGIN)  #Translating the position of the mouse into rows and columns
            row = Pos[1] // (TILEHEIGHT + TILEMARGIN)
            print(str(row) + ", " + str(column))

            for i in range(len(Map.Grid[column][row])):
                print(str(Map.Grid[column][row][i].name))  #print stuff that inhabits that square

        elif event.type == pygame.KEYDOWN:
            wild_char_arr = Map.wild_characters[:]

            for wildcharacter in wild_char_arr:
                if wildcharacter.name == "Goblin":
                    wildcharacter.random_move() 

            if event.key == 97:      # Keypress: a
                print("New turn.")
                temparr = Map.no_moves[:]
                for item in temparr:
                    if item.moves_left == 0:
                        item.moves_left = 15
                TURN = TURN + 1
                print("Turn: ", TURN)

            elif event.key == 115:    # Keypress: s
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 113:    # Keypress: q     
                print("ranged attack")
                Map.can_move[0].ranged_attack(Map.can_move[0].direction)

            elif event.key == 119:    # Keypress: w
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 101:    # Keypress: e
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 114:    # Keypress: r
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 116:    # Keypress: t
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 100:  # Keypress: d
                Map.generate_goblin()
                print("Generated goblin.")

            elif event.key == 102:  # Keypress: f
                Map.can_move[0].attack(Map.can_move[0].direction) 

            elif len(Map.can_move) > 0:
                Map.can_move[0].move(KeyLookup[event.key])

            else:
                print("invalid")

            Map.update()

    Screen.fill(BLACK)

    for row in range(MAPSIZE):           # Drawing grid
        for column in range(MAPSIZE):
            for i in range(0, len(Map.Grid[column][row])):
                Color = WHITE

                if len(Map.can_move) > 0:   # Creating colored area around character showing his move range
                    if (math.sqrt((Map.can_move[0].internal_column - column)**2 + (Map.can_move[0].internal_row - row)**2)) <= Map.can_move[0].moves_left:
                        Color = MOVECOLOR

                if len(Map.Grid[column][row]) > 1:
                    Color = RED
                if Map.Grid[column][row][i].name == "Tree":

                    Color = GREEN
                if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                    Color = BROWN

            pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN,
                                             TILEWIDTH,
                                             TILEHEIGHT])

            if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                if Map.Grid[column][row][i].direction == "N":
                    Color = RED

                    pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN + 8,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN,
                                             TILEWIDTH/4,
                                             TILEHEIGHT/4])

            if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                if Map.Grid[column][row][i].direction == "S":
                    Color = RED

                    pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN + 8,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN*5 - 1 ,
                                             TILEWIDTH/4,
                                             TILEHEIGHT/4])

            if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                if Map.Grid[column][row][i].direction == "E":
                    Color = RED

                    pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN + 15,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN*5 - 8,
                                             TILEWIDTH/4,
                                             TILEHEIGHT/4])

            if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                if Map.Grid[column][row][i].direction == "W":
                    Color = RED

                    pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN
                                                     ,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN*5 - 8 ,
                                             TILEWIDTH/4,
                                             TILEHEIGHT/4])


    Clock.tick(60)      
    pygame.display.flip()     

pygame.quit()
随机导入
输入数学
导入pygame
pygame.init()
Clock=pygame.time.Clock()
Screen=pygame.display.set_模式([650650])
完成=错误
MAPSIZE=25#有多少个瓷砖
转动=0
瓷砖宽度=20#瓷砖的像素大小
瓷砖高度=20
TILEMARGIN=4
黑色=(0,0,0)
白色=(255,255,255)
绿色=(0,255,0)
红色=(255,0,0)
蓝色=(0,0255)
布朗=(123123,0)
MOVECOLOR=(150250150)
键查找={
pygame.K_左:“W”,
pygame.K_右:“E”,
pygame.K_向下:“S”,
pygame.K_UP:“N”
}
类MapTile(object):#用于栅格中静止物体的主类。。。草,树,石头等等。
def uu init uu(self,name,internal_列,internal_行,可见):
self.name=名称
self.internal\u列=internal\u列
self.internal\u行=internal\u行
self.visible=可见
职业角色(对象):#可以四处走动,做一些很酷的事情
定义初始值(自我、姓名、生命、内部列、内部行、伤害、忠诚):
self.name=名称
self.HP=HP
self.internal\u列=internal\u列
self.internal\u行=internal\u行
自毁
自我效忠
visionrange=10
向左移动=15
方向=“N”
定义移动(自我、方向):#角色如何移动
如果自碰撞检查(方向):
打印(“冲突”)
返回
如果self.moves_left==0:
打印(“不再向左移动”)
返回
elif方向==“N”:
self.internal_行-=1
self.direction=“N”
elif方向==“W”:
self.internal_列-=1
self.direction=“W”
elif方向==“E”:
self.internal_列+=1
self.direction=“E”
elif方向==“S”:
self.internal_行+=1
self.direction=“S”
self.moves\u left=self.moves\u left-1
def碰撞检查(自身、方向):
如果方向==“N”:
如果self.internal_row==0:
返回真值
如果len(映射网格[self.internal\u列][(self.internal\u行)-1])>1:
返回真值
elif方向==“W”:
如果self.internal_列==0:
返回真值
如果len(映射网格[self.internal\u column-1][(self.internal\u row)])>1:
返回真值
elif方向==“E”:
如果self.internal_column==MAPSIZE-1:
返回真值
如果len(映射网格[self.internal\u column+1][(self.internal\u row)])>1:
返回真值
elif方向==“S”:
如果self.internal_row==MAPSIZE-1:
返回真值
如果len(映射网格[self.internal\u列][(self.internal\u行)+1])>1:
返回真值
返回错误
def攻击(自身、方向):
如果自碰撞检查(方向):
打印(“攻击尝试”)
如果self.direction==“N”:
对于范围(0,len(Map.Grid[self.internal\u column][self.internal\u row-1])中的i:
如果Map.Grid[int(self.internal\u column)][int(self.internal\u row-1)][i]。\uuuuuuuuu类\uuuuuuuuuu名称\uuuuuuuuuuuu==“字符”:
Map.Grid[self.internal\u column][self.internal\u row-1][i].HP-=self.damage
打印(str(自我伤害)+“伤害”)
elif self.direction==“E”:
对于范围内的i(0,len(Map.Grid[self.internal\u column+1][self.internal\u row]):
如果Map.Grid[self.internal\u column+1][self.internal\u row][i]。\uuuuuuuuu class\uuuuuuu.\uuuuuuuuuu name\uuuuuuuuuu==“Character”:
Map.Grid[self.internal\u column+1][self.internal\u row][i].HP-=self.damage
打印(str(自我伤害)+“伤害”)
elif self.direction==“W”:
对于范围(0,len(Map.Grid[self.internal\u column-1][self.internal\u row])中的i:
如果Map.Grid[self.internal\u column-1][self.internal\u row][i]。\uuuuuuuuuu class\uuuuuuuuuuuuuu name\uuuuuuuuuuuuu==“Character”:
Map.Grid[self.internal\u column-1][self.internal\u row][i].HP-=self.damage
打印(str(自我伤害)+“伤害”)
elif self.direction==“S”:
对于范围内的i(0,len(Map.Grid[self.internal\u column][self.internal\u row+1]):
如果Map.Grid[self.internal\u column][self.internal\u row+1][i]。\uuuuuuuuu class\uuuuuuuuuuuu name\uuuuuuuuuuu==“Character”:
Map.Grid[self.internal\u column][self.internal\u row+1][i].HP-=self.damage
打印(str(自我伤害)+“伤害”)
self.moves\u left=self.moves\u left-1
远程攻击(自我、方向):
如果self.direction==“S”:
对于范围(1)(MAPSIZE-self.internal_行)中的k:
对于范围内的i(0,len(Map.Grid[self.internal\u column][self.internal\u row+k]):
如果Map.Grid[self.internal\u column][self.internal\u row+k][i]。\uuuuuuuuu class\uuuuuuuuuuu name\uuuuuuuuuuu==“Character”:
Map.Grid[self.internal\u column][self.internal\u row+k][i].HP-=self.damage
打印(str(自我伤害)+“伤害
for column in range(MAPSIZE):
            for row in range(MAPSIZE):
                for i in range(len(Map.Grid[column][row])):
                    if Map.Grid[column][row][i].__class__.__name__ == "Character":
                        Map.everyone.append(Map.Grid[column][row][i])
import random
import math
import pygame

pygame.init()                                 
Clock = pygame.time.Clock()                   
Screen = pygame.display.set_mode([650, 650])  
DONE = False                                  
MAPSIZE = 25   #how many tiles
TURN = 0


TILEWIDTH  = 20    #pixel size of tile                               
TILEHEIGHT = 20
TILEMARGIN = 4

BLACK = (0, 0, 0)                             
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
BROWN = (123, 123, 0)
MOVECOLOR = (150, 250, 150)

KeyLookup = {
    pygame.K_LEFT: "W",
    pygame.K_RIGHT: "E",
    pygame.K_DOWN: "S",
    pygame.K_UP: "N"
}

class MapTile(object):                       #The main class for stationary things that inhabit the grid ... grass, trees, rocks and stuff.
    def __init__(self, name, internal_column, internal_row, visible):
        self.name = name
        self.internal_column = internal_column
        self.internal_row = internal_row
        self.visible = visible

class Character(object):                    #can move around and do cool stuff
    def __init__(self, name, HP, internal_column, internal_row, damage, allegiance):
        self.name = name
        self.HP = HP
        self.internal_column = internal_column
        self.internal_row = internal_row
        self.damage = damage
        self.allegiance = allegiance

    visionrange = 10
    moves_left = 15
    direction = "N"

    def move(self, direction):      #how characters move around
        if self.collision_check(direction):
            print("Collision")
            return
        if self.moves_left == 0:
            print("No more moves left")
            return

        elif direction == "N":                    
                self.internal_row -= 1
                self.direction = "N"
        elif direction == "W":
                self.internal_column -= 1
                self.direction = "W"
        elif direction == "E":
                self.internal_column += 1
                self.direction = "E"
        elif direction == "S":
                self.internal_row += 1
                self.direction = "S"

        self.moves_left = self.moves_left - 1


    def collision_check(self, direction):       
        if direction == "N":
            if self.internal_row == 0:
                return True
            if len(Map.Grid[self.internal_column][(self.internal_row)-1]) > 1:
                return True
        elif direction == "W":
            if self.internal_column == 0:
                return True
            if len(Map.Grid[self.internal_column-1][(self.internal_row)]) > 1:
                return True
        elif direction == "E":
            if self.internal_column == MAPSIZE-1:
                return True
            if len(Map.Grid[self.internal_column+1][(self.internal_row)]) > 1:
                return True
        elif direction == "S":
            if self.internal_row == MAPSIZE-1:
                return True
            if len(Map.Grid[self.internal_column][(self.internal_row)+1]) > 1:
                return True

        return False

    def attack(self, direction):
        if self.collision_check(direction):
            print("Attack attempt.")
            if self.direction == "N":
              for i in range(0, len(Map.Grid[self.internal_column][self.internal_row-1])):
                if Map.Grid[int(self.internal_column)][int(self.internal_row-1)][i].__class__.__name__ == "Character":
                    Map.Grid[self.internal_column][self.internal_row-1][i].HP -= self.damage
                    print(str(self.damage) + " damage")
            elif self.direction == "E":
                for i in range(0, len(Map.Grid[self.internal_column+1][self.internal_row])):
                    if Map.Grid[self.internal_column+1][self.internal_row][i].__class__.__name__ == "Character":
                        Map.Grid[self.internal_column+1][self.internal_row][i].HP -= self.damage
                        print(str(self.damage) + " damage")
            elif self.direction == "W":
                for i in range(0, len(Map.Grid[self.internal_column-1][self.internal_row])):
                    if Map.Grid[self.internal_column-1][self.internal_row][i].__class__.__name__ == "Character":
                        Map.Grid[self.internal_column-1][self.internal_row][i].HP -= self.damage
                        print(str(self.damage) + " damage")
            elif self.direction == "S":
                for i in range(0, len(Map.Grid[self.internal_column][self.internal_row+1])):
                    if Map.Grid[self.internal_column][self.internal_row+1][i].__class__.__name__ == "Character":
                        Map.Grid[self.internal_column][self.internal_row+1][i].HP -= self.damage
                        print(str(self.damage) + " damage")

            self.moves_left = self.moves_left - 1

    def ranged_attack(self, direction):
            if self.direction == "S":
                for k in range(1, (MAPSIZE - self.internal_row)):
                    for i in range(0, len(Map.Grid[self.internal_column][self.internal_row + k])):
                        if Map.Grid[self.internal_column][self.internal_row + k][i].__class__.__name__ == "Character":
                            Map.Grid[self.internal_column][self.internal_row + k][i].HP -= self.damage
                            print(str(self.damage) + " damage")
                            self.moves_left = self.moves_left - 1 
            if self.direction == "N":
                for k in range(1, self.internal_row):
                    for i in range(0, len(Map.Grid[self.internal_column][self.internal_row - k])):
                        if Map.Grid[self.internal_column][self.internal_row - k][i].__class__.__name__ == "Character":
                            Map.Grid[self.internal_column][self.internal_row - k][i].HP -= self.damage
                            print(str(self.damage) + " damage")
                            self.moves_left = self.moves_left - 1
            if self.direction == "W":
                for k in range(1, self.internal_column):
                    for i in range(0, len(Map.Grid[self.internal_column - k][self.internal_row])):
                        if Map.Grid[self.internal_column - k][self.internal_row][i].__class__.__name__ == "Character":
                            Map.Grid[self.internal_column - k][self.internal_row][i].HP -= self.damage
                            print(str(self.damage) + " damage")
                            self.moves_left = self.moves_left - 1
            if self.direction == "E":
                for k in range(1, (MAPSIZE - self.internal_column)):
                    for i in range(0, len(Map.Grid[self.internal_column + k][self.internal_row])):
                        if Map.Grid[self.internal_column + k][self.internal_row][i].__class__.__name__ == "Character":
                            Map.Grid[self.internal_column + k][self.internal_row][i].HP -= self.damage
                            print(str(self.damage) + " damage")
                            self.moves_left = self.moves_left - 1
            else:
                return 


class Goblin(Character):
    def __init__(self):
        Character.__init__(self, "Goblin", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1), 10, random.randint(0,1))

    def random_move(self):
        i = random.randint(0,3)
        if i == 0:
            self.move("N")
        elif i == 1:
            self.move("S")
        elif i == 2:
            self.move("W")
        elif i == 3:
            self.move("E")

        self.moves_left = 10


class Archer(Character):
    def __init__(self):
        Character.__init__(self, "Archer", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Warrior(Character):
    def __init__(self):
        Character.__init__(self, "Warrior", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Scout(Character):
    def __init__(self):
        Character.__init__(self, "Scout", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Rogue(Character):
    def __init__(self):
        Character.__init__(self, "Rogue", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Wizard(Character):
    def __init__(self):
        Character.__init__(self, "Wizard", random.randint(15,20), random.randint(0,MAPSIZE-1), random.randint(0,MAPSIZE-1))


class Map(object):              #The main class; where the action happens
    global MAPSIZE
    wild_characters = []
    can_move = []
    no_moves = []
    Grid = []
    friendlies = []
    enemies = []
    everyone = [friendlies + enemies]
    visible = []

    for row in range(MAPSIZE):     # Creating grid
        Grid.append([])
        for column in range(MAPSIZE):
            Grid[row].append([])

    for row in range(MAPSIZE):     #Filling grid with grass
        for column in range(MAPSIZE):
            TempTile = MapTile("Grass", column, row, False)
            Grid[column][row].append(TempTile)

    for row in range(MAPSIZE):     #Putting some rocks near the top
        for column in range(MAPSIZE):
            TempTile = MapTile("Rock", column, row, False)
            if row == 1:
                Grid[column][row].append(TempTile)

    for i in range(10):         #Trees in random places
        random_row = random.randint(0, MAPSIZE - 1)
        random_column = random.randint(0, MAPSIZE - 1)
        TempTile = MapTile("Tree", random_column, random_row, False)
        Grid[random_column][random_row].append(TempTile)

    def generate_hero(self):            #Generate a character and place it randomly
        temp_hero = Character("Hero", 30, random.randint(0, MAPSIZE - 1), random.randint(0, MAPSIZE - 1) , 10, random.randint(0,1))
        self.Grid[temp_hero.internal_column][temp_hero.internal_row].append(temp_hero)
        self.can_move.append(temp_hero)
        if temp_hero.allegiance == 0:
            self.friendlies.append(temp_hero)
        elif temp_hero.allegiance == 1:
            self.enemies.append(temp_hero)

    def return_distance(self, pointA, pointB):
        distance = math.sqrt((pointA.internal_column - pointB.internal_column)**2 + (pointA.internal_row - pointB.internal_row)**2)
        return distance

    def generate_goblin(self):            #Generate a character and place it randomly
        random_row = random.randint(0, MAPSIZE - 1)
        random_column = random.randint(0, MAPSIZE - 1)
        temp_goblin = Goblin()
        self.Grid[random_column][random_row].append(temp_goblin)
        Map.wild_characters.append(temp_goblin)

    def update(self):           
        for column in range(MAPSIZE):                           #These nested loops go through entire grid 
            for row in range(MAPSIZE):                          #They check if any objects internal coordinates
                for i in range(len(Map.Grid[column][row])):     #disagree with its place on the grid and update it accordingly                            
                    if Map.Grid[column][row][i].internal_column != column:
                        TempChar = Map.Grid[column][row][i]
                        Map.Grid[column][row].remove(Map.Grid[column][row][i])
                        Map.Grid[int(TempChar.internal_column)][int(TempChar.internal_row)].append(TempChar)

                    elif Map.Grid[column][row][i].internal_row != row:
                        TempChar = Map.Grid[column][row][i]
                        Map.Grid[column][row].remove(Map.Grid[column][row][i])
                        Map.Grid[int(TempChar.internal_column)][int(TempChar.internal_row)].append(TempChar)

        temparr = Map.no_moves[:]
        for characterobject in temparr:    #This moves any characters with moves to the can move list 
            if len(temparr) > 0:
                if characterobject.moves_left > 0:
                    Map.can_move.append(characterobject)
                    Map.no_moves.remove(characterobject)
            if characterobject.HP <= 0:
                Map.no_moves.remove(characterobject)

        arr = Map.can_move[:] # copy
        for item in arr:
            if item.moves_left == 0:
                Map.can_move.remove(item)
                Map.no_moves.append(item)
            if item.HP <= 0:
                Map.can_move.remove(item)

        for column in range(MAPSIZE):                           
            for row in range(MAPSIZE):                          
                for i in range(len(Map.Grid[column][row])):     
                    if Map.Grid[column][row][i].__class__.__name__ == "Character":
                        if Map.Grid[column][row][i].HP <= 0:
                            Map.Grid[column][row].remove(Map.Grid[column][row][i])
                            print("Character died")

        for column in range(MAPSIZE):
            for row in range(MAPSIZE):
                for i in range(len(Map.Grid[column][row])):
                    if Map.Grid[column][row][i].__class__.__name__ == "Character":
                        Map.everyone.append(Map.Grid[column][row][i])

        for character in Map.everyone:            
            for column in range(MAPSIZE):
                for row in range(MAPSIZE):
                    if Map.return_distance(Map.Grid[column][row][0], character ) <= 15:
                        Map.Grid[column][row].visible = True

    def listofcharacters(self):
        for column in range(MAPSIZE):
            for row in range(MAPSIZE):
                for i in range(len(Map.Grid[column][row])):
                    if Map.Grid[column][row][i].__class__.__name__ == "Character":
                        print("Column: ", Map.Grid[column][row][i].internal_column, ", Row: ", Map.Grid[column][row][i].internal_row, ", Allegiance: ", Map.Grid[column][row][i].allegiance)





Map = Map()
Map.generate_hero()

while not DONE:     #Main pygame loop
    for event in pygame.event.get():         #catching events
        if event.type == pygame.QUIT:
            DONE = True       
        elif event.type == pygame.MOUSEBUTTONDOWN:
            Pos = pygame.mouse.get_pos()
            column = Pos[0] // (TILEWIDTH + TILEMARGIN)  #Translating the position of the mouse into rows and columns
            row = Pos[1] // (TILEHEIGHT + TILEMARGIN)
            print(str(row) + ", " + str(column))

            for i in range(len(Map.Grid[column][row])):
                print(str(Map.Grid[column][row][i].name))  #print stuff that inhabits that square

        elif event.type == pygame.KEYDOWN:
            wild_char_arr = Map.wild_characters[:]

            for wildcharacter in wild_char_arr:
                if wildcharacter.name == "Goblin":
                    wildcharacter.random_move() 

            if event.key == 97:      # Keypress: a
                print("New turn.")
                temparr = Map.no_moves[:]
                for item in temparr:
                    if item.moves_left == 0:
                        item.moves_left = 15
                TURN = TURN + 1
                print("Turn: ", TURN)

            elif event.key == 115:    # Keypress: s
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 113:    # Keypress: q     
                print("ranged attack")
                Map.can_move[0].ranged_attack(Map.can_move[0].direction)

            elif event.key == 119:    # Keypress: w
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 101:    # Keypress: e
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 114:    # Keypress: r
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 116:    # Keypress: t
                print("Generated hero.")
                Map.generate_hero()

            elif event.key == 100:  # Keypress: d
                Map.generate_goblin()
                print("Generated goblin.")

            elif event.key == 102:  # Keypress: f
                Map.can_move[0].attack(Map.can_move[0].direction) 

            elif len(Map.can_move) > 0:
                Map.can_move[0].move(KeyLookup[event.key])

            else:
                print("invalid")

            Map.update()

    Screen.fill(BLACK)

    for row in range(MAPSIZE):           # Drawing grid
        for column in range(MAPSIZE):
            for i in range(0, len(Map.Grid[column][row])):
                Color = WHITE

                if len(Map.can_move) > 0:   # Creating colored area around character showing his move range
                    if (math.sqrt((Map.can_move[0].internal_column - column)**2 + (Map.can_move[0].internal_row - row)**2)) <= Map.can_move[0].moves_left:
                        Color = MOVECOLOR

                if len(Map.Grid[column][row]) > 1:
                    Color = RED
                if Map.Grid[column][row][i].name == "Tree":

                    Color = GREEN
                if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                    Color = BROWN

            pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN,
                                             TILEWIDTH,
                                             TILEHEIGHT])

            if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                if Map.Grid[column][row][i].direction == "N":
                    Color = RED

                    pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN + 8,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN,
                                             TILEWIDTH/4,
                                             TILEHEIGHT/4])

            if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                if Map.Grid[column][row][i].direction == "S":
                    Color = RED

                    pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN + 8,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN*5 - 1 ,
                                             TILEWIDTH/4,
                                             TILEHEIGHT/4])

            if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                if Map.Grid[column][row][i].direction == "E":
                    Color = RED

                    pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN + 15,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN*5 - 8,
                                             TILEWIDTH/4,
                                             TILEHEIGHT/4])

            if str(Map.Grid[column][row][i].__class__.__name__) == "Character":
                if Map.Grid[column][row][i].direction == "W":
                    Color = RED

                    pygame.draw.rect(Screen, Color, [(TILEMARGIN + TILEWIDTH) * column + TILEMARGIN
                                                     ,
                                             (TILEMARGIN + TILEHEIGHT) * row + TILEMARGIN*5 - 8 ,
                                             TILEWIDTH/4,
                                             TILEHEIGHT/4])


    Clock.tick(60)      
    pygame.display.flip()     

pygame.quit()
friendlies = []
enemies = []
everyone = [friendlies + enemies]
for character in Map.everyone:
for row in range(MAPSIZE):     # Creating grid
    Grid.append([])

for row in range(MAPSIZE):     #Filling grid with grass
    for column in range(MAPSIZE):
        TempTile = MapTile("Grass", column, row, False)
        Grid[row].append(TempTile)