国际象棋决赛:国王和白嘴鸦vs国王在蟒蛇

我在Python中使用这个简单的国际象棋代码时遇到了一些问题。 它是每周任务的一部分; 这是我到目前为止:

from math import sqrt
from random import randint,shuffle,seed
def rand_pos():
    return [randint(0,7),randint(0,7)]

#first, classes defining the kings and the rook; 
#their only attribute is a randomly generated position on the chessboard. 
#Each of them has its special print method that will be used in the Chessboard (Scacchiera) class.
class W_king:
    def __init__(self,coord=rand_pos()):
        self.coord=coord
        self.x=coord[1]
        self.y=coord[0]
    def __repr__(self):
        return "R"
class B_king:
    def __init__(self,coord=rand_pos()):
        self.coord=coord
        self.x=coord[1]
        self.y=coord[0]
    def __repr__(self):
        return "r"
class Rook:
    def __init__(self,coord=rand_pos()):
        self.coord=coord
        self.x=coord[1]
        self.y=coord[0]
    def __repr__(self):
        return "T"

#the following will be used to calculate the distance between the kings and between a king and the rook; 
#I'll use it in the while statements later in the Scacchiera class to check if the kings are generated too near or stuff
def distance(n1,n2):
    return sqrt(sum((n1.coord[i]-n2.coord[i])**2 for i in [0,1]))

class Scacchiera:
    def __init__(self,w_king=W_king(),b_king=B_king(),rook=Rook(),boxes=[[" " for y in range(8)] for x in range(8)]):
        self.w_king=w_king
        self.b_king=b_king
        self.rook=rook
        self.boxes=boxes
        #here it is: while the two kings are generated too near, 
        #get the black king new coordinates
        while distance(self.b_king,self.w_king)<2:
            self.b_king.coord=[randint(0,7),randint(0,7)]
        #...and, while the white king (or the black king) and the rook have the same coordinates 
        #or the black king is in the rook's sight, 
        #get a new pair of coordinates for the rook:
        while self.w_king.coord==self.rook.coord or self.b_king.coord==self.rook.coord or self.rook.x==self.b_king.x or self.rook.y==self.b_king.y:
            self.rook.coord=[randint(0,7),randint(0,7)]
        print distance(self.b_king,self.w_king) #to check, just for me
        #the function conv switches to the chessboard's coordinates e.g. e4, h5, etc
        print conv(self.w_king.coord),conv(self.b_king.coord),conv(self.rook.coord)
    def __repr__(self):
        #self.boxes is an array of blank spaces " ",
        #and in the right place the kings and the rook are placed
        scacchiera=self.boxes[:]
        scacchiera[self.w_king.x][self.w_king.y]=self.w_king
        scacchiera[self.b_king.x][self.b_king.y]=self.b_king
        scacchiera[self.rook.x][self.rook.y]=self.rook
        return "n".join([str(8-i)+" "+" ".join(str(scacchiera[i][j]) for j in range(8)) for i in range(8)])+"n  "+" ".join([chr(97+k) for k in range(8)])
    def check(self,king):
        #no need for this for now
        return self.rook.x==king.x or self.rook.y==king.y
    def black_legal_moves(self,mossa):
        future_king=B_king([self.b_king.y+mossa[0],self.b_king.x+mossa[1]])
        if distance(self.w_king,future_king)<2 or self.check(future_king):
            return False
        else:
            return True

    def new_mossa_random(self):
        #this method chooses randomly a new position for the black king from the list of adjacent cells 
        #and tests if it's legal with the method above. If it's not, it deletes it from the list and re-tries 
        moves_list=[[self.b_king.y+hor,self.b_king.x+ver] for ver in [-1,0,1] for hor in [-1,0,1] if not hor==ver==0]
        shuffle(moves_list)
        move=moves_list[0]
        #while it's not legal or the coordinates are out of the board:
        while not self.black_legal_moves(move) or not 0<=move[0]<=7 or not 0<=move[1]<=7:
            del moves_list[0]
            if not moves_list:
                return None
            move=moves_list[0]
        return move
def conv(coord):
    return [chr(coord[0]+97),8-coord[1]]

#you just need to run it:
seed()
scacchiera=Scacchiera()
print scacchiera
print conv(scacchiera.new_mossa_random())

问题有两个:

  • 我的代码虽然不完整,但在棋盘生成部分对我来说似乎是正确的。 然而,经常(近十分之三)国王彼此相邻,或者一个国王和一个国王被放置在另一个之上,或者黑王的随机行动甚至不在他的箱子附近。
  • 很多时候,代码一直在运行,不会打印任何棋盘; 好像它贴在两个while在Scacchiera年初秒。
  • 注意 :F5脚本将在PC上打印,顺序如下:

  • 两位国王之间的距离,

  • 棋盘上的坐标:白色国王,黑色国王,然后是白嘴鸦

  • 棋盘上的棋子

  • 一个新的黑色国王随机移动的坐标。

  • 让我知道我是否应该添加其他信息。


    如果发生碰撞,你正在改变棋子上的coord成员。 但仓位也存储在xy ,这些未更新。

    我建议你只保留xy或只coord在你的类。 如果你想变得有趣,你可以通过使用@property来保持coord并将x和y转换成属性。


    您的问题很可能源于错误使用默认参数。

    简短的回答,这样做:

    def __init__(self, coord=None):
        coord = coord or rand_pos()
    

    说明:Python缺省参数的常见问题


    感谢您的帮助! 最后,我去除了国王和白嘴鸦的班级。 他们毫无意义,我只需要一本字典,就像这里的代码一样。

    这是我经历的解决方案

    from random import randint,shuffle,choice
    
    
    def rand_pos():
        return [randint(0,7),randint(0,7)]
    
    def dist(n1,n2):
        return (sum([(n1[i]-n2[i])**2 for i in [0,1]]))**(0.5)
    def invconv(coord):
        return [ord(coord[0])-97,8-coord[1]]
    #the core of the game is here; Scacchiera means Checkboard, and it basically generates coordinates
    #for the kings and the rook while they are in illegal positions.
    #then there's a bunch of methods to determine wether a move is legal or not
    #and, just for black, a random move is chosen.
    #finally, all the stuff is gathered in the Partita (=Game) function.
    class Scacchiera:
    def __init__(self,w_king=rand_pos(),b_king=rand_pos(),rook=rand_pos()):
        self.w_king=w_king
        self.b_king=b_king
        self.rook=rook
            while dist(self.b_king,self.w_king)<=1.5:
                self.b_king=rand_pos()
            while self.w_king==self.rook or self.b_king==self.rook or self.rook[0]==self.b_king[0] or self.rook[1]==self.b_king[1]:
                self.rook=rand_pos()
            self.pezzi={"R":self.w_king,"r":self.b_king,"T":self.rook}
            self.mosse=[self.pezzi[item] for item in ["r","R","T"]]
        def __repr__(self):
            griglia=[["." for j in range(8)] for i in range(8)]
            for item in self.pezzi:
                griglia[self.pezzi[item][0]][self.pezzi[item][1]]=item
            return "n".join([str(8-j)+" "+" ".join(str(griglia[i][j]) for i in range(8)) for j in range(8)])+"n  "+" ".join([chr(97+k) for k in range(8)])
    
        def move(self,pezzo,end):
            if not end:
                return
            end=[end[0]-self.pezzi[pezzo][0],end[1]-self.pezzi[pezzo][1]]
            self.pezzi[pezzo][0]+=end[0]
            self.pezzi[pezzo][1]+=end[1]
            if self.pezzi["r"]==self.pezzi["T"]:
                del self.pezzi["T"]
            self.mosse.append(self.pezzi.values())
            return
        def check(self):
            return self.pezzi["T"][0]==self.pezzi["r"][0] or self.pezzi["T"][1]==self.pezzi["r"][1]
    
        def black_legal_move(self,end):
            kings_dist=dist(self.pezzi["R"],end)
            rook_king_dist=dist(self.pezzi["T"],self.pezzi["R"])
            if  kings_dist<=1.5:
                return False
            elif self.pezzi["T"]==end and rook_king_dist>1.5:
                return True
            elif self.pezzi["T"][0]==end[0] or self.pezzi["T"][1]==end[1] or end[0] not in range(8) or end[1] not in range(8):
                return False
            return True
    
        def mosse_legali_b(self):
            moves_list=[[self.pezzi["r"][0]+hor,self.pezzi["r"][1]+ver] for ver in [-1,0,1] for hor in [-1,0,1] if not hor==ver==0]
            shuffle(moves_list)
            elle=[]
            for i in range(len(moves_list)):
                if self.black_legal_move(moves_list[i]):
                    elle.append(moves_list[i])
            if not elle:
                return None
            return elle
    
        def mossa_random_black(self):
            print "Tocca al nero.n"
            end=choice(self.mosse_legali_b())
            if not end:
                return None
            self.move("r",end)
            print self
            return
    
        def scacco_matto(self):
            return self.check() and self.mosse_legali_b()==None
        def stallo(self):
            return self.mosse_legali_b()==None
        def ripetizione(self):
            return 3 in [self.mosse.count(item) for item in self.mosse]
    
        def white_king_lmove(self,beg,end):
            return dist(beg,end)<=1.5 and dist(self.pezzi["r"],end)>1.5 and beg!=end
        def white_rook_lmove(self,beg,end):
            return (beg[0]==end[0] or beg[1]==end[1]) and beg!=end
        def white_legal_move(self,beg,end):
            if self.pezzi["R"]==beg:
                return self.white_king_lmove(beg,end)
            else:
                return self.white_rook_lmove(beg,end)
    
        def mossa_white(self):
            print "n**Tocca al bianco**"
            mossa=raw_input("Inserisci la prossima mossa:n")
            beg=invconv([mossa[0],int(mossa[1])])
            end=invconv([mossa[2],int(mossa[3])])
            if not self.white_legal_move(beg,end):
                print "nMossa non valida."
                return self.mossa_white()
            if self.pezzi["R"]==beg:
                pezzo="R"
            elif self.pezzi["T"]==beg:
                pezzo="T"
            self.move(pezzo,end)
            if self.check():
                print "Scacco!n",self
            else:
                print self      
            return 
    
    链接地址: http://www.djcxy.com/p/84669.html

    上一篇: Chess final: king and rook vs king in python

    下一篇: Get enemy's possible moves in chess to a 2D array