import tkinter
from tkinter import filedialog
import os
import math
class Terrain :
def __init__ ( self ) :
self . height = 15000 / / 25
self . width = 28000 / / 25
self . three_points = 6250 / / 25 # rayon
self . middle_circle = 1800 / / 25 # rayon
class Team :
def __init__ ( self , players ) :
self . players = players
self . posx , self . posy = 0 , 0 # coo de la dernière action
self . ac_player = 0 # dernier joueur
class File :
def __init__ ( self , name = ' untitled.bbm ' ) :
self . name = name
self . temp_data = ' '
self . content = [ ]
def write_data ( self ) :
with open ( self . name , ' a ' ) as f :
f . write ( self . temp_data )
self . temp_data = ' '
self . read_file ( )
def read_file ( self ) :
with open ( self . name , ' r ' ) as f :
self . content = f . readlines ( )
class Gui :
def __init__ ( self ) :
self . terrain = Terrain ( )
self . team = None
self . mode = None
self . root = tkinter . Tk ( )
self . root . title ( ' BasketBall Analitycs® ' )
self . canvas = tkinter . Canvas ( self . root , width = self . terrain . width , height = self . terrain . height , background = ' #bbb ' )
self . start_frame = tkinter . Frame ( self . root , width = self . terrain . width , height = self . terrain . height , bg = ' red ' )
self . start_button_new = tkinter . Button ( self . start_frame , text = ' new ' , command = self . new )
self . start_button_open = tkinter . Button ( self . start_frame , text = ' open ' , command = self . browse_open )
self . start_frame . pack ( )
self . start_button_new . place ( x = self . terrain . width / / 2 - 45 , y = self . terrain . height / / 2 - 30 , width = 90 , height = 30 )
self . start_button_open . place ( x = self . terrain . width / / 2 - 45 , y = self . terrain . height / / 2 , width = 90 , height = 30 )
# file menu
self . menubar = tkinter . Menu ( self . root )
self . filemenu = tkinter . Menu ( self . menubar , tearoff = 0 )
self . filemenu . add_command ( label = " new " , command = self . new )
self . filemenu . add_command ( label = " open " , command = self . browse_open )
self . filemenu . add_separator ( )
self . filemenu . add_command ( label = " exit " , command = self . root . quit )
self . menubar . add_cascade ( label = " file " , menu = self . filemenu )
self . action_to_show = [ ]
# topbar
self . root . config ( menu = self . menubar )
# image des actions
self . tir_reussi = tkinter . PhotoImage ( file = ' img/tir_reussi.png ' )
self . tir_rate = tkinter . PhotoImage ( file = ' img/tir_rate.png ' )
self . lance_reussi = tkinter . PhotoImage ( file = ' img/lance_reussi.png ' )
self . lance_rate = tkinter . PhotoImage ( file = ' img/lance_rate.png ' )
self . rebond_def = tkinter . PhotoImage ( file = ' img/rebond_def.png ' )
self . rebond_off = tkinter . PhotoImage ( file = ' img/rebond_off.png ' )
self . faute = tkinter . PhotoImage ( file = ' img/faute.png ' )
self . passe_dec = tkinter . PhotoImage ( file = ' img/passe_dec.png ' )
self . root . bind ( " <Control-o> " , self . browse_open )
self . root . bind ( " <Control-n> " , self . new )
self . root . bind ( " <Control-s> " , self . save )
self . canvas . bind ( " <Button-1> " , self . context_menu )
self . root . mainloop ( )
def get_names ( self ) :
self . team = Team ( self . players_entry . get ( ) . split ( ' , ' ) )
print ( self . team . players )
self . w_player . destroy ( )
self . w_player . quit ( )
def new ( self , * event ) :
# créer un fichier vierge
self . file = File ( )
self . root . title ( self . file . name )
self . w_player = tkinter . Toplevel ( )
frame = tkinter . Frame ( self . w_player , width = 600 , height = 200 )
self . players_entry = tkinter . Entry ( frame )
text = tkinter . Label ( frame , text = " Entrez les joueurs séparés par virgules " )
ok_button = tkinter . Button ( frame , text = ' OK ' , command = self . get_names )
frame . pack ( )
self . players_entry . place ( x = 200 , y = 80 , width = 200 , height = 20 )
text . place ( x = 150 , y = 40 , width = 300 , height = 40 )
ok_button . place ( x = 280 , y = 120 , width = 40 , height = 20 )
self . w_player . mainloop ( )
self . setup ( )
def save ( self , * event ) :
# sauvegarde du fichier
if self . menu != None :
if self . file . name == ' untitled.bbm ' :
path = tkinter . filedialog . asksaveasfilename ( initialdir = " ~ " , title = " Select a File " , filetypes = ( ( " BasketBall Match " , " *.bbm " ) , ( " all files " , " *.* " ) ) )
if len ( path ) != 0 :
self . file . name = path
self . file . write_data ( )
self . root . title ( self . file . name )
def browse_open ( self , * event ) :
# ouvre un fichier
path = tkinter . filedialog . askopenfilename ( initialdir = " ~/Documents/python/basket " , title = " Select a File " , filetypes = ( ( " BasketBall Match " , " *.bbm " ) , ( " all files " , " *.* " ) ) )
if len ( path ) != 0 :
self . file = File ( path )
self . file . read_file ( )
self . team = Team ( self . file . content [ 0 ] . strip ( ) . split ( ' ' ) )
self . root . title ( self . file . name )
self . setup ( )
def setup ( self ) :
self . start_frame . pack_forget ( )
self . canvas . pack ( )
self . mode = ' match '
self . draw_terrain ( )
self . filemenu . insert_command ( 2 , label = " save " , command = self . save )
# mode menu
self . modemenu = tkinter . Menu ( self . menubar , tearoff = 0 )
self . modemenu . add_command ( label = " stat " , command = lambda : self . changemode ( ' stat ' ) )
self . modemenu . add_command ( label = " match " , command = lambda : self . changemode ( ' match ' ) )
self . menubar . add_cascade ( label = " mode " , menu = self . modemenu )
# stat menu
self . statmenu = tkinter . Menu ( self . menubar , tearoff = 0 )
self . statsubmenu = tkinter . Menu ( self . statmenu , tearoff = 0 )
self . statsubmenu . add_command ( label = self . team . players [ 0 ] , command = lambda : self . draw_player ( self . team . players [ 0 ] ) )
self . statsubmenu . add_command ( label = self . team . players [ 1 ] , command = lambda : self . draw_player ( self . team . players [ 1 ] ) )
self . statsubmenu . add_command ( label = self . team . players [ 2 ] , command = lambda : self . draw_player ( self . team . players [ 2 ] ) )
self . statsubmenu . add_command ( label = self . team . players [ 3 ] , command = lambda : self . draw_player ( self . team . players [ 3 ] ) )
self . statsubmenu . add_command ( label = self . team . players [ 4 ] , command = lambda : self . draw_player ( self . team . players [ 4 ] ) )
self . statmenu . add_cascade ( label = " player " , menu = self . statsubmenu )
self . statmenu . add_command ( label = ' team ' , command = lambda : self . draw_player ( ' * ' ) )
# actions menubar
self . actionmenu = tkinter . Menu ( self . menubar , tearoff = 0 )
self . actionmenu . add_checkbutton ( 0 , label = ' tirs ' , command = lambda : self . check_action ( ' tirs ' ) )
self . actionmenu . add_checkbutton ( 0 , label = ' lance ' , command = lambda : self . check_action ( ' lance ' ) )
self . actionmenu . add_checkbutton ( 0 , label = ' rebonds ' , command = lambda : self . check_action ( ' rebond ' ) )
self . actionmenu . add_checkbutton ( 0 , label = ' passe ' , command = lambda : self . check_action ( ' passe ' ) )
self . actionmenu . add_checkbutton ( 0 , label = ' faute ' , command = lambda : self . check_action ( ' faute ' ) )
for i in range ( 5 ) :
self . actionmenu . invoke ( i )
# menu contextuel des actions
self . action = tkinter . Menu ( self . root , tearoff = 0 )
self . action . add_command ( label = ' tir réussi ' , command = lambda : self . action_menu ( ' tm ' ) )
self . action . add_command ( label = ' tir raté ' , command = lambda : self . action_menu ( ' tr ' ) )
self . action . add_command ( label = ' lancé franc réussi ' , command = lambda : self . action_menu ( ' lfm ' ) )
self . action . add_command ( label = ' lancé franc raté ' , command = lambda : self . action_menu ( ' lfr ' ) )
self . action . add_command ( label = ' faute ' , command = lambda : self . action_menu ( ' f ' ) )
self . action . add_command ( label = ' rebond offensif ' , command = lambda : self . action_menu ( ' ro ' ) )
self . action . add_command ( label = ' rebond défensif ' , command = lambda : self . action_menu ( ' rd ' ) )
self . action . add_command ( label = ' passe décisive ' , command = lambda : self . action_menu ( ' pd ' ) )
# Menu contextuel des joueurs
self . menu = tkinter . Menu ( self . root , tearoff = 0 )
self . menu . add_command ( label = self . team . players [ 0 ] , command = lambda : self . show_sub_menu ( self . team . players [ 0 ] ) )
self . menu . add_command ( label = self . team . players [ 1 ] , command = lambda : self . show_sub_menu ( self . team . players [ 1 ] ) )
self . menu . add_command ( label = self . team . players [ 2 ] , command = lambda : self . show_sub_menu ( self . team . players [ 2 ] ) )
self . menu . add_command ( label = self . team . players [ 3 ] , command = lambda : self . show_sub_menu ( self . team . players [ 3 ] ) )
self . menu . add_command ( label = self . team . players [ 4 ] , command = lambda : self . show_sub_menu ( self . team . players [ 4 ] ) )
self . bind_click = " <Button-1> "
self . bind_ctrl_s = " <Control-s> "
def check_action ( self , action ) :
if action in self . action_to_show :
self . action_to_show . remove ( action )
else :
self . action_to_show . append ( action )
def changemode ( self , newmode ) :
if self . mode != newmode :
if newmode == ' stat ' :
self . menubar . add_cascade ( label = ' stat ' , menu = self . statmenu )
self . menubar . add_cascade ( label = ' actions ' , menu = self . actionmenu )
else :
for i in range ( 2 ) :
self . menubar . delete ( 3 )
self . mode = newmode
items = self . canvas . find_all ( )
while len ( items ) > 4 :
self . canvas . delete ( items [ - 1 ] )
items = self . canvas . find_all ( )
def context_menu ( self , event ) :
if self . mode == " match " :
self . team . posx , self . team . posy = event . x , event . y
self . coo = [ event . x_root , event . y_root ]
self . menu . tk_popup ( event . x_root , event . y_root )
self . menu . grab_release ( )
def show_sub_menu ( self , player ) :
self . team . ac_player = player
self . action . tk_popup ( self . coo [ 0 ] , self . coo [ 1 ] )
self . action . grab_release ( )
def action_menu ( self , action ) :
""" enregistre temporairement l ' action """
self . clean_terrain ( )
# test si l'action est dans la liste des 3 points
if action == ' tm ' :
self . canvas . create_image ( self . team . posx - 20 , self . team . posy - 20 , image = self . tir_reussi , anchor = ' nw ' )
if ( ( self . team . posx - 0 ) * * 2 ) + ( ( self . team . posy - self . terrain . height / 2 ) * * 2 ) < = self . terrain . three_points * * 2 or ( ( self . team . posx - self . terrain . width ) * * 2 ) + ( ( self . team . posy - self . terrain . height / 2 ) * * 2 ) < = self . terrain . three_points * * 2 :
score = 2
else :
score = 3
if action == ' tr ' :
self . canvas . create_image ( self . team . posx - 20 , self . team . posy - 20 , image = self . tir_rate , anchor = ' nw ' )
score = 0
if action == ' lfm ' :
self . canvas . create_image ( self . team . posx - 20 , self . team . posy - 20 , image = self . lance_reussi , anchor = ' nw ' )
score = 1
if action == ' lfr ' :
self . canvas . create_image ( self . team . posx - 20 , self . team . posy - 20 , image = self . lance_rate , anchor = ' nw ' )
score = 0
if action == ' ro ' :
self . canvas . create_image ( self . team . posx - 20 , self . team . posy - 20 , image = self . rebond_off , anchor = ' nw ' )
score = 0
if action == ' rd ' :
self . canvas . create_image ( self . team . posx - 20 , self . team . posy - 20 , image = self . rebond_def , anchor = ' nw ' )
score = 0
if action == ' f ' :
self . canvas . create_image ( self . team . posx - 20 , self . team . posy - 20 , image = self . faute , anchor = ' nw ' )
score = 0
if action == ' pd ' :
self . canvas . create_image ( self . team . posx - 20 , self . team . posy - 20 , image = self . passe_dec , anchor = ' nw ' )
score = 0
if self . file . temp_data == ' ' :
self . root . title ( self . file . name + ' * ' )
self . file . temp_data + = self . team . ac_player + ' ' + action + ' ' + str ( score ) + ' ' + str ( self . team . posx ) + ' ' + str ( self . team . posy ) + ' \n '
def clean_terrain ( self ) :
""" Nettoie le terrain """
items = self . canvas . find_all ( )
while len ( items ) > 4 :
self . canvas . delete ( items [ - 1 ] )
items = self . canvas . find_all ( )
def draw_player ( self , player , * event ) :
""" dessine les actions de toute l ' équipe """
self . clean_terrain ( )
for line in self . file . content [ 2 : ] :
# forme type: joueur action points x y
params = line . strip ( ) . split ( ' ' )
if params [ 0 ] == player or player == ' * ' : # nom du joueur
if ' tirs ' in self . action_to_show :
if params [ 1 ] == ' tm ' :
self . canvas . create_image ( int ( params [ 3 ] ) , int ( params [ 4 ] ) , image = self . tir_reussi , anchor = ' nw ' )
if params [ 1 ] == ' tr ' :
self . canvas . create_image ( int ( params [ 3 ] ) , int ( params [ 4 ] ) , image = self . tir_rate , anchor = ' nw ' )
if ' lance ' in self . action_to_show :
if params [ 1 ] == ' lfm ' :
self . canvas . create_image ( int ( params [ 3 ] ) , int ( params [ 4 ] ) , image = self . lance_reussi , anchor = ' nw ' )
if params [ 1 ] == ' lfr ' :
self . canvas . create_image ( int ( params [ 3 ] ) , int ( params [ 4 ] ) , image = self . lance_rate , anchor = ' nw ' )
if ' faute ' in self . action_to_show and params [ 1 ] == ' f ' :
self . canvas . create_image ( int ( params [ 3 ] ) , int ( params [ 4 ] ) , image = self . faute , anchor = ' nw ' )
if ' rebond ' in self . action_to_show :
if params [ 1 ] == ' ro ' :
self . canvas . create_image ( int ( params [ 3 ] ) , int ( params [ 4 ] ) , image = self . rebond_off , anchor = ' nw ' )
if params [ 1 ] == ' rd ' :
self . canvas . create_image ( int ( params [ 3 ] ) , int ( params [ 4 ] ) , image = self . rebond_def , anchor = ' nw ' )
if ' passe ' in self . action_to_show and params [ 1 ] == ' pd ' :
self . canvas . create_image ( int ( params [ 3 ] ) , int ( params [ 4 ] ) , image = self . passe_dec , anchor = ' nw ' )
def draw_terrain ( self ) :
""" dessinne les lignes du terrain """
# ligne des 3 points
self . canvas . create_arc ( - self . terrain . three_points , self . terrain . height / / 2 - self . terrain . three_points , self . terrain . three_points , self . terrain . height - ( self . terrain . height / / 2 - self . terrain . three_points ) , width = 3 , start = 90 , extent = - 180 )
self . canvas . create_arc ( self . terrain . width - self . terrain . three_points , self . terrain . height / / 2 - self . terrain . three_points , self . terrain . width + self . terrain . three_points , self . terrain . height - ( self . terrain . height / / 2 - self . terrain . three_points ) , width = 3 , start = 90 , extent = 180 )
# ligne centrale
self . canvas . create_line ( self . terrain . width / / 2 , 0 , self . terrain . width / / 2 , self . terrain . height , width = 3 )
# cercle du milieu
self . canvas . create_oval ( self . terrain . width / / 2 - self . terrain . middle_circle , self . terrain . height / / 2 - self . terrain . middle_circle , self . terrain . width / / 2 + self . terrain . middle_circle , self . terrain . height / / 2 + self . terrain . middle_circle , width = 3 )
gui = Gui ( )