Kniffel
this game is able to give you tips whats best to keep and which result to submit, so the perfekt yahtzee game is nearer then ever before
you can play it alone or change the playernumber up to 5.
here the code for those who are interessted in and for me to keep it up to date
edit: forgot sth, get this code after you downloaded and extracted the rar
edit: Kniffel is called Yahtzee outside of German-speaking countries
sorry for that
hModule := DllCall("LoadLibrary", "str", "ole32.dll") DllCall("ole32\CoInitialize", "uint", 0) ;variables trials = 0 rounds = 0 tips = 0 Player1 = Player1 Player2 = Player3 = Player4 = Player5 = players = 1 currenttab = %Player1% currentplayer = 1 ; ;GUI ; ;creating menubar+gui Menu, Filemenu, add, New &Game, new_game Menu, Filemenu, add Menu, Filemenu, add, E&xit, filemenuexit Menu, gamemenu, add, Show &tips, tips Menu, gamemenu, add, &Change Player Number, pl_number Menu, gamemenu, add, Change Player &Names, pl_names Menu, Helpmenu, add, &Help, helpmenuhelp Menu, helpmenu, add Menu, helpmenu, add, &About, helpmenuabout Menu, mybar, add, &File, :Filemenu Menu, mybar, add, &Game, :gamemenu Menu, mybar, add, &Help, :Helpmenu Gui, menu, mybar Gui, color, white ;creating dice + checkbox buttons loop, 5 { xpos:=-40 +50*a_index Gui, add, button, x%xpos% y10 w40 h40 vb%a_index% gbutton%a_index% xpos:=-30 +50*a_index Gui, add, checkbox, x%xpos% y60 vkeep%a_index% Guicontrol, disable, keep%a_index% } ;shuffle button Gui, add, button,y20 x270 w40 h25 default vRoll, Roll ;tip text gui, add, text, w100 x20 y80 vvtips, Best: guicontrol, hide, vtips ;throw-bar Gui, add, text ,x170 y80, Throws Gui, Add, Progress, range0-3 xp+40 yp+3 h10 w80 vMyProgress cblue ;tab control Gui, add, tab, vmytab x0 y100 w400 h400 , %Player1%| ;ListView bgURL = %a_workingdir%\images\wuerfel.bmp loop, 5 { gui, tab, %a_index% gui, font, s10 bold, verdana Gui, Add, ListView, +grid vLV%a_index% HwndhMyListView gmylistview NoSortHdr -multi h330 w300 LV0x10000, Throws|Points| LV_SetBackgroundURL(bgURL, hMyListView) LV_add( "", "1er") LV_add( "", "2er") LV_add( "", "3er") LV_add( "", "4er") LV_add( "", "5er") LV_add( "", "6er") LV_add( "", "Total") LV_add( "", "Bonus?") LV_add( "", "Total up") LV_add( "", "3 of a kind") LV_add( "", "4 of a kind") LV_add( "", "Full House") LV_add( "", "Lt. Street") LV_add( "", "Bg. Street") LV_add( "", "Kniffel") LV_add( "", "Chance") LV_add( "", "Total down") LV_add( "", "Overall") LV_ModifyCol(1, 150) LV_ModifyCol(2, 145) } Gui, Show, w320 h470, Kniffel - %Player1% Guicontrol,choose, mytab, 1 Gui, ListView, LV1 return ; ; Submit result ; MyListView: if A_GuiEvent = DoubleClick { Guicontrolget, whichtab , ,mytab if whichtab = %currenttab% { if trials>=1 { LV_GetText(RowText, A_EventInfo, 2) if a_eventinfo not in 7,8,9,17,18 { if Rowtext = { LV_modify(a_eventinfo, "Col2", check(a_eventinfo, var) ) gosub calc_up gosub calc_down sleep, 1000 Guicontrol, enable, Roll trials = 0 GuiControl,, MyProgress, 0 GuiControl,, vtips, Best: loop, 5 { Guicontrol,, b%a_index% Guicontrol,, keep%a_index%, 0 } Guicontrolget, currenttab , ,mytab loop, %players% { if currenttab = % Player%a_index% { currentplayer = 1 currentplayer += %a_index% if currentplayer <= %Players% { Guicontrol, choose, mytab, %currentplayer% Gui, ListView, LV%currentplayer% loop, 5 { Guicontrol, disable, keep%a_index% } currenttab = % Player%currentplayer% Gui,1: show ,, Kniffel - %currenttab% Guicontrol, focus, Roll return } else { Guicontrol, choose, mytab, 1 Gui, ListView, LV1 loop, 5 { Guicontrol, disable, keep%a_index% } currenttab = %Player1% currentplayer = 1 Gui,1: show ,, Kniffel - %Player1% Guicontrol, focus, Roll rounds++ } } } if rounds = 13 ; END { gosub calc_together msgbox, 4, , Again? ifmsgbox, yes goto new_round ifmsgbox, no return } } } } } else msgbox, This is not your tab! } return ; ;check result ; check(x, var) { if x in 1,2,3,4,5,6 ; gather numbers { temp=0 loop, 5 { if numbers%a_index% = %x% temp +=x } return %temp% } if x= 10 ; kind of three { temp=0 loop, 6 { xkind=0 indexa= %a_index% if var contains %a_index% { loop,5 { if numbers%a_index% = %indexa% { xkind++ } if xkind = 3 { 3kind =% numbers%a_index% loop, 5 { temp+= numbers%a_index% } break } } if 3kind break } } return %temp% } if x= 11 ; kind of 4 { temp=0 loop, 6 { xkind=0 indexa= %a_index% if var contains %a_index% { loop,5 { if numbers%a_index% = %indexa% { xkind++ } if xkind = 4 { 4kind =% numbers%a_index% loop, 5 { temp+= numbers%a_index% } break } } if 4kind break } } return %temp% } if x= 12 ; full house { temp=0 loop, 6 { xkind=0 indexa= %a_index% if var contains %a_index% { loop,5 { if numbers%a_index% = %indexa% { xkind++ } if xkind = 3 { 3kind =% numbers%a_index% break } } if 3kind break } } loop, 6 { xkind=0 indexa= %a_index% if var contains %a_index% { loop,5 { if numbers%a_index% = %indexa% if numbers%a_index% <> %3kind% { xkind++ } if xkind = 2 { 2kind =% numbers%a_index% break } } if 2kind break } } if 3kind { if 2kind { temp =25 } } return %temp% } if x= 13 ; little street { temp=0 if var contains 1 if var contains 2 if var contains 3 if var contains 4 { temp =30 } if var contains 2 if var contains 3 if var contains 4 if var contains 5 { temp =30 } if var contains 3 if var contains 4 if var contains 5 if var contains 6 { temp =30 } return %temp% } if x= 14 ; Big street { temp=0 if var contains 1 if var contains 2 if var contains 3 if var contains 4 if var contains 5 temp=40 if var contains 2 if var contains 3 if var contains 4 if var contains 5 if var contains 6 temp=40 return %temp% } if x= 15 ; kniffel { temp=0 loop, 6 { xkind=0 indexa= %a_index% if var contains %a_index% { loop,5 { if numbers%a_index% = %indexa% { xkind++ } if xkind = 5 { 5kind =% numbers%a_index% temp=50 break } } if 5kind break } } return %temp% } if x= 16 ; chance { temp=0 loop, 5 { temp+= numbers%a_index% } return %temp% } } return ;calcs calc_up: temp=0 loop, 6 { LV_GetText(value, a_index, 2) temp += value } if temp { LV_modify(7, "Col2", temp ) } if temp >=63 { LV_modify(8, "Col2", 35) } loop, 6 { LV_GetText(value, a_index, 2) if value = return if a_index = 6 { if temp <63 { LV_modify(8, "Col2"," - ") } temp = 0 LV_GetText(value, 8, 2) temp+=value LV_GetText(value, 7, 2) temp+=value LV_modify(9, "Col2", temp ) } } return calc_down: temp=0 loop, 7 { LV_GetText(value, a_index+9, 2) temp += value } if temp { LV_modify(17, "Col2", temp ) } return calc_together: temp=0 LV_GetText(value, 9, 2) temp+=value LV_GetText(value, 17, 2) temp+=value LV_modify(18, "Col2", temp ) return ; ;misc functions ; button1: keep_toggle(1) return button2: if trials >0 keep_toggle(2) return button3: if trials >0 keep_toggle(3) return button4: if trials >0 keep_toggle(4) return button5: if trials >0 keep_toggle(5) return keep_toggle(x) { global if trials >0 { gui, submit, nohide if keep%x% Guicontrol, , keep%x%, 0 else Guicontrol, , keep%x%, 1 } } return LV_SetBackgroundURL(URL, ControlID) { VarSetCapacity(bki, 24, 0) NumPut(0x2|0x10, bki, 0) ; LVBKIF_SOURCE_URL | LVBKIF_STYLE_TILE NumPut(&URL, bki, 8) SendMessage, 0x1044, 0, &bki,, ahk_id %ControlID% ; LVM_SETBKIMAGE } new_round: { Gui, 1:default rounds = 0 trials = 0 loop, 5 { Gui, ListView, LV%a_index% LV_deleteCol(2) LV_InsertCol(2,"", "Points") } Guicontrol,1: choose, mytab, 1 Gui, ListView, LV1 currenttab = %Player1% loop, 5 { Guicontrol,, b%a_index% Guicontrol,, keep%a_index%, 0 Guicontrol, disable, keep%a_index% } Gui, show ,, Kniffel - %player1% Guicontrol, enable, Roll Guicontrol,1: focus, Roll GuiControl,, MyProgress, 0 Guicontrol,, vtips, Best: } return mergeplayer: { loop, 5 { if a_index > %players% ; clear only those which dont play player%a_index% = } if player1 { if player2 { if player3 { if player4 { if player5 { str= %player1%|%player2%|%player3%|%player4%|%player5% } else { str= %player1%|%player2%|%player3%|%player4% } } else { str= %player1%|%player2%|%player3% } } else { str= %player1%|%player2% } } else { str= %player1% } } Guicontrol,1: ,mytab, |%str% } return ; ; Menu functions ; #IfWinActive, ahk_class AutoHotkeyGUI ^g:: new_game: msgbox, 4, , Sure? ifmsgbox, yes goto new_round ifmsgbox, no return return #IfWinActive, ahk_class AutoHotkeyGUI ^x:: filemenuexit: exitapp return #IfWinActive, ahk_class AutoHotkeyGUI ^t:: tips: menu, gamemenu, ToggleCheck, Show &tips if tips =0 { tips = 1 guicontrol, show, vtips if trials gosub showtips } else { tips = 0 guicontrol, hide, vtips } return showtips: if tips { str = kniffel loop, 18 { if a_index not in 7,8,9,17,18 { LV_GetText(value, a_index, 2) if value str = %str% %value% else if value = 0 str = %str% 0 else str = %str% - } } str = %str% %trials% %var% > history.txt runwait, %comspec% /c %str% FileReadLine, line, history.txt, 22 StringSplit, prearray, line , `, StringSplit, endarray, prearray1 , :, %a_space% ;translation best = %endarray4% if best = Einser best = 1er else if best = Zweier best = 2er else if best = Dreier best = 3er else if best = Vierer best = 4er else if best = Fuenfer best = 5er else if best = Sechser best = 6er else if best = FullHouse best = Full House else if best = Kleine Strasse best = Lt. Street else if best = Grosse Strasse best = Bg. Street else if best = 0 best = - Guicontrol,, vtips, Best: %best% } return #IfWinActive, ahk_class AutoHotkeyGUI ^c:: pl_number: Gui, 4:destroy Gui, 4:font, s12 bold Gui, 4:add, text, , Choose the number`nof players: Gui, 4:Add, Edit, x70 w50 vpl_nbr Gui, 4:font, normal Gui, 4:Add, UpDown, Range1-5, 2 Gui, 4:add, button, x40 default, Ok Gui, 4:add, button, x85 yp, Cancel Gui, 4:show, autosize, Playernumber return 4Buttonok: Gui, 4:submit gui, 4:destroy if pl_nbr = %players% return else { players = %pl_nbr% loop, %players% { if player%a_index% = player%a_index% = Player%a_index% } gosub mergeplayer goto new_round } return 4Guiescape: 4Guiclose: 4ButtonCancel: Gui,4:destroy Guicontrol,1: focus, Roll return #IfWinActive, ahk_class AutoHotkeyGUI ^n:: pl_names: Gui, 5:destroy gui, 5:font, s12 loop,5 if player%a_index% { ypos := -20 +40*a_index gui, 5:add, text,x10 y%ypos%, Player %a_index%: gui, 5:add, edit,vpl_name%a_index% x80 y%ypos% w100, % player%a_index% } Gui, 5:add, button, x40 y+15 default, Ok Gui, 5:add, button, x85 yp, Cancel Gui, 5:show, autosize, Playernames return 5ButtonOk: Gui,5:Submit loop, 5 player%a_index% = % pl_name%a_index% Gui,5:destroy gosub mergeplayer currenttab = % player%currentplayer% Gui,1: show ,, Kniffel - %currenttab% return 5Guiescape: 5Guiclose: 5ButtonCancel: gui,5:destroy Guicontrol,1: focus, Roll return #IfWinActive, ahk_class AutoHotkeyGUI ^h:: helpmenuhelp: Gui, 2:destroy gui, 2:font, s15 underline bold, Arial Gui, 2:add, text,, Help gui, 2:font, normal gui, 2:font, s10 gui, 2:add, text,,-Click the roll button to get new dice`n-Select either a dice or a checkbox under a it in order to keep the dice`n-Double click on an entry to submit your result.`n-The "throw-bar" indicates how many throws you have left`n-The menuentries are self-explaining Gui, 2:add, button, default +center x185 yp+100, Ok Gui, 2:color, white Gui, 2:+resize Gui, 2:show, autosize return 2Buttonok: Gui, 2:destroy return #IfWinActive, ahk_class AutoHotkeyGUI ^a:: helpmenuabout: gui, 3:destroy gui, 3:font, s15 underline bold, Arial Gui, 3:add, text,, Kniffel gui, 3:font, normal gui, 3:font, s10 gui, 3:add, text,, Version: 1.00`nAuthor: Nils Gui, 3:add, button, default +center x70 yp+50, Ok Gui, 3:color, white Gui, 3:+resize Gui, 3:show, autosize return 3Buttonok: Gui, 3:destroy return ; ;Roll ; ;shuffle ButtonRoll: Gui, submit, nohide var=0 trials+=1 GuiControl,, MyProgress, +1 if trials =1 { loop, 5 { Guicontrol, enable, keep%a_index% } } if trials = 3 Guicontrol, disable, Roll loop, 5 { xpos:=-40 +50*a_index Random, rnd, 1,6 if keep%a_index% = 0 { Guicontrol,, b%a_index%, %rnd% numbers%a_index% = %rnd% } } var = %numbers1%%numbers2%%numbers3%%numbers4%%numbers5% gosub showtips return Guiclose: FileDelete, %a_workingdir%\history.txt gui, destroy ;do this to avoid access violation DllCall("ole32\CoUninitialize") ; DllCall("FreeLibrary", "UInt", hModule) ;this must be done at the end exitapp return