Home > Enterprise >  Why aren't the images of the first two instances of WhitePawn() displayed?
Why aren't the images of the first two instances of WhitePawn() displayed?

Time:11-19

Here's my Code:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image
from kivy.uix.relativelayout import RelativeLayout


class WhitePawn():
    def __init__(self):
        self.source='whitepawn.png'
        
class CubeWidget(RelativeLayout):
    def __init__(self,color,id,piece,**kwargs):
        self.color=color
        self.id=id
        self.piece=piece
        super().__init__(**kwargs)
        if self.piece:
            self.img=Image(source='whitepawn.png')
            self.add_widget(self.img)
    def on_touch_down(self, touch):
        if self.collide_point(touch.x,touch.y):
            print(self.id,self.pos)
            return True
        return super().on_touch_down(touch)    
class New_Board(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.board=[]
        self.theme=None
        self.gen_board()
    def gen_board(self):
        a=[(WhitePawn(),1,1),(WhitePawn(),2,2),(WhitePawn(),3,3)]
        for i in range(8):
            for j in range(8):
                color=(0,1,0,1) if (i j)%2!=0 else (1,1,1,1)
                for k in a:
                    if (k[1],k[2])==(i,j):
                        cube=CubeWidget(color,(i,j),k[0])
                        self.board.append((k[0],cube))
                    else:
                        cube=CubeWidget(color,(0,0),None)
                self.add_widget(cube)
class MyChessApp(App):
    def build(self):
        board=New_Board()
        return board
           
MyChessApp().run()

only the last whitepawn instance is displaying the image none other.

CodePudding user response:

Your approach is flawed. Your for k in a: loop is printing every square of the board thrice.

Here is a short reproduceable example of what you are currently doing.

a = [(1, 1), (2, 2), (3, 3)]

for i in range(8):
    for j in range(8):
        for k in a:
            if (k[0], k[1]) == (i, j):
                print((i, j), 'printed piece')
            else:
                print((i, j), 'printed blank')

For the position (1, 1) you will see:

(1, 1) printed piece
(1, 1) printed blank
(1, 1) printed blank

As you see, (3, 3) is the only one where the piece is in final position it checks. That is why it's the one that survives.

(3, 3) printed blank
(3, 3) printed blank
(3, 3) printed piece

A simple fix would be to utilize the else in your final for loop to print the blank position if the for loop didn't yield any results for pieces.

a = [(1, 1), (2, 2), (3, 3)]

for i in range(8):
    for j in range(8):
        for k in a:
            if (k[0], k[1]) == (i, j):
                print((i, j), 'printed piece')
                break
        else:
            print((i, j), 'printed blank')

However, some people shy away from the else on for loops since it's a less utilized portion of the language.

If you want something that works without using the else, this should work.

a = [(1, 1), (2, 2), (3, 3)]

for i in range(8):
    for j in range(8):
        piece = None
        for k in a:
            if (k[0], k[1]) == (i, j):
                piece = k
        if piece is not None:
            print((piece[0], piece[1]), 'printed piece')
        else:
            print((i, j), 'printed blank')
  • Related