#!/a/air/alpha-bin/awelewish -f

# variables connues de C et de TCL
set levelname "REGULAR"
set awcur "12060000040404040404040404040404"

# variables globales a ce script
set awbak "12060000040404040404040404040404"
set level 6
set pris1 3
set pris2 3
set cp 0
for {set i 0} {$i < 12} {incr i} {set aw_cur($i) 4}
set status_str "Welcome to AWELE 1.0"
set firstplay 1

# fenetres de regle du jeu
#########################################
#en francais
proc regles {w} {
	toplevel $w
	wm title $w "Regles du jeu"
	message $w.msg -justify left -width 10c -fg palegreen -bg sienna -text "\
	L'AWELE est jeu d'Afrique aussi connu sous le nom de SUNGO.\
	Il se prsente sous la forme de deux ranges de 6 trous\
	contenant initialement 4 pierres. La range du bas est votre camp,\
	celle du haut celui de l'adversaire.\
	Le but est de capturer le maximum de pierres.\n\n\
	Mouvements:\n\
	Tour a tour, les joueurs choisissent un trou non vide de leur camp\
	et en repartissent le contenu  raison d'une pierre sur les trous\
	successifs dans l'ordre inverse des aiguilles d'une montre, en \
	omettant systematiquement le trou d'origine.\n\n\
	Prises:\n\
	Si la dernire pierre pose tombe dans le camp adverse ET dans un\
	trou contenant 2 ou 3 pierres (la pierre pose y compris) alors\
	les pierres de ce trou sont faites prisonnires et sont enleves\
	du jeu. La prise continue alors en examinant l'avant dernire pierre pose\
	(etc..) tant que les deux conditions de prise sont verifies. Ds que\
	celles-ci sont mises en defaut, la prise s'arrte.\n\n\
	Fin de partie:\n\
	Si un des joueurs ne peut jouer (son camp est vide),\
	la partie s'arrte et il capture toutes les pierres restant dans le camp adverse.\
	Il existe des endroits o l'on considre que ce cas de figure est un pat, ce\
	n'est pas la rgle implemente ici. En gnral, la partie s'arrte\
	quand il n'y a plus assez de pierres pour faire des prises.\
	Ce programme ne dtecte pas les fins de partie.\n\n\
	A propos de ce programme: la technique utilise est une recherche\
	de type alpha-beta. Pour jouer, cliquer du 1er bouton sur le trou\
	choisi. Cliquer du bouton 2 vous permet de voir o arrive la dernire pierre."
	pack $w.msg -side top
	button $w.ok -text "OK" -command "destroy $w" -relief raised -fg palegreen -bg sienna\
		-activebackground chocolate
	pack $w.ok -side bottom -fill x -expand yes
}

#en anglais
proc rules {w} {
	toplevel $w
	wm title $w "Game rules"
	message $w.msg -justify left -width 10c -fg palegreen -bg sienna -text "\
	AWELE is an african game also known as SUNGO.\
	The game board is made up of 2 rows of 6 squares with each\
	square initially containing 4 stones. Your side is the bottom row\
	and your opponent's side is the top row. The aim is to capture as\
	many stones as possible.\n\n\
	Moves:\nPlayers alternate turns. To play, choose a non-empty square in your side\
	and drop its stones (1 each) in each successive squares in a counter clockwise\
	direction. Always skip over the original square.\n\n\
	Captures:\n\
	If you end up your turn by dropping a stone in your opponent's side AND\
	in a square containing 2 or 3 stone (including the stone you dropped in)\
	these stones are captured. Then, continue capturing in each preceding\
	squares as long as those 2 conditions are respected. Captures end as soon as\
	this is no more the case.\n\n\
	End of the game:\n\
	if one of the player can't play at his turn (i.e. his side is empty)\
	he captures all the remaining stones and the game ends. There exist rules where\
	such a situation is declared a draw. This is not the case here.\
	In general, the game ends when there is not enough stones to allow captures.\
	This soft doesn't detect the end of the game.\n\n\
	About the program: an alpha-beta search is used. To play, click with button-1\
	on the square you choosed. Clicking with button-2 on a square indicates where\
	the last stone is dropped."
	pack $w.msg -side top
	button $w.ok -text "OK" -command "destroy $w" -relief raised -fg palegreen -bg sienna\
		-activebackground chocolate
	pack $w.ok -side bottom -fill x -expand yes
}	

# CONVERSIONS AWELE TABLEAU <-> STRING
##########################################
proc awele_get {} {
global pris1
global pris2
global cp
global level
global aw_cur
global awcur
	scan $awcur "%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d" cp level pris1 pris2 aw_cur(0) aw_cur(1) aw_cur(2) aw_cur(3) aw_cur(4) aw_cur(5) aw_cur(6) aw_cur(7) aw_cur(8) aw_cur(9) aw_cur(10) aw_cur(11) 
}

proc awele_put {} {
global pris1
global pris2
global cp
global level
global aw_cur
global awcur
	set awcur [format "%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d%02d" $cp $level $pris1 $pris2 $aw_cur(0) $aw_cur(1) $aw_cur(2) $aw_cur(3) $aw_cur(4) $aw_cur(5) $aw_cur(6) $aw_cur(7) $aw_cur(8) $aw_cur(9) $aw_cur(10) $aw_cur(11)]
}


# ROUTINES DE DISPLAY DE L'AWELE
#############################################################################
# trou i
proc aweletrou { w i } {
	if { $i < 6 } { 
		set x1 [ expr 10 + 110*$i ]
		set x2 [ expr $x1 + 100 ]
		set y1 120
		set y2 220
	} else {
		set x1 [ expr 10 + 110*(11-$i) ]
		set x2 [ expr $x1 + 100 ]
		set y1 10
		set y2 110
	}
	$w create oval $x1 $y1 $x2 $y2 -width 10 -fill sienna -tags "$i trou$i trou thing"
}

# place feves de aw_cur dans le trou i
############################################################################
# trace d'une feve en x,y
proc drawfeve { w x y taglist } {
	set x1 [expr $x-8]
	set y1 [expr $y-8]
	set x2 [expr $x+8]
	set y2 [expr $y+8]
	.c create oval $x1 $y1 $x2 $y2 -fill palegreen -width 1 -outline red -tags $taglist
}

# met les feves du trou i
proc putfeve { w i } {
global aw_cur
	set contenu $aw_cur($i)
	if { $contenu > 0 } { putnfeve $w $contenu $i }
}

# met n feves dans le trou i	
proc putnfeve { w n i } {
	set taglist "$i feve$i feve thing"
	if { $i < 6 } {
		set xc [expr 60+110*$i]  
		set yc 170
	} else {
		set xc [expr 60+110*(11-$i)]  
		set yc 60
	}

	switch $n {
		1 {
			drawfeve $w $xc $yc $taglist
		}
		2 {
			drawfeve $w $xc [expr $yc-20] $taglist
			drawfeve $w $xc [expr $yc+20] $taglist
		}
		3 {
			drawfeve $w $xc [expr $yc-20] $taglist
			drawfeve $w $xc $yc $taglist
			drawfeve $w $xc [expr $yc+20] $taglist
		}
		4 {
			drawfeve $w [expr $xc-20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc-20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc+20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc+20] [expr $yc+20] $taglist
		}
		5 {
			drawfeve $w [expr $xc-20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc-20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc+20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc+20] [expr $yc+20] $taglist
			drawfeve $w $xc $yc $taglist
		}
		6 {
			drawfeve $w [expr $xc-20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc-20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc-20] $yc $taglist
			drawfeve $w [expr $xc+20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc+20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc+20] $yc $taglist
		}
		7 {
			drawfeve $w [expr $xc-20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc-20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc-20] $yc $taglist
			drawfeve $w [expr $xc+20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc+20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc+20] $yc $taglist
			drawfeve $w $xc $yc $taglist
		}
		8 {
			drawfeve $w [expr $xc-20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc-20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc-20] $yc $taglist
			drawfeve $w [expr $xc+20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc+20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc+20] $yc $taglist
			drawfeve $w $xc [expr $yc+10] $taglist
			drawfeve $w $xc [expr $yc-10] $taglist
		}
		9 {
			drawfeve $w [expr $xc-20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc-20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc-20] $yc $taglist
			drawfeve $w [expr $xc+20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc+20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc+20] $yc $taglist
			drawfeve $w $xc [expr $yc+20] $taglist
			drawfeve $w $xc [expr $yc-20] $taglist
			drawfeve $w $xc $yc $taglist
		}
		default {
			if {$n > 0} {
			drawfeve $w [expr $xc-20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc-20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc-20] $yc $taglist
			drawfeve $w [expr $xc+20] [expr $yc-20] $taglist
			drawfeve $w [expr $xc+20] [expr $yc+20] $taglist
			drawfeve $w [expr $xc+20] $yc $taglist
			drawfeve $w $xc [expr $yc+20] $taglist
			drawfeve $w $xc [expr $yc-20] $taglist
			drawfeve $w $xc $yc $taglist
			.c create rectangle [expr $xc-10] [expr $yc-10]\
				[expr $xc+10] [expr $yc+10] -outline red -fill white -tags $taglist
			.c create text $xc $yc -text $n -fill red -tags $taglist
			}
		}
	}
}
# flash le trou numero i
##########################################################################
proc flashtrou {w i n color} {
	for {set j 0} {$j<$n} {incr j} {
		$w itemconfigure trou$i -outline $color
		update idletasks
		after 100
		$w itemconfigure trou$i -outline black
		update idletasks
		after 100
	}
}


# fait le tout
###########################################################################
proc affichage_trou {w} {
	for {set i 0} {$i <12} {incr i} {
		aweletrou $w $i
	}
}
proc affichage_feve {w} {
	$w delete feve
	for {set i 0} {$i <12} {incr i} {
		putfeve $w $i
	}
}

# UNDO
############################################################################
proc undo {w} {
global awcur 
global awbak
global level 
global levelname
	set awcur $awbak
	awele_get
	setlevel $levelname $awbak
	affichage_feve $w
}

# NEWGAME 
###########################################################################
proc newgame {w initplayer} {
global awcur awbak status_str
global cp
global firstplay
global levelname
	set awcur "12060000040404040404040404040404"
	set awbak "12060000040404040404040404040404"
	setlevel $levelname $awcur
	awele_get
	affichage_feve $w 
	if { $initplayer == 2 } {
		computer_rand_play $awcur
		scan [string range $awcur 0 1] %d cp
		set cp [expr $cp%12]
		showplay $w $cp 2
		awele_get
#		affichage_feve $w
		set status_str "Your turn"
		set firstplay 0
	} else {
		set firstplay 1
	}
}

#joue efectivement un coup avec affichage temps reel
proc showplay { w cp who } {
global aw_cur
	flashtrou $w $cp 2 red
	set n $aw_cur($cp)
	$w delete feve$cp
	update idletasks
	set ind $cp
	for {set i 1} {$i <= $n} {incr i} {
		set ind [expr ($ind+1)%12]
		if {$ind == $cp} {set ind [expr ($ind+1)%12]}
		set aw_cur($ind) [expr $aw_cur($ind)+1]
		$w delete feve$ind		
		update idletasks
		putnfeve $w $aw_cur($ind) $ind 
		update idletasks
		after 100
	}
	set ok 1
	if { $who==1 } {
		for {set i $ind} {$i>=6 && $ok==1} {incr i -1} {
			if { $aw_cur($i)==2 || $aw_cur($i)==3 } {
				.c delete feve$i
				flashtrou $w $i 2 white 
			} else {
				set ok 0
			}			
		}
	} else {
		for {set i $ind} {$i<6 && $i>=0 && $ok==1} {incr i -1} {
			if { $aw_cur($i)==2 || $aw_cur($i)==3 } {
				.c delete feve$i
				flashtrou $w $i 2 white
			} else {
				set ok 0
			}			
		}
	}
}


# ACTIONS DES BOUTONS
############################################################################
# bouton 1: joue
proc button1action {w x y} {
global awcur awbak
global cp
global firstplay
global status_str
global aw_cur
	set id [$w find closest $x $y]
	set nb [lindex [$w gettags $id] 0]
	awele_get
	if {$nb < 6 && $aw_cur($nb)>0} {
		$w configure -cursor watch
		update idletasks
		set awbak $awcur
		showplay $w $nb 1
		human_play $nb $awcur
		awele_get
		set status_str "thinking ...."
		update idletasks
		if {$firstplay == 1} {
			computer_rand_play $awcur
			set firstplay 0
		} else {
			computer_play $awcur
		}
		scan [string range $awcur 0 1] %d cp
		set cp [expr $cp%12]
		showplay $w $cp 2
		awele_get
		affichage_feve $w
		update idletasks
		set status_str "Your turn"
		$w configure -cursor top_left_arrow
	}
}

#bouton 2: flash dernier trou atteint
proc button2action {w x y} {
	set id [$w find closest $x $y]
	set nb [lindex [$w gettags $id] 0]
	set n [ lasttrou $nb ]
	if {$n>=0} {flashtrou $w $n 1 red}
}

proc lasttrou { case } {
global aw_cur
	awele_get
	set contenu $aw_cur($case)
	set j [expr $case+$contenu]
	if {$contenu>=12} {incr j}
	if {$contenu>=23} {incr j}
	if {$contenu>=34} {incr j}
	expr $j%12
}	
# WINDOW TREE
#############################################################################
wm title . "AWELE"

# MENU BAR
#############################################################################
frame .menu -relief raised -borderwidth 1 -bg chocolate 
pack .menu -side top -fill x
menubutton .menu.file -text "Misc" -menu .menu.file.m \
	-background chocolate -activebackground chocolate
menubutton .menu.level -text "Level" -menu .menu.level.m \
	-background chocolate -activebackground chocolate

menu .menu.file.m -background chocolate -activebackground chocolate
.menu.file.m add command -label "New game (you start)" -command "newgame .c 1"\
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen
.menu.file.m add command -label "New game (I start)" -command "newgame .c 2" \
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen
.menu.file.m add command -label "Rules" -command "rules .ru" \
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen
.menu.file.m add command -label "Regles" -command "regles .re" \
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen
.menu.file.m add command -label "Quit" -command exit \
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen

menu .menu.level.m -background chocolate -activebackground chocolate
.menu.level.m add command -label "Beginner" -command "setlevel BEGINNER $awcur" \
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen
.menu.level.m add command -label "Novice" -command "setlevel NOVICE $awcur" \
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen
.menu.level.m add command -label "Regular" -command "setlevel REGULAR $awcur"\
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen
.menu.level.m add command -label "Fair" -command "setlevel FAIR $awcur"\
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen
.menu.level.m add command -label "Good" -command "setlevel GOOD $awcur"\
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen
.menu.level.m add command -label "Expert" -command "setlevel EXPERT $awcur"\
 	-background  chocolate -foreground palegreen \
	-activebackground sienna -activeforeground palegreen

pack .menu.file .menu.level -side left
tk_menuBar .menu .menu.file .menu.level

# STATUS 
#############################################################################
frame .status -borderwidth 1 -relief sunken 
pack .status -fill x

label .status.pp1 -text "Your captures: " -borderwidth 1 -background sienna -foreground palegreen
label .status.p1 -textvariable pris1 -borderwidth 1  -background sienna -foreground palegreen
label .status.pp2 -text "My captures: " -borderwidth 1  -background sienna -foreground palegreen
label .status.p2 -textvariable pris2 -borderwidth 1  -background sienna -foreground palegreen
label .status.stat -textvariable status_str -borderwidth 1 -relief sunken \
	-background chocolate -foreground palegreen 
button .status.undo -text "  UNDO  " -borderwidth 1  -background sienna -borderwidth 1\
	-foreground palegreen -command "undo .c" -relief raised -activebackground chocolate
label .status.llevel -text "Level: " -borderwidth 1  -background chocolate -foreground palegreen
label .status.level -textvariable  levelname -borderwidth 1  -background chocolate -foreground  palegreen
pack .status.pp1 .status.p1 .status.pp2 .status.p2 -side left -fill both	
pack .status.stat -side left -fill both -expand yes
pack .status.level .status.llevel .status.undo -side right -fill both

# GRAPHIC WINDOW
#############################################################################
canvas .c -width 670 -height 230 -background chocolate
pack .c -side bottom -fill both

# CREATE AWELE
#############################################################################
awele_get
affichage_trou .c
affichage_feve .c
.c bind thing <1> "button1action .c %x %y"
.c bind thing <2> "button2action .c %x %y"

