(phixonline)--> -- -- demo\rosetta\21_Game.exw -- ======================== -- with javascript_semantics -- DEV NORMALIZESIZE, CANFOCUS, "You" not checked, VALUE_HANDLE. -- The radio_texts simply don't do anything at all in p2js. constant title = "21 Game", help_text = """ Play by choosing 1, 2, or 3 to add to the running total (initially 0). The first player to reach 21 wins. If the computer goes first you cannot win. If you leave your opponent on 18, 19, or 20, they will play {3,2,1} and win. If you leave your opponent on 17, simply match their play {1,2,3} with {3,2,1} and win. If you leave your opponent on 14, 15, or 16, they'll leave you on 17 and win. So the aim is 21 (doh), and before that 17, 13, 9, 5, and 1. Anything else loses. """, radio_texts = {"You","Computer","Random"}, button_text = {"one","two","three","concede","new game","quit"} integer total = 0 include pGUI.e Ihandle dlg, vbox, frame, radios, playstate sequence radioset, buttons function show_help() IupMessage(title,help_text) return IUP_IGNORE -- (don't open browser help!) end function function play(integer n) if n!=0 then if n=6 then return IUP_CLOSE end if string title if n>3 then -- concede or new_game total = 0 title = iff(n=4?"(conceded) ":"") title &= "Total is 0" Ihandle r = IupGetAttributePtr(radios,"VALUE_HANDLE") n = find(r,radioset) if n=2 or (n=3 and rand(2)=1) then title &= "," -- trigger a computer move end if IupSetInt(buttons[1..3],"ACTIVE",true) else -- n = 1..3 title = sprintf("Total is %d",total) if total=21 -- (from key_cb) or total+n>21 then -- (invalid) return IUP_IGNORE end if total += n title &= sprintf(", you play %d (-> %d),",{n,total}) if total=21 then title &= " you win" end if end if if find(',',title) and total!=21 then -- computer move sequence moves = {1,rand(3),3,2} n = moves[mod(total,4)+1] total += n title &= sprintf(" computer plays %d (-> %d)",{n,total}) if total=21 then title &= ", computer wins" elsif mod(total,4)=1 then title &= ", (you've already lost)" end if end if if total=21 then title &= " GAME OVER" IupSetInt(buttons[1..4],"ACTIVE",false) else if total>18 then IupSetInt(buttons[22-total..3],"ACTIVE",false) end if IupSetInt(buttons[4],"ACTIVE",total!=0) end if IupSetFocus(dlg) -- (stops inactive button beeping) IupSetStrAttribute(playstate,"TITLE",title) end if return IUP_IGNORE end function function button_cb(Ihandle ih) string title = IupGetAttribute(ih,"TITLE") return play(find(title,button_text)) end function constant cb_button = Icallback("button_cb") function key_cb(Ihandle /*dlg*/, atom c) if c=K_ESC then return IUP_CLOSE end if -- (standard practice for me) if c=K_F5 then return IUP_DEFAULT end if -- (let browser reload work) if c=K_F1 then return show_help() end if return play(find(upper(c),"123CNQ")) end function IupOpen() playstate = IupLabel("","EXPAND=HORIZONTAL, PADDING=10x10") radioset = apply(true,IupToggle,{radio_texts,{"RIGHTBUTTON=YES, CANFOCUS=NO"}}) buttons = apply(true,IupButton,{button_text,cb_button,{"PADDING=5x5"}}) radios = IupRadio(IupHbox(radioset,"GAP=45")) frame = IupHbox({IupLabel(`First Player:`),radios},"NORMALIZESIZE=VERTICAL") vbox = IupVbox({frame,playstate,IupHbox(buttons,"GAP=10")},"MARGIN=20x10") dlg = IupDialog(vbox,`TITLE="%s", MINSIZE=540x200`,{title}) IupShow(dlg) IupSetCallback({dlg,buttons},"KEY_CB",Icallback("key_cb")) IupSetAttributeHandle(NULL,"PARENTDIALOG",dlg) {} = play(find("new game",button_text)) if platform()!=JS then IupMainLoop() IupClose() end if