Python chess project. Any GUI coding recommendations?

Hi
I found this page of 60x60 chess images to use in my uncontestedly invulnerable ;) Python AI development

here

Instead of  trial and error myself, is there an example page with code for a Python Frame of image load, drag and drop? w listeners? like in chess apps? I have pygame ready.
I can see the functions on pygame.org, but I'd love to see it mostly in one screen.

Thanks
LVL 1
beavoidAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gelonidaCommented:
Well nobody replied so far:

Well I never used pygame so I can't help a lot.

First imagine how you want to implement your user interface.
There's many options. Some more elegant, some less elegant, some easier to implement some more difficult.

I suggest here a rather simple one without animation. Lateron you can add animation.

For example you decide, that in order to move a chess piece you:
- have to move your mouse on the chess piece, that you want to move
- you press the button down
    - if you clicked on a field without one of your chess pieces, then nothing will happen)
- then you move the mouse to the target position
- and click again
    - if the target position is empty but invalid,then nothing will happen and you wait for a click on a
      correct target field
    - if you click again on the same position as your start position, then you will 'cancel' the move
    - if the target position is valid, you move the piece to this position.


I'll send you a very simple code snippet lateron.
1
gelonidaCommented:
Ok here my very simple working pygame example.
Please note, that I never used pygame before, so perhaps some things are less elegant than they could be.

Note as well, that Game.run is getting quite long.
I wrote everything in one method, but you should refactor this. Especially if you want to add animation lateron.

First part is just some imports and constant declarations:
#!/usr/bin/env python


import pygame


FIELD_WIDTH = 60 # 60 pixel per field
BOARD_WIDTH = FIELD_WIDTH * 8  # width of board

BOARD_F  = "board.png"
FIGURE_F = "Chess_%s%st60.png"

Open in new window



You need a file containing the image of the board "board.png" and one file for each different figure.
for this demo you just need the files "Chess_kdt60.png"  and "Chess_klt60.png"
I adapted to the naming style of the link you referenced.

Next part declares a class which is a stub for your gaming engine with its chessboard.
class Board:
    """ a fake class for a chess board """
    def __init__(self):
        self.fields = [  [" "]* 8 for i in range(8)]
        self.fields[7][5] = "k"
        self.fields[5][4] = "K"

    def figure_on_field(self, field):
        """ fake functionidication whether field contains a figure, that
            I'm allowed to move
        """
        x, y = field
        return self.fields[y][x] != " "

    def is_valid_move(self, field_from, field_to):
        """ fake function to see if moveis valid
            - field_from must contain a figure
            - field_to must be a neighbour field
        """
        x1, y1 = field_from
        x2, y2 = field_to
        if self.fields[y1][x1] == " ":
            return False  # not empty 
        if field_from == field_to:
            return False
        delta_x = abs(x2-x1)
        if delta_x > 1:
            return False
        delta_y = abs(y2-y1)
        if delta_y > 1:
            return False
        return True

    def move(self, field_from, field_to):
        fields = self.fields
        x1, y1 = field_from
        x2, y2 = field_to
        to_move = fields[y1][x1]
        fields[y1][x1] = " "
        fields[y2][x2] = to_move
    def print(self):
        """ Just for debugging 
            It allows you to see whether
            your non graphical game stays in sync with 
            the bygame board
        """
        print("+-" * 8 + "+")
        for row in self.fields:
            print("|" + "|".join(row) + "|")
            print("+-" * 8 + "+")

Open in new window


I implemented functions to:
- move a figure from one place to another
- to tell me whether the I can move a figure on a certain position on the board
- to tell me whether I can move a figure from one position to another
- a function for debugging, that prints the chess board on the console.

Next part implements the pygame code:
If you press 'q' you willquit the game.
with clicking you can select and move a figure:


class Game:
    def __init__(self):
        """ load images for chess board and chess figures """
        self.board = Board()
        self.background = pygame.image.load(BOARD_F)
        self.figures = {}
        self.screen = None
        self.clock = None

        fields = self.board.fields
        for x in range(8):
            for y in range(8):
                fieldval = fields[y][x]
                if fieldval != " ":
                    color = "l" if fieldval.lower() == fieldval else "d"
                    print("loading %s for %d,%d" % (fieldval, x, y))
                    figure = pygame.image.load(FIGURE_F % (fieldval.lower(), color))
                    self.figures[(x,y)] = figure

    def init_pygame(self):
        """ just initialize the screen and draw it a first time """
        print("init game")
        pygame.init()
        pygame.display.set_caption("My Game")
        pygame.mouse.set_visible(1)
        self.clock = pygame.time.Clock()
        pygame.key.set_repeat(1, 30)
        # load figures (I just load one here)
        self.screen = screen = pygame.display.set_mode((BOARD_WIDTH, BOARD_WIDTH))
        print("created screen", screen)
        self.running = True
        self.draw()

    def draw(self):
        self.screen.blit(self.background, (0, 0))
        for position, figure in self.figures.items():
            x, y = position
            x *= FIELD_WIDTH
            y *= FIELD_WIDTH
            self.screen.blit(figure, (x, y))

        pygame.display.flip()
        self.board.print() # just for debugging

    def run(self):
        self.init_pygame()
        clock = self.clock
        changes = False
        field_from = None 
        board = self.board
        figures = self.figures
        while self.running:
            if changes:
                print("redraw")
                self.draw()
                changes = False
            clock.tick(30)
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        x, y = event.pos
                        x //= FIELD_WIDTH
                        y //= FIELD_WIDTH 
                        print("X", x, "Y", y)
                        field = (x, y)
                        if field_from is None:
                            # We just clicked on what we want to move
                            if board.figure_on_field(field):
                                print("clicked on a figure", field)
                                field_from = field
                            else:
                                print("clicked on empty field")
                        elif field == field_from:
                            # we clicked again on the same field.
                            # we cancelled
                            print("unselected figure", field_from) 
                            field_from = None
                        else:
                            if board.is_valid_move(field_from, field):
                                print("move figure from %s to %s" % (field_from, field))
                                board.move(field_from, field)
                                figure = figures.pop(field_from)
                                figures[field] = figure
                                print(sorted(figures.keys()))
                                self.draw()
                                field_from = None
                                
                elif event.type == pygame.KEYDOWN:
                    if event.unicode == 'q':
                        self.running = False

Open in new window



The last parts just starts the game:
if __name__ == "__main__":
    game = Game()
    game.run()

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
beavoidAuthor Commented:
Thanks!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Game Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.