[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Simple board game GUI framework

On 9/11/2017 12:56 PM, Paul Moore wrote:

> I'm not looking at actually implementing chess. The idea was prompted
> by a programming exercise my son was given, that was about programming
> a series of classes modelling robots that know their position on a
> grid, and when told to move, can do so according to certain rules. One
> moves in a straight line till it hits the edge, one moves in a random
> direction, some bounce when they hit an obstacle and some just stop,
> etc. The idea is to demonstrate classes and inheritance to model
> common behaviours and objects holding state that the behaviour acts
> on.
> The original exercise (which used Java) just had the program print out
> the objects' co-ordinates at each step. I thought that visualising the
> results by actually showing the objects moving would be better. (And a
> quick discussion/demo with the guy I'm training showed me I'm right -
> his reaction was "wow, that looks really impressive" :-))

Once you have a tkinter board, it is pretty easy to add an animated 
'sprite'.  The key is understanding root.after loops.  This example has 
multiple animated warp-around robots, moving at different speeds and 
different movement patterns.

import random
import tkinter as tk

def create_board(root):
     board = {}
     for r in range(8):
         for c in range(8):
             lbl = tk.Button(bg="white", text="   ", font=("Consolas", 12))
             lbl.grid(row=r, column=c)
             board[c,r] = lbl
     return board

class Robot():
     def __init__(self, color, x, y, dt, strategy):
         self.color = color
         self.x = x
         self.y = y
         self.dt = dt
         self.strategy = strategy
         board[x, y]['bg'] = color
         root.after(dt, self.move)
     def move(self):
         dx, dy = self.strategy()
         if dx or dy:
             x, y = self.x, self.y
             board[x, y]['bg'] = 'white'
             x, y = (x+dx) % 8, (y+dy) % 8
             board[x, y]['bg'] = self.color
             self.x, self.y = x, y
         root.after(self.dt, self.move)

def ranmove():
     return random.choice((-1, 0, 1)), random.choice((-1, 0, 1))

def upperleft():
     return -1, -1

def lowerright():
     return 1, 1

root = tk.Tk()
board = create_board(root)
yellow = Robot('yellow', 1, 1, 50, ranmove)
red = Robot('red', 3, 5, 100, ranmove)
blue = Robot('blue', 5, 3, 150, ranmove)
green = Robot('green', 2, 7, 300, lowerright)
black= Robot('black', 7, 1, 350, upperleft)

#root.mainloop()  # Uncomment if not run from IDLE editor.

If one want a time resolution finer than 50 milliseconds, then one would 
need to active mainloop even in IDLE.

Terry Jan Reedy