#!/usr/bin/env python # coding: utf-8 """ Connect4 client plugin for chatwisted that adds a game grid with some more functionallity to the standard tkPluginClient """ import Tkinter as tk from chatwisted.tk_gui import TkPluginClient class TkConnect4Field(tk.Canvas): """ A Canvas that draws a Connect4 game grid """ colors = {"X":"blue", "O":"red", "_":"white"} bg = "gray" def __init__(self, master, width, height, put_func, highlight_key = "X"): """ Define and set some attributes """ tk.Canvas.__init__(self, master, width=width, height=height, bg=self.bg) self.highlight_color = self.colors[highlight_key] self.put_func = put_func def draw_field(self, rows): """ redraw the whole filed """ self.delete("ALL") # self.tag_unbind("ALL", "") col_width = int(self["width"])/len(rows[0]) row_height = int(self["height"])/len(rows) bound = False for row, items in enumerate(rows): for col, item in enumerate(items): left, top = col * col_width, row * row_height right, bottom = left + col_width, top + row_height color = self.colors[item] oval = self.create_oval(left, top, right, bottom, fill=color) if not bound: self.tag_bind(oval, "", lambda e, oval=oval: self.highlight(oval)) self.tag_bind(oval, "", lambda e, oval=oval, key=item: self.set_normal(oval, key)) self.tag_bind(oval, "<1>", lambda e, key=col: self.put_func(key)) bound = True def highlight(self, chip): """ highlight a chip :type chip: TagOrID """ self.itemconfig(chip, fill="black")#self.highlight_color) def set_normal(self, chip, item): """ un-highlight a chip :tpye chip: TagOrID :param item: Item to represent with the chip (to get the color) :type item: string """ self.itemconfig(chip, fill=self.colors[item]) class TkConnect4Client(TkPluginClient): """ A simple connect4 game client with Tkinter :todo: write and inherit as well from a gui independent Connect4Client class """ name = "connect4" def __init__(self, master, facotry, name): """ Pack a TkConnect4Field on the predefined main_frame and add a Button to start the game """ TkPluginClient.__init__(self, master, facotry, name) self.game_frame = tk.Frame(self) self.field = TkConnect4Field(self.main_frame, 200, 200, self.put) self.field.pack() self.start_but = tk.Button(self.main_frame, text="start", command=lambda:self.send_cmd("start", "")) self.start_but.pack() def cmd_field(self, field): """ Update the game grid """ lines = [line for line in field.replace("|", "").split("-") if line.strip()] self.field.draw_field(lines) def put(self, col): """ Put a chip into column col """ self.send_cmd("put", col)